0

所以我试图用 C# 读取一个 excel 文件,该文件是 181MB。我尝试过使用 Microsoft.Office.Interop.Excel、OpenXML、ClosedXML 和 ExcelDataReader。我无法让 OpenXML 正常工作,并且 ClosedXML 似乎存在与大型 excel 文件有关的问题(读取文件也需要至少 6 分钟)。我最喜欢 ExcelDataReader,因为我可以像读取数组一样读取数据表,但读取文件确实需要 4-5 分钟,这比 Interlop 快得多,但仍然需要等待很长时间。我正在考虑将 excel 文档转换为 csv 文件,但是当我这样做时,大小从 181 MB 变为 248 MB,所以我不确定它是否会更有效。它还迫使用户执行额外的步骤将他们的文件转换为 csv,但如果性能值得,我会尝试这条路线。

不幸的是,我无法预先确定 excel 文档将有多少列和行,因为用户将使用 openFileDialog 来选择一个文件。

ExcelDataReader 是最好的方法还是有更好的解决方案?

这是我当前的代码,以防我可以做出一些改进:

OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Excel Files|*.xls;*.xlsx;*.slxm";
if (openFileDialog.ShowDialog() == true)
{
    using (var stream = File.Open(openFileDialog.FileName, FileMode.Open, FileAccess.Read))
    {
        using (var reader = ExcelReaderFactory.CreateReader(stream))
        {
            //results will be in dataSet.Tables
            var dataSet = reader.AsDataSet();
            var dataTable = dataSet.Tables[0];

            int r = 0;
            for(int c = 0; c < dataTable.Columns.Count; c += 3)
            {
                TagListData.Add(new TagClass { IsTagSelected = false, TagName = dataTable.Rows[r][c].ToString(), rIndex = r, cIndex = c });
            }                    
        }
    }
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
}
4

1 回答 1

1

想法 1:ExcelDataReader 的 AsDataSet 存在一些开销 - 因此在处理大工作表时直接使用阅读器界面是个好主意。它实现IDataReader接口并提供对数据的 pr-row 级别访问:

using (var reader = ExcelReaderFactory.CreateReader(stream)) {
    reader.Read();
    for(int c = 0; c < reader.FieldCount; c += 3) {
        TagListData.Add(new TagClass { IsTagSelected = false, TagName = Convert.ToString(reader.GetValue(c)), rIndex = r, cIndex = c });
    }                    
}

想法2:尝试传递ExcelDataSetConfiguration.UseColumnDataType = false给AsDataSet,这消除了内部传递并减少了内存压力,因此应该显着提高大型工作表的性能

于 2018-08-10T10:28:29.020 回答