首页 新闻 会员 周边 捐助

ASP.NET在服务器端生成Excel文件速度过慢(超过半小时),有什么办法优化吗?

0
悬赏园豆:20 [已解决问题] 解决于 2013-11-08 10:05

先说下我的大体逻辑吧.

是在服务器端安装了Office2010,然后用引用了Microsoft.Office.Interop.Excel,通过复制一个模板文件,得到Excel application对象,然后复制sheet,最后将DataSet中的数据写入sheet.

 

因为之前的一些特殊要求,所以是每个单元格去写入数据,同时进行一些逻辑运算,worksheet.Cells[i,j]=string;这样在服务器端生成Excel的时候就比较慢,慢到超过半小时.

 

所以想问问有没有大神能帮忙给个优化方案?

PS.这里其实很迷惑,我这个功能之前做在winform的时候,大概两分钟就可以产生好Excel了.但是没想到移植到ASP.Net之后,有这么大的问题.按道理来说,不是应该服务器调用的资源比本地要快吗.

问题补充:

现在我也在做逻辑的分离,将逻辑和写入Excel这里分开,希望这样能提高一部分效率.

新手猿的主页 新手猿 | 初学一级 | 园豆:99
提问于:2013-11-05 14:32
< >
分享
最佳答案
0

遇到这种问题,我一般推荐NPOI(Office2003),Epplus(Office2007)

 

如果要使用Office组件的话,可以先将数据保存为二维数组,然后通过AddRange的方式实现,这样能提高速度。

收获园豆:4
幻天芒 | 高人七级 |园豆:37207 | 2013-11-05 17:11

对的,可以使用AddRange的方法提速,那如果是DataTable里面的数据呢?

新手猿 | 园豆:99 (初学一级) | 2013-11-06 09:33

想问问,你这里的AddRange是怎么去实现的?

新手猿 | 园豆:99 (初学一级) | 2013-11-06 10:52

@新手猿:AddRange是Excel组件自带的方法。DataTable你需要先转换为二位数组。 

幻天芒 | 园豆:37207 (高人七级) | 2013-11-06 17:10

@幻天芒: AddRange我知道怎么用了,但是相对于下面我的方法还是慢了,有多少Row都要去请求一下.

 

谢谢大家,问题我已经解决了,我之前是Sheet.Celss[top,row]=string;这样来写数据的,因为方便做这边比较纠结的逻辑运算.

之后我将逻辑和写入分离了,还是发现很慢,然后去查,说是用Sheet.Celss[top,row]这种方法每次都要请求一次链接,然后才能写入数据

所以我修改成先得到要写入的DataTable,然后转换成string[,]数组.

再得到Excel.Range.get_Range("A2",missing.value),(这里A2的意思是从A列的第2行起的Range对象)

通过设置Range.get_Resize(RowsSize,ColumnSize)(就是你DataTable数据有多少行和多少列,在Excel.Range对象中得到从A2开始的,这么大的区域.)

最后Excel.Range.Value=objDate;(将你DataTable转换出来的数组,直接一次写入你之前得到的Range区域里里面)

速度灰一样的快.大家可以试试.

新手猿 | 园豆:99 (初学一级) | 2013-11-08 10:06

@新手猿:嗯,不错。用第三方控制性更好,哈哈~ 

幻天芒 | 园豆:37207 (高人七级) | 2013-11-08 10:10
其他回答(4)
0

试试这种方式 导出EXCEL

 

http://www.cnblogs.com/yipeng-yu/archive/2013/03/21/2972720.html

收获园豆:4
Yu | 园豆:12990 (专家六级) | 2013-11-05 16:05
0

直接用逗号分隔,然后保存为csv文件的不行么? 目测十万行(大概五六列,数据不是很复杂)导出不到10秒钟。

收获园豆:4
程序诗人 | 园豆:313 (菜鸟二级) | 2013-11-05 18:03

这个还真不能保存为csv文件,必须是Excel.

支持(0) 反对(0) 新手猿 | 园豆:99 (初学一级) | 2013-11-06 09:31
0

还是用npoi吧!最新的虽是测试版 也够平常用了!还支持office2007的版本,再说导出excel导出03的就行,国内还是office03的多!

            //IWorkbook wk = new HSSFWorkbook(); //写03的xls
            IWorkbook wk = new XSSFWorkbook();   //写07之后xlsx
            ISheet sheet = wk.CreateSheet("A1"); //创建叫A1的Sheet
            IRow row1 = sheet.CreateRow(0);      //创建第一行 
            for (int i = 0; i < 10; i++) {       //循环给单元格设置内容
                row1.CreateCell(i).SetCellValue("create" + i);
            }
            IRow row2 = sheet.CreateRow(1);
            for (int i = 0; i < 8; i++) {
                row2.CreateCell(i).SetCellValue("delete" + i);
            }
            using (FileStream fs = File.OpenWrite("1213.xlsx")) { //
                wk.Write(fs); 
            }
            MessageBox.Show("ok");
收获园豆:4
秋壶冰月 | 园豆:5903 (大侠五级) | 2013-11-05 19:11
0

谢谢大家,问题我已经解决了,我之前是Sheet.Celss[top,row]=string;这样来写数据的,因为方便做这边比较纠结的逻辑运算.

之后我将逻辑和写入分离了,还是发现很慢,然后去查,说是用Sheet.Celss[top,row]这种方法每次都要请求一次链接,然后才能写入数据

所以我修改成先得到要写入的DataTable,然后转换成string[,]数组.

再得到Excel.Range.get_Range("A2",missing.value),(这里A2的意思是从A列的第2行起的Range对象)

通过设置Range.get_Resize(RowsSize,ColumnSize)(就是你DataTable数据有多少行和多少列,在Excel.Range对象中得到从A2开始的,这么大的区域.)

最后Excel.Range.Value=objDate;(将你DataTable转换出来的数组,直接一次写入你之前得到的Range区域里里面)

速度灰一样的快.大家可以试试.

新手猿 | 园豆:99 (初学一级) | 2013-11-08 10:04
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册