在C#中快速读取excel文件

我是C#的初学者,我有一个30000行的Excel文件,我想读取它,并在每个单元格上做一些进程。 我用这个代码读取,之后,我有一个for循环这个很慢(约2小时)的Excel文件。 你能帮我解决这个问题吗? 有没有什么办法来读取这个文件非常快?

Excel.Application xlApp; Excel.Workbook xlWorkBook; Excel.Workbook xlWorkBookahan1; Excel.Workbook xlWorkBookahan2; Excel.Workbook xlWorkBookahangh; Excel.Worksheet xlWorkSheet; Excel.Worksheet xlWorkSheetahan1; Excel.Worksheet xlWorkSheetahan2; Excel.Worksheet xlWorkSheetahangh; Excel.Range range; string str; int rCnt; int cCnt; int rw = 0; int cl = 0; // Excel.Application xlahan1 = new Microsoft.Office.Interop.Excel.Application(); Excel.Application xlahan2 = new Microsoft.Office.Interop.Excel.Application(); Excel.Application xlahangh = new Microsoft.Office.Interop.Excel.Application(); object misValue = System.Reflection.Missing.Value; if (xlahan1 == null) { MessageBox.Show("Excel is not properly installed!!"); return; } xlWorkBookahan1 = xlahan1.Workbooks.Add(misValue); xlWorkBookahan2 = xlahan2.Workbooks.Add(misValue); xlWorkBookahangh = xlahangh.Workbooks.Add(misValue); xlWorkSheetahan1 = (Excel.Worksheet)xlWorkBookahan1.Worksheets.get_Item(1); xlWorkSheetahan2 = (Excel.Worksheet)xlWorkBookahan2.Worksheets.get_Item(1); xlWorkSheetahangh = (Excel.Worksheet)xlWorkBookahangh.Worksheets.get_Item(1); // xlApp = new Excel.Application(); xlWorkBook = xlApp.Workbooks.Open(@"C:\Users\maedeh\Desktop\Base.xls", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0); xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1); range = xlWorkSheet.UsedRange; rw = range.Rows.Count; cl = range.Columns.Count; int ahanghtei = 0, ahan1 = 0, ahan2 = 0, fooladghatei = 0, foolad1 = 0, foolad2 = 0, ngarmghatei = 0, ngarm1 = 0, ngarm2 = 0, nsardghatei = 0, nsard1 = 0, nsard2 = 0, energyghatei = 0, energy1 = 0, energy2 = 0, hamlghatei = 0, haml1 = 0, haml2 = 0, tmarkazighatei = 0, tmarkazi1 = 0, tmarkazi2 = 0, tgmarkazighatei = 0, tgmarkazi1 = 0, tgmarkazi2 = 0, dfnetghatei = 0, dfnet1 = 0, dfnet2 = 0, mtnasoozghatei = 0, mtnasooz1 = 0, mtnasooz2 = 0, fooladsabaghatei = 0, fooladsaba1 = 0, fooladsaba2 = 0; for (rCnt = 2; rCnt <= rw; rCnt++) { if (range.Cells[rCnt, 25].value == 1)// { if (((range.Cells[rCnt, 16]).value <= 1999 && (range.Cells[rCnt, 16]).value >= 1000)) { if ((range.Cells[rCnt, 120]).value >= 1000 && (range.Cells[rCnt, 120]).value <= 1999) { ahanghtei++; xlWorkSheetahangh.Cells[ahanghtei, 1] = range.Cells[rCnt, 1]; xlWorkSheetahangh.Cells[ahanghtei, 2] = range.Cells[rCnt, 2]; xlWorkSheetahangh.Cells[ahanghtei, 3] = range.Cells[rCnt, 3]; } else { xlWorkSheet.Rows[rCnt].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red); ahan1++; xlWorkSheetahan1.Cells[ahan1, 1] = range.Cells[rCnt, 1]; xlWorkSheetahan1.Cells[ahan1, 2] = range.Cells[rCnt, 2]; xlWorkSheetahan1.Cells[ahan1, 3] = range.Cells[rCnt, 3]; } } else { if ((range.Cells[rCnt, 120]).value >= 1000 && (range.Cells[rCnt, 120]).value <= 1999) { xlWorkSheet.Rows[rCnt].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow); //xlWorkSheet.Cells[rCnt, 1].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Yellow); ahan2++; xlWorkSheetahan2.Cells[ahan2, 1] = range.Cells[rCnt, 1]; xlWorkSheetahan2.Cells[ahan2, 2] = range.Cells[rCnt, 2]; xlWorkSheetahan2.Cells[ahan2, 3] = range.Cells[rCnt, 3]; } } xlWorkBookahan1.SaveAs("C:\\ahan1.xls", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue); xlWorkBookahan2.SaveAs("C:/Users/maedeh/Desktop/ahan2.xls"); xlWorkBookahangh.SaveAs("C:/Users/maedeh/Desktop/ahangh.xls"); xlWorkBookahan1.Close(true, misValue, misValue); xlWorkBookahan2.Close(true, misValue, misValue); xlWorkBookahangh.Close(true, misValue, misValue); xlahan1.Quit(); xlahan2.Quit(); xlahangh.Quit(); Marshal.ReleaseComObject(xlWorkSheetahan1); Marshal.ReleaseComObject(xlWorkSheetahan2); Marshal.ReleaseComObject(xlWorkSheetahangh); Marshal.ReleaseComObject(xlWorkBookahan1); Marshal.ReleaseComObject(xlWorkBookahan2); Marshal.ReleaseComObject(xlWorkBookahangh); Marshal.ReleaseComObject(xlahan1); Marshal.ReleaseComObject(xlahan2); Marshal.ReleaseComObject(xlahangh); Marshal.ReleaseComObject(range); Marshal.ReleaseComObject(xlWorkSheet); //close and release xlWorkBook.Close(); Marshal.ReleaseComObject(xlWorkBook); //quit and release xlApp.Quit(); Marshal.ReleaseComObject(xlApp); 

