使用 c# 读取 Excel 文件并写入文本文件非常慢
本文关键字:文件 文本 非常 读取 Excel 使用 | 更新日期: 2023-09-27 17:56:14
我在 c# wpf 应用程序中有以下代码。 我正在读取一个 Excel 文件,删除隐藏字符并尝试保留单元格格式,然后将数据写入管道分隔的文本文件。 这段代码看起来非常简单,但速度很慢。 关于我为什么以及如何改进流程的任何想法?
private void ReadWriteExcelData(string strFileName)
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range, colrange, rowrange;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(strFileName, 0, true, 5, "", "", true,
Excel.XlPlatform.xlWindows, "'t", false, false, 0, true, 1, 0);
Excel.Sheets excelSheets = xlWorkBook.Worksheets;
if (blnLetExcelDecide)
{
range = xlWorkSheet.UsedRange;
}
else
{
Excel.Range c1 = xlWorkSheet.Cells[lngExcelStartRow, strExcelStartCol];
Excel.Range c2 = xlWorkSheet.Cells[lngExcelEndRow, strExcelEndCol];
range = (Excel.Range)xlWorkSheet.get_Range(c1, c2);
}
colrange = range.Columns;
lngNumCols = colrange.Count;
rowrange = range.Rows;
lngNumRows = rowrange.Count;
object[,] values = (object[,])range.Value;
string[] Fields = new string[lngNumCols];
int NumRow = 1;
while (NumRow <= values.GetLength(0))
{
strDataRow = "";
for (lngColCnt = 1; lngColCnt <= lngNumCols; lngColCnt++)
{
strCellData = range[NumRow, lngColCnt].Text;
strCellData = strCellData.TrimStart(' ');
if (strCellData == null)
{
strCellData = string.Empty;
}
else
{
strCellData = strCellData.Replace("'r'n", " ").Replace("'n", " ").Replace("'r", " ");
}
if (lngColCnt == lngNumCols)
{
strDataRow += strCellData;
}
else
{
strDataRow += strCellData + "|";
}
}
WriteDataRow(strDataRow, strFullOutputFileName);
if (NumRow % intModNumber == 0)
{
dblProgressPct = ((double)NumRow / (double)lngNumRows);
dblProgress = Math.Round((dblProgressPct * 100), 0);
prgIndicator.Width = dblProgress * 4;
lblPrctPrgrs.Content = dblProgress + "%";
grdProgressIndicator.InvalidateVisual();
System.Windows.Forms.Application.DoEvents();
}
NumRow++;
}
}
下面是 WriteDataRow 例程:
public void WriteDataRow(string strDataRow, string strFullFileName)
{
using (StreamWriter file = new StreamWriter(@strFullFileName, true, Encoding.GetEncoding("iso-8859-1")))
{
file.WriteLine(strDataRow);
}
}
这是一种涉及使用一些 VBA 读取所有单元格的文本值的方法。
首先,在常规模块中创建一个包含此函数的 xlsm 文件:
Public Function GetText(strWB As String, strSheet As String, _
strAddress As String) As Variant()
Dim rng As Range, arr() As Variant, r As Long, c As Long
Set rng = Workbooks(strWB).Worksheets(strSheet).Range(strAddress)
rng.Columns.AutoFit 'avoid getting "######" !
ReDim arr(0 To rng.Rows.Count - 1, 0 To rng.Columns.Count - 1)
For r = 1 To rng.Rows.Count
For c = 1 To rng.Columns.Count
arr(r - 1, c - 1) = rng.Cells(r, c).Text
Next c
Next r
GetText = arr
End Function
打开数据文件后,使用宏打开文件:
Excel.Workbook xlCodeWb = xlApp.Workbooks.Open(@"D:'Folder'Stuff'TheMacro.xlsm");
然后调用宏:
object[,] values = xlApp.Run("'" + xlCodeWb.Name + "'!GetText",
xlWorkBook.Name, xlWorkSheet.Name, range.Address);
values
现在是工作表中所有 Text 值的 2D 数组,而无需在跨进程边界的单独调用中挑选每个值的开销。 您可以循环访问数组并将"清理"值写入文件。
顺便说一句,您可能应该考虑在 main 方法中打开并写入输出文件:打开它一次,然后编写行,仅在完成后关闭它。 无需为每行重新打开它。
我添加了对格式类型"#,##0.00_)Red的检查。 只有当这个单元格有这种格式时,我才做了Convert.ToString(range[NumRow, lngColCnt]。值 2)。