我是c#的初学者,我有一个30000行的excel文件,我想读它并在每个单元格上做一些处理。我使用此代码进行读取,之后我在这个excel文件上有一个for循环,速度很慢(约2小时)。你能帮我解决这个问题吗?有没有办法快速读取这个文件?
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);
你还没有分享你所询问的循环,但如果代码示例重复了30,000次,那么一个大问题是:
我很惊讶Windows并没有崩溃。它在2小时后甚至完成了吗?
一个好的开始是通过谷歌搜索您不完全理解的每个关键字。就个人而言,我喜欢MSDN,但有成千上万的有用网站和示例。
例如:
new Excel.Application
的作用吗?我们来看看。 Click here,然后转到第一个搜索结果。Workbooks.Open
做什么? Click here.我实际上对C#Interop没有多少经验,但答案很容易获得。听起来像@Zameer's links可能是你需要的 - 但不仅仅是复制/粘贴代码,请确保你也理解这些例子的每一步!
一开始可能会压倒一切,有时甚至不知道从哪里开始寻找,但那里有无数的资源。
另请参阅:
祝好运!
我希望我听起来根本没有贬低;有时很难说出一个人的经验水平,即使不管怎样,我认为简单的事情往往是最容易忽视的(包括我自己!)我仍然认为对象处理至少是问题的一部分。
我在处理多个对象时遇到内存或性能问题时有时会使用的故障排除方法是“简化和总结”。我将重命名所有代码的副本,删除除对象之外的所有内容,并将它们重命名为“object subtype + number”,以查看类似这样的内容:
正如我所说,我对C#相当新,但我知道在其他语言中,忘记关闭和释放对象会导致严重的问题,尤其是在反复循环时。
此外,我不能肯定地说,但我怀疑你最好重新使用在循环之前创建的单个Excel.Application
对象,而不是使用多个create / open / close / release来刻录资源。
另一种可能性,而不是通过UsedRange
中的每一行和列,也许尝试相当于For Each
循环的C。
Dim c as Range
For Each c in xlWorkSheet.UsedRange
c.Value = .....
...etc..
Next
最后想到,如果它仍然很慢,请在这里和那里贴上一些计时器,以确切地找出造成性能问题的原因。 (还要检查Windows任务管理器在运行时是否关注资源。)
你可以使用Open XML SDK
来达到这个目的。它与interop方法不同,读取工作簿的Interop方法通常也很慢。
我已经使用openxml sdk来创建和读取包含不同表单上超过10k行的excel。这应该符合你的目的。
这里有一些链接可以帮助您入门。
Read excel as data table with OpenXML
希望能帮助到你