我想从Excel到C#中的二维数组中读取大量单元格。 使用Microsoft.Office.Interop.Excel并一一读取单元格太慢。我知道如何将数组写入范围(Microsoft.Office.Interop.Excel really slow),但我想朝相反的方向做
_Excel.Application xlApp = new _Excel.Application();
_Excel.Workbook xlWorkBook;
_Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlWorkBook = xlApp.Workbooks.Open(path);
xlWorkSheet = xlWorkBook.Worksheets["Engineering BOM"];
_Excel.Range range = (_Excel.Range)xlWorkSheet.Cells[1, 1];
range = range.get_Resize(13000, 9);
string[,] indexMatrix = new string[13000, 9];
// below code should be much faster
for (int i = 1; i < 1300; i++)
{
for (int j = 1; j < 9; j++)
{
indexMatrix[i, j] = xlWorkSheet.Cells[i, j].Value2;
}
}
因此,我想从数组中的单元格范围中获取值(范围大小与数组大小完全相同)。现在,应用正在逐个单元读取数据并将数据写入数组,但这太慢了。有什么办法可以将整个范围直接复制到单元格吗?
预先感谢您:)
答案 0 :(得分:2)
您可以尝试一下,它应该更快,但是:
您必须使用数据表 (在这种情况下,最好使用数据表代替 多维数组。)
您不再需要关心范围 。
那我们该怎么办?连接到excel并进行查询以选择所有数据并填充数据表。我们需要的?几行代码。
首先,我们声明连接字符串:
对于 Excel 2007 或更高版本(*.XLSX
个文件)
string connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 Xml;HDR=No;IMEX=1\";", fullPath);
对于 Excel 2003 (*.XLS
个文件)
string connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0; data source={0}; Extended Properties=\"Excel 8.0;HDR=No;IMEX=1\";", fullPath);
其中fullPath
是Excel文件的完整文件路径
现在,我们必须创建连接并填充数据表:
OleDbConnection SQLConn = new OleDbConnection(strConnectionString);
SQLConn.Open();
OleDbDataAdapter SQLAdapter = new OleDbDataAdapter();
string sql = "SELECT * FROM [" + sheetName + "$]";
OleDbCommand selectCMD = new OleDbCommand(sql, SQLConn);
SQLAdapter.SelectCommand = selectCMD;
SQLAdapter.Fill(dtXLS);
SQLConn.Close();
其中sheetName
是工作表名称,而dtXLS
是填充了所有excel值的数据表。
这应该更快。
答案 1 :(得分:0)
我猜这个范围在某种程度上定义了一个“数据表”。如果是正确的话,最快的方法是使用OleDb或ODbc将其读取为数据(甚至不需要安装excel):
DataTable tbl = new DataTable();
using (OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;" +
$"Data Source={path};" +
@"Extended Properties=""Excel 12.0;HDR=Yes"""))
using (OleDbCommand cmd = new OleDbCommand(@"Select * from [Engineering BOM$A1:i13000]", con))
{
con.Open();
tbl.Load(cmd.ExecuteReader());
}
如果不是,那么您可以这样做:
Excel.Application xl = new Excel.Application();
var wb = xl.Workbooks.Open(path);
Excel.Worksheet ws = (Excel.Worksheet)wb.Worksheets["Engineering BOM"];
var v = ws.Range["A1:I13000"].Value;
(不确定excel本身是否可以进行如此大的数组分配)。