阅读大型 Excel 文档

问题描述 投票:0回答:6

我想知道在 Excel 中读取单元格的最快方法是什么。 我有一个包含 50000 行的 Excel 文件,我想知道如何快速读取它。 我只需要阅读第一列,使用 oledb 连接大约需要 15 秒。 有没有更快的方法?

谢谢

c# excel datatable oledb
6个回答
9
投票

这是一种依赖于使用 Microsoft.Office.Interop.Excel 的方法。

请注意:我使用的 Excel 文件只有一列包含 50,000 个条目的数据。

1)用Excel打开文件,另存为csv,然后关闭Excel。

2)使用StreamReader快速读取数据。

3)按回车换行符拆分数据并将其添加到字符串列表中。

4)删除我创建的csv文件。

我使用 System.Diagnostics.StopWatch 来计时执行,该函数运行需要 1.5568 秒。

public static List<string> ExcelReader( string fileLocation )
{                       
    Microsoft.Office.Interop.Excel.Application excel = new Application();
    Microsoft.Office.Interop.Excel.Workbook workBook =
        excel.Workbooks.Open(fileLocation);
    workBook.SaveAs(
        fileLocation + ".csv",
        Microsoft.Office.Interop.Excel.XlFileFormat.xlCSVWindows
    );
    workBook.Close(true);
    excel.Quit();
    List<string> valueList = null;
    using (StreamReader sr = new StreamReader(fileLocation + ".csv")) {
        string content = sr.ReadToEnd();
        valueList = new List<string>(
            content.Split(
                new string[] {"\r\n"},
                StringSplitOptions.RemoveEmptyEntries
            )
        );
    }
    new FileInfo(fileLocation + ".csv").Delete();
    return valueList;
}

资源:

http://www.codeproject.com/Articles/5123/Opening-and-Navigating-Excel-with-C

如何用C#分割回车符字符串?


3
投票

您可以放置使用 OLEDb 提供程序读取 50000 条记录的代码吗?我尝试过这样做,读取 3 列的 50000 条记录需要 4-5 秒。我按照下面的方法做了,你看看,也许对你有帮助。 :)

       // txtPath.Text is the path to the excel file
        string conString = @"Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + txtPath.Text + ";" + "Extended Properties=" + "\"" + "Excel 12.0;HDR=YES;" + "\"";

        OleDbConnection oleCon = new OleDbConnection(conString);

        OleDbCommand oleCmd = new OleDbCommand("SELECT field1, field2, field3 FROM [Sheet1$]", oleCon);

        DataTable dt = new DataTable();

        oleCon.Open(); 
        dt.Load(oleCmd.ExecuteReader());
        oleCon.Close();

如果您可以将您的代码放在这里,以便我尝试纠正。 :)


2
投票

OLEDB 总是需要更多时间。

SQL Server 2005/2008 将使速度更快。

对于 OLEDB 连接,每秒需要 7 条记录,而

对于 SQLServer 来说,每秒需要 70 条记录。

读取逗号分隔的文件不需要太多时间,但插入数据需要时间。

我确实经历过这件事。


0
投票

您只想从文件中读取数字列表?一定要在Excel中吗?是否有非技术人员更新该列表?如果您想将单列中的 50,000 个数字读取到内存中的列表中,只需将单元格复制到文本文件并使用 TextReader 读取即可。马上就可以了。

List<string> ReadFile(string path)
{
   TextReader tr = new StreamReader(path);
   string line;
   List<string> lines = new List<string>();
   while((line=tr.ReadLine())!=null)
   {
       //if this was a CSV, you could string.split(',') here
       lines.add(line);
   }

   return lines;
}

0
投票

我面临着同样的事情,我在办公室开发中心阅读:

http://social.msdn.microsoft.com/Forums/office/en-US/418ada31-8748-48d2-858b-d177326daa76/export-to-excel-open-xml-sdk-vs-microsoftofficeinteropexcel?forum= oxmlsdk

您有两种操作 Excel 文件的选择:

  • Microsoft.Office.Interop.Excel 使用 Excel.Application 作为代码执行的附加层
  • 开放 XML SDK,允许开发人员直接使用关闭的文件

两者之间没有太大区别,但在性能是一个问题的情况下,您应该使用 Open XML SDK,它可能更快一点,并且在处理之前不需要太多时间打开大文件。正如您也可以在上面的链接中阅读和我引用的那样:

不支持用于自动化目的的 Office。 Office 应用程序并非设计为在没有人工监督的情况下运行,并且具有令人讨厌的“挂起”倾向

此链接提供了学习 open xml sdk 的良好开端: http://msdn.microsoft.com/en-us/library/office/gg575571.aspx


0
投票

您可以使用XlsxHelper这是 NuGet 链接。 XlsxHelper 旨在读取大型 Excel Xlsx 文件。

注意:在处理大文件时,我们应该记住,并非所有数据都加载到 RAM 中。避免在 IEnumerable 上调用

ToList()
ToArray()
。以流式处理记录(读取行 -> 处理行 -> 读取行 -> 处理行)。

© www.soinside.com 2019 - 2024. All rights reserved.