【问题标题】:Reading very large excel file读取非常大的ex​​cel文件
【发布时间】:2015-09-17 22:33:19
【问题描述】:

我正在使用这篇文章来读取一个非常大的 excel 文件,使用 SAX 方法。

https://msdn.microsoft.com/en-us/library/office/gg575571.aspx

由于客户端计算机没有足够的内存,无法将值存储在 DataTable 或内存中。尝试读取并立即将值存储到数据库中:

// The SAX approach.

static void ReadExcelFileSAX(string fileName)
{
        using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false))
    {

        WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
        WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();

        OpenXmlReader reader = OpenXmlReader.Create(worksheetPart);
        string text;
        while (reader.Read())
        {
            if (reader.ElementType == typeof(CellValue))
            {
                text = reader.GetText();
                Console.Write(text + " ");
            }
        }
        Console.WriteLine();
        Console.ReadKey();
    }
}

例如当我阅读这个excel文件时:

Test 1
22
345345
345345435
2333
333333
4444
4444444
324324
99999

我得到这个输出:

Blank
22
Blank
345345
Blank 
etc

我不知道这些空白是从哪里来的。试图将 if 语句放在那里测试空白,然后我错过了最后一个值 99999。

那个读者似乎太有限了。非常感谢您的建议,我的意思是什么!

【问题讨论】:

  • 为什么不通过批处理来解析和持久化文件呢?一次 1000 行应该没问题吧?

标签: c# excel openxml openxml-sdk large-data


【解决方案1】:

OpenXmlReader 将开始和结束元素视为独立项。这些可以通过检查IsStartElementIsEndElement 属性来区分。

您的空白值是由于 GetText 返回空字符串的结尾元素。

您有 2 个选项来修复它。首先,您可以在循环中检查 IsStartElement

while (reader.Read())
{
    if (reader.ElementType == typeof(CellValue)
        && reader.IsStartElement)
    {
        text = reader.GetText();
        Console.WriteLine(text + " ");
    }
}

或者,您可以使用LoadCurrentElement 方法加载整个元素,同时消耗您之前获得的开始和结束:

while (reader.Read())
{
    if (reader.ElementType == typeof(CellValue))
    {
        CellValue cellVal = (CellValue)reader.LoadCurrentElement();
        Console.WriteLine(cellVal.Text);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    • 2016-03-09
    • 2022-01-23
    • 2017-12-21
    • 1970-01-01
    相关资源
    最近更新 更多