你没有分享你所问的Loop ,但是如果代码示例是被重复的30,000次,那么一个大问题就是:

  • 你打开同一个文件30,000次

  • 你正在closures该文件次。

我很惊讶Windows不会崩溃。 2小时后甚至完成了吗?

一个好的开始是通过谷歌search你不完全理解的每个关键字。 就个人而言,我喜欢MSDN,但有成千上万的有用的网站和例子。

例如:

  • 你知道什么new Excel.Application做? 让我们找出来。 点击这里 ,然后转到第一个search结果。

  • 接下来, Workbooks.Open做什么? 点击这里。

我其实没有太多的C#Interop经验,但答案是容易获得的。 听起来像@ Zameer的链接可能是你需要的 – 但不只是复制/粘贴代码,确保你理解这些例子的每一步!

起初它可能是压倒性的,有时甚至不知道从哪里开始寻找,但是那里有无数的资源。

另请参阅:

  • 游览

  • 如何提出一个好的问题

  • 如何创build一个最小,完整和可validation的例子

祝你好运!


编辑:

我希望我完全没有听起来贬低; 有时很难说出一个人的经验水平,即使不这样,我认为简单的事情往往是最容易忽略的(我自己也包括在内)。我仍然认为对象处理至less是问题的一部分。

在处理多个对象时,我有时会遇到有关内存或性能问题的疑难解答方法,那就是“简化和总结”。 我将重命名所有代码的副本,删除除对象之外的所有对象,并将其重命名为“object subtype + number”,以查看类似如下的内容:

objectcounts

正如我所说,我相当新的C#,但我知道在其他语言中,忘记closures和释放对象可能会导致严重的问题,尤其是当反复循环。

另外我不能肯定地说,但我怀疑你最好重新使用一个Excel.Application对象,在循环之前创build,而不是使用多个create / open / close / release来刻录资源。

另一种可能性,不是经过UsedRange每一行和每一列,而是尝试一个For Each循环的C等价物。

 Dim c as Range For Each c in xlWorkSheet.UsedRange c.Value = ..... ...etc.. Next 

最后想到,如果速度还是很慢的话,可以在这里粘贴一些定时器,以确定究竟是什么导致了性能问题。 (同时在运行时检查Windows任务pipe理器以关注资源。)

您可以使用Open XML SDK来达到此目的。 它不同于互操作方法,读取工作簿的Interop方法通常很慢。

我已经使用openxml sdk创build并读取包含不同工作表上超过10k行的excel。 这应该是你的目的。

这里有一些链接,让你开始。

使用OpenXML读取excel

使用OpenXML作为数据表读取excel

希望能帮助到你