我想从C#中的Excel文档中提取所有文本数据,并遇到性能问题。在下面的代码中,我打开工作簿,遍历所有工作表,并循环使用范围中的所有单元格,并随时提取每个单元格中的文本。问题是,这需要14秒来执行。C#Excel Interop在循环遍历单元格时缓慢
public class ExcelFile
{
public string Path = @"C:\test.xlsx";
private Excel.Application xl = new Excel.Application();
private Excel.Workbook WB;
public string FullText;
private Excel.Range rng;
private Dictionary<string, string> Variables;
public ExcelFile()
{
WB = xl.Workbooks.Open(Path);
xl.Visible = true;
foreach (Excel.Worksheet CurrentWS in WB.Worksheets)
{
rng = CurrentWS.UsedRange;
for (int i = 1; i < rng.Count; i++)
{ FullText += rng.Cells[i].Value; }
}
WB.Close(false);
xl.Quit();
}
}
在VBA我会做这样的事情,这需要约1秒:
Sub run()
Dim strText As String
For Each ws In ActiveWorkbook.Sheets
For Each c In ws.UsedRange
strText = strText & c.Text
Next c
Next ws
End Sub
或者,甚至更快(小于1秒):
Sub RunFast()
Dim strText As String
Dim varCells As Variant
For Each ws In ActiveWorkbook.Sheets
varCells = ws.UsedRange
For i = 1 To UBound(varCells, 1)
For j = 1 To UBound(varCells, 2)
strText = strText & CStr(varCells(i, j))
Next j
Next i
Next ws
End Sub
也许东西正在C#中for循环中发生,我不知道?是否可以将一个范围加载到数组类型对象中(如我的最后一个示例中),以允许仅迭代值而不是单元对象?
这并不罕见,VBA在进程中运行,但是您的第一个代码段不在运行过程中。跨越流程边界缓慢。使用数组可以减少往返次数或基于OpenXML的进程内解决方案(如EPPlus或ClosedXML)。 –
感谢汉斯 - 那么问题仍然是如何将一个范围加载到数组中以避免往返? – pwwolff