C#处理Excel表格速度很慢

hello_mcu 2017-12-07 02:58:36
工程需要,做了一个处理重复表号的一个表格。
表格里第一列是表号;第一行是标题头;从第二行开始是12位数字的表号。这个小程序的用途就是将相同表号的这一行删除掉。比如第二行取表号,然后与第3行,第N行比较,遇到相同的,就把这一行删掉;依次做下去,最后保存的表格每行的表号都是唯一的。
做的这个小程序,处理速度极慢,1137行的数据,按道理说,应该很快。我算了下时间,10分钟才处理300来个。是两层循环,循环是慢点,但我觉得不至于这么慢。
因为对C#了解很少,找不到问题,请朋友们指点下,谢了。
下面上截图和代码:


 private void OpenExcel(string strFileName)
{
object missing = System.Reflection.Missing.Value;
int meterColumn = 0;
int rowEffictive = 0;
string[] meterNo = new string[150000];
try
{
string workTmp = strFileName;
Range range = null;
objExcelApp = new ApplicationClass();
objExcelWorkBooks = objExcelApp.Workbooks;
objExcelWorkbook = objExcelWorkBooks.Open(strFileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
objExcelWorkSheet = (Worksheet)objExcelWorkbook.Worksheets.get_Item(1); //获取sheet1工作薄

int rowTotal = objExcelWorkSheet.UsedRange.Cells.Rows.Count; //取得行数
int columnTotal = objExcelWorkSheet.UsedRange.Cells.Columns.Count; //得到列数

textBox1.Text = "共计" + rowTotal.ToString() + "数据";

for (int i = 1; i < rowTotal + 1; i++) //从第二行开始
{
string meterNum = "";
string tempNum = "";
meterNum = ((Microsoft.Office.Interop.Excel.Range)objExcelWorkSheet.Cells[i, 1]).Text.ToString(); //赋值表号
for (int j = i + 1; j < rowTotal+1; j++)
{
tempNum = ((Microsoft.Office.Interop.Excel.Range)objExcelWorkSheet.Cells[j, 1]).Text.ToString();
if (tempNum == meterNum) //表号比较
{
range = (Microsoft.Office.Interop.Excel.Range)objExcelWorkSheet.Rows[j, missing];
range.Delete(Microsoft.Office.Interop.Excel.XlDeleteShiftDirection.xlShiftUp); //一样就删除,下面的行上移
rowTotal = objExcelWorkSheet.UsedRange.Cells.Rows.Count; //获取新的有效行数
}

}
textBox2.Text = "处理第" + i.ToString();
}
string fileName = System.Windows.Forms.Application.StartupPath + "处理后.xlsx";
objExcelWorkbook.SaveAs(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
//Creat_ConfigExl((exlFileName + "配置表.xlsx"), meterNo, rowTotal); //add 2017-7-13

objExcelApp.Quit(); //要退出EXCEL操作,否则进程不会被结束,占用资源
//Write_ToExl(meterNo,meterColumn);
}
...全文
3475 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复 1
是使用什么内存里边的数据结构来保存数据,其实不重要。重要地是“你要多少次跨进程通讯Excel进程?”这个问题。比如说你不是1次程序内部操作就读取Excel进程中的一个二维数组区域数据,而是100万次操作才读取这个数据,那么自然就要把原本2秒钟的事情搞成2分钟以上,这跟你在自己程序中用什么高达上的结构来保存数据其实都没有关系了。
  • 打赏
  • 举报
回复
我之前举过例子写了几个常用的 excel 操作:http://bbs.csdn.net/topics/391975896?page=
leon51 2017-12-12
  • 打赏
  • 举报
回复 1
引用
你把excel读成一个datatable ,在table里处理这些事情不就完了吗? table里就不用考虑过滤列头这些事情了,而且一个循环就可以搞定, 处理完之后在写回excel
高见,我之前都是放在一个二维数组,速度尚可
wangmin06jb 2017-12-12
  • 打赏
  • 举报
回复 1
先把数据读出来,处理好,再写到excel中
plcly1 2017-12-08
  • 打赏
  • 举报
回复 1
读出来,用对象处理,然后再存回去 对象处理搜索一下linq去重
FainSheeg 2017-12-08
  • 打赏
  • 举报
回复
尽量避免使用ExcelApplication来操作Excel文件,那速度真是没得说,用微软的数据库引擎或者用NOPI都可以
秋的红果实 2017-12-08
  • 打赏
  • 举报
回复
NPOI或者oledb
泡泡龙 2017-12-08
  • 打赏
  • 举报
回复 1
不要直接操作range,读到数组里面再操作,然后一次写回去
hello_mcu 2017-12-07
  • 打赏
  • 举报
回复
private void OpenExcel(string strFileName) { object missing = System.Reflection.Missing.Value; int meterColumn = 0; int rowEffictive = 0; string[] meterNo = new string[150000]; try { string workTmp = strFileName; Range range = null; objExcelApp = new ApplicationClass(); objExcelWorkBooks = objExcelApp.Workbooks; objExcelWorkbook = objExcelWorkBooks.Open(strFileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); objExcelWorkSheet = (Worksheet)objExcelWorkbook.Worksheets.get_Item(1); //获取sheet1工作薄 int rowTotal = objExcelWorkSheet.UsedRange.Cells.Rows.Count; //取得行数 int columnTotal = objExcelWorkSheet.UsedRange.Cells.Columns.Count; //得到列数 textBox1.Text = "共计" + rowTotal.ToString() + "数据"; for (int i = 1; i < rowTotal + 1; i++) //从第二行开始 { string meterNum = ""; string tempNum = ""; meterNum = ((Microsoft.Office.Interop.Excel.Range)objExcelWorkSheet.Cells[i, 1]).Text.ToString(); //赋值表号 for (int j = i + 1; j < rowTotal+1; j++) { tempNum = ((Microsoft.Office.Interop.Excel.Range)objExcelWorkSheet.Cells[j, 1]).Text.ToString(); if (tempNum == meterNum) { // range = (Microsoft.Office.Interop.Excel.Range)objExcelWorkSheet.Rows(j, missing); range = (Microsoft.Office.Interop.Excel.Range)objExcelWorkSheet.Rows[j, missing]; range.Delete(Microsoft.Office.Interop.Excel.XlDeleteShiftDirection.xlShiftUp); rowTotal = objExcelWorkSheet.UsedRange.Cells.Rows.Count; } } textBox2.Text = "处理第" + i.ToString(); } string fileName = System.Windows.Forms.Application.StartupPath + "处理后.xlsx"; objExcelWorkbook.SaveAs(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); //Creat_ConfigExl((exlFileName + "配置表.xlsx"), meterNo, rowTotal); //add 2017-7-13 objExcelApp.Quit(); //要退出EXCEL操作,否则进程不会被结束,占用资源 //Write_ToExl(meterNo,meterColumn); } finally { objExcelApp.Quit(); } } 上面代码不知道怎么插的,比较乱。
大然然 2017-12-07
  • 打赏
  • 举报
回复 1
你把excel读成一个datatable ,在table里处理这些事情不就完了吗? table里就不用考虑过滤列头这些事情了,而且一个循环就可以搞定, 处理完之后在写回excel
全栈极简 2017-12-07
  • 打赏
  • 举报
回复
1、可以设置断点调试看哪一步执行慢 2、使用NPOI操作Excel。http://www.cnblogs.com/guwei4037/p/3499327.html

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