如何使用 C# 从远程位置将 Excel csv 或 xls 文件的行读入 ASP.NET 应用程序?
Posted
技术标签:
【中文标题】如何使用 C# 从远程位置将 Excel csv 或 xls 文件的行读入 ASP.NET 应用程序?【英文标题】:How can I read the rows of an Excel csv or xls file into an ASP.NET app from a remote location using C#? 【发布时间】:2013-07-02 17:35:35 【问题描述】:这是我的情况。我正在设计一个程序,它从远程网络驱动器获取 Excel 文件(可能是 csv、xls 或 xlsx 格式),处理数据,然后输出并存储该过程的结果。该程序提供了一个文件名列表框,这些文件名使用已接受的答案here 中详述的方法从远程网络驱动器文件夹中获取。一旦用户从列表框中选择了一个文件名,我希望程序找到该文件并从中获取信息以进行数据处理。我曾尝试在线程安全上下文中使用this 方法从 Excel 文件中读取数据,但该方法失败而没有给出任何类型的错误。它似乎没有终止。我是不是走错了路?
编辑 - (最后说明:我已取出 OleDbDataAdapter 并用 EPPlus 处理替换它。)
我能够从代码中清除敏感数据,所以这里是:
protected void GetFile(object principalObj)
if (principalObj == null)
throw new ArgumentNullException("principalObj");
IPrincipal principal = (IPrincipal)principalObj;
Thread.CurrentPrincipal = principal;
WindowsIdentity identity = principal.Identity as WindowsIdentity;
WindowsImpersonationContext impersonationContext = null;
if (identity != null)
impersonationContext = identity.Impersonate();
try
string fileName = string.Format("0\\" + Files.SelectedValue, @"RemoteDirectoryHere");
string connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.14.0; data source=0; Extended Properties=Excel 14.0;", fileName);
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM Sheet1", connectionString);
DataSet ds = new DataSet();
adapter.Fill(ds, "Sheet1");
dataTable = ds.Tables["Sheet1"];
finally
if (impersonationContext != null)
impersonationContext.Undo();
其他编辑
现在 xlsx 文件已添加到组合中。
第三方
在这种情况下不接受第三方解决方案(除非它们允许不受限制的商业用途)。
尝试 - (最后说明:最终我不得不放弃 OleDb 连接。)
我已经尝试了所有提供的不同连接字符串,并且一次只尝试了一种文件类型。没有一个连接字符串适用于任何文件类型。
权限
用户确实有权访问文件及其目录。
【问题讨论】:
查看本页右侧的相关问题列表。最重要的问题有很多赞成票。 @DOK 这些似乎不是我问题的答案。 更正。 CSV 不是 Excel 文件。这是一个文本文件 确保您使用正确的提供程序来读取 Excel 文件。如果你在 office 14 上使用 office 12 的引擎,它将无法读取 确保您使用正确的提供程序,它与安装的 Excel 版本相对应 【参考方案1】:您的连接字符串可能是这里的问题。据我所知,没有 1 可以读取所有 xls、csv 和 xlsx。我认为您使用的是 XLSX 连接字符串。
当我阅读 xls 时,我使用以下连接字符串:
@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + sFilePath + ";Extended Properties='Excel 8.0;HDR=YES;IMEX=1;'"
话虽如此,我还是建议使用第 3 方文件读取器/解析器来读取 XLS 和 CSV,因为根据我的经验,OleDbDataAdapter 取决于正在读取的数据类型(以及它们在每列中的混合程度) .
对于 XLS,请尝试 NPOI https://code.google.com/p/npoi/
对于 CSV,请尝试 http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader
对于 XLSX,试试 EPPlus http://epplus.codeplex.com/
我在上述库方面取得了巨大的成功。
【讨论】:
现在 xlsx 文件也在混合中,这些连接字符串都不适用于 csv、xls 或 xlsx。我已经分别对它们进行了尝试。在这种情况下,第 3 方解决方案是不可接受的。不过感谢您的链接。 本地读取文件(正如第 3 方解决方案所做的那样)是正确读取混合数据的唯一方法。即使您确实使用 oledb 读取它,您很快就会意识到它在某些情况下并不可靠。 即使我尽可能单独处理扩展?我觉得很难相信。有没有办法在没有第三方解决方案的情况下本地读取文件? @call2voyage 它们只是文件,因此如果您可以请求并将它们放入内存中,您可以自己解析它们,但这将是大量的代码要编写。它们的格式各不相同,因此您需要为它们编写不同的解析器。该代码已经在开源项目中编写。在我看来,EPPlus 非常适合 xlsx,只需要您在项目中包含一个 DLL。无需购买许可证,无需 COM 互操作,无需在服务器上安装 Excel。不确定您所说的第 3 方,但获得许可的 .NET DLL 与您自己的代码没有什么不同。 @AaronLS 开源许可证是否允许商业用途?【参考方案2】:为此使用OleDb
接口真的很重要吗?我一直使用Microsoft.Office.Excel.Interop
,也就是说:
using System;
using Microsoft.Office.Interop.Excel;
namespace ***Example
class Program
static void Main(string[] args)
var app = new Application();
var wkbk = app.Workbooks.Open(@"c:\data\foo.xls") as Workbook;
var wksht = wkbk.Sheets[1] as Worksheet; // not zero-based!
for (int row = 1; row <= 100; row++) // not zero-based!
Console.WriteLine("This is row #" + row.ToString());
for (int col = 1; col <= 100; col++)
Console.WriteLine("This is col #" + col.ToString());
var cell = wksht.Cells[row][col] as Range;
if (cell != null)
object val = cell.Value;
if (val != null)
Console.WriteLine("The value of the cell is " + val.ToString());
【讨论】:
互操作,当然!我知道必须有更好的解决方案。我会回复你,让你知道它是否有效。 不幸的是它不起作用,但我已经让它与 EPPlus 一起使用。 嗯。它的哪一部分不起作用?或者......它在什么方面不起作用?【参考方案3】:由于您将处理 xlsx 扩展,您应该选择新的连接字符串。
public static string getConnectionString(string fileName, bool HDRValue, bool WriteExcel)
string hdrValue = HDRValue ? "YES" : "NO";
string writeExcel = WriteExcel ? string.Empty : "IMEX=1";
return "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + fileName + ";" + "Extended Properties=\"Excel 12.0 xml;HDR=" + hdrValue + ";" + writeExcel + "\"";
以上是获取连接字符串的代码。第一个参数需要文件位置的实际路径。第二个参数将决定是否将第一行值视为列标题。第三个参数有助于决定您是要打开连接以创建和写入数据还是只是读取数据。要读取数据,请将其设置为“FALSE”
public static ReadData(string filePath, string sheetName, List<string> fieldsToRead, int startPoint, int endPoint)
DataTable dt = new DataTable();
try
string ConnectionString = ProcessFile.getConnectionString(filePath, false, false);
using (OleDbConnection cn = new OleDbConnection(ConnectionString))
cn.Open();
DataTable dbSchema = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (dbSchema == null || dbSchema.Rows.Count < 1)
throw new Exception("Error: Could not determine the name of the first worksheet.");
StringBuilder sb = new StringBuilder();
sb.Append("SELECT *");
sb.Append(" FROM [" + sheetName + fieldsToRead[0].ToUpper() + startPoint + ":" + fieldsToRead[1].ToUpper() + endPoint + "] ");
OleDbDataAdapter da = new OleDbDataAdapter(sb.ToString(), cn);
dt = new DataTable(sheetName);
da.Fill(dt);
if (dt.Rows.Count > 0)
foreach (DataRow row in dt.Rows)
string i = row[0].ToString();
cn.Dispose();
return fileDatas;
catch (Exception)
【讨论】:
【参考方案4】:这是用于将 2007 Excel 读入数据集
DataSet ds = new DataSet();
try
string myConnStr = "";
myConnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=MyDataSource;Extended Properties=\"Excel 12.0;HDR=YES\"";
OleDbConnection myConn = new OleDbConnection(myConnStr);
OleDbCommand cmd = new OleDbCommand("select * from [Sheet1$] ", myConn);
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.SelectCommand = cmd;
myConn.Open();
adapter.Fill(ds);
myConn.Close();
catch
return ds;
【讨论】:
以上是关于如何使用 C# 从远程位置将 Excel csv 或 xls 文件的行读入 ASP.NET 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章
从 CSV 生成 Excel 电子表格(ASP.NET C#)[重复]
将超过 255 个字符从 excel 导入到 sql server(上一个问题 - 如何使用 ssis 将文本限定 CSV 动态加载到 sql server)