大家好,又见面了,我是你们的朋友全栈君。
【工具】Excel利器—NPOI VS EPPLUS
由于最近客户端不停抱怨,查询会宕机。
其实,这算是老问题了,主要原因是:Query性能不佳
由于该查询会使用到的Table事务量很大,容易会有Wait的现象到最后就TimeOut了。
查询数据量太大,目前是放到DataSet之后直接用GridView绑定。
其实,以上种种造成因素太多了。
再加上,查询出来的结果使用端整批下载或是自订下载成Excel。
最一开始的版本的使用Office原生的套件写到Excel,在网页TimeOut前的极限大约是6000~9000笔。
而,我接手以后我把它改成直接用Html Render出来,在网页TimeOut前的极限大约是10000~14000笔。
但是,这样还是有不少问题。
最后,最近开会主管提出一种方案,让使用者需要大量数据时,用离线的方式制作。
这样的好处有:SQL Command TimeOut 可以拉长。
不用再受限网页TimeOut的问题点。
可以避开高峰时间,让这些又臭又长的Query在深夜里享受性能。
好啦….既然决定要做总要改变用更好的工具吧!!
NPOI应该已经有很多人听闻过了,主管在前几天也刚好提到有一套第三方原件EPPlus。
网络上其实已经有人写过类似评测:皮尼网前走
上面那篇文章,看起来主要是网页版的时间比较,看起来EPPlus根本就是让NPOI看不到车尾灯。
但是,我要的是Console版的比较,就自己来学啦!!
我对NPOI和EPPlus其实都不熟,靠着范例&部分教学拼凑出来了以下结论。
NPOI
我是使用官方最新版本1.2.4,NPOI只能存取Office 2003的版本,我的目的是有一个Templete,我们只把数据塞到各列中。
步骤一:将下载的DLL,加入至参考(此部分不另说明)。
步骤二:using NPOI.HSSF.UserModel;
using NPOI.HPSF;
using NPOI.POIFS.FileSystem;
using NPOI.SS.UserModel;
步骤三://将WorkBook指到我们原本设计好的Templete Book1.xls
using (IWorkbook wb = new HSSFWorkbook(new FileStream(“D:/Book1.xls”, FileMode.Open)))
{
try
{
//设定要使用的Sheet为第0个Sheet
ISheet TempSheet = wb.GetSheetAt(0);
int StartRow = 4;
//tDS为Query带回来的数据
for (int i = 0; i < tDS.Tables[0].Rows.Count; i++)
{
//第一个Row要用Create的
TempSheet.CreateRow(StartRow + i).CreateCell(0).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][0]));
//第二个Row之后直接用Get的
TempSheet.GetRow(StartRow + i).CreateCell(1).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][1]));
TempSheet.GetRow(StartRow + i).CreateCell(2).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][2]));
TempSheet.GetRow(StartRow + i).CreateCell(3).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][3]));
TempSheet.GetRow(StartRow + i).CreateCell(4).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][4]));
TempSheet.GetRow(StartRow + i).CreateCell(5).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][5]));
TempSheet.GetRow(StartRow + i).CreateCell(6).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][6]));
TempSheet.GetRow(StartRow + i).CreateCell(7).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][7]));
TempSheet.GetRow(StartRow + i).CreateCell(8).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][8]));
TempSheet.GetRow(StartRow + i).CreateCell(9).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][9]));
TempSheet.GetRow(StartRow + i).CreateCell(10).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][10]));
TempSheet.GetRow(StartRow + i).CreateCell(11).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][11]));
TempSheet.GetRow(StartRow + i).CreateCell(12).SetCellValue(Convert.ToString(tDS.Tables[0].Rows[i][12]));
}
//将文件写到指定位置
using (FileStream file = new FileStream(“H:/Test_NPOI4.xls”, FileMode.Create))
{
wb.Write(file);
file.Close();
file.Dispose();
}
}
catch (Exception e)
{
string a = e.ToString();
}
}
NPOI的程序撰写部分大概就是上方的方式。
EPPLUS
EPPlus我也是用官方最新版本2.6.0.1,EPPluse适用Office 2007&2010,但要注意,只支持.net 3.5以上,至于程序目的跟NPOI是一样的。
步骤一:也是把下载的DLL加入到参考。
步骤二:FileInfo newFile = new FileInfo(“D:” + @”Test.xlsx”);
//开启
using (ExcelPackage pck = new ExcelPackage(newFile))
{
try
{
//设定ExcelWorkBook
ExcelWorkbook workBook = pck.Workbook;
if (workBook != null)
{
if (workBook.Worksheets.Count > 0)
{
//复制Temp这个Sheet同时命名为《清单》
ExcelWorksheet currentWorksheet = workBook.Worksheets.Copy(“Temp”, “清单”);
//可以设定保护Sheet的密码
//currentWorksheet.Protection.SetPassword(“1234”);
int StartRow = 4;
for (int i = 0; i < tDS.Tables[0].Rows.Count; i++)
{
//Cells[RowIndex,CellIndex]
currentWorksheet.Cells[StartRow + i, 1].Value = Convert.ToString(tDS.Tables[0].Rows[i][0]);
currentWorksheet.Cells[StartRow + i, 2].Value = Convert.ToString(tDS.Tables[0].Rows[i][1]);
currentWorksheet.Cells[StartRow + i, 3].Value = Convert.ToString(tDS.Tables[0].Rows[i][2]);
currentWorksheet.Cells[StartRow + i, 4].Value = Convert.ToString(tDS.Tables[0].Rows[i][3]);
currentWorksheet.Cells[StartRow + i, 5].Value = Convert.ToString(tDS.Tables[0].Rows[i][4]);
currentWorksheet.Cells[StartRow + i, 6].Value = Convert.ToString(tDS.Tables[0].Rows[i][5]);
currentWorksheet.Cells[StartRow + i, 7].Value = Convert.ToString(tDS.Tables[0].Rows[i][6]);
currentWorksheet.Cells[StartRow + i, 8].Value = Convert.ToString(tDS.Tables[0].Rows[i][7]);
currentWorksheet.Cells[StartRow + i, 9].Value = Convert.ToString(tDS.Tables[0].Rows[i][8]);
currentWorksheet.Cells[StartRow + i, 10].Value = Convert.ToString(tDS.Tables[0].Rows[i][9]);
currentWorksheet.Cells[StartRow + i, 11].Value = Convert.ToString(tDS.Tables[0].Rows[i][10]);
currentWorksheet.Cells[StartRow + i, 12].Value = Convert.ToString(tDS.Tables[0].Rows[i][11]);
currentWorksheet.Cells[StartRow + i, 13].Value = Convert.ToString(tDS.Tables[0].Rows[i][12]);
}
//将Temp 这个Sheet删除
workBook.Worksheets.Delete(“Temp”);
}
}
//存档至Text4.xlsx
pck.SaveAs(new FileInfo(“H:” + @”Test4.xlsx”));
}
catch (Exception e)
{
oLogger.Fatal(e.ToString());
}
}
EPPlus程序撰写方是大概就如上方。
目前不确定我两种组件的写法,有没有可能会造成资源被Lock住,或著是没有释放掉,
这部分如果有高人愿意指教非常之欢迎喔!!
写法说明完,要开始评测啦!
首先我们先来看执行速度,两种组件我都分别跑了10000~40000左右的笔数。
以下是我整理的列表,开始到结束时间是从算出数据笔数后开始计算,因为这次的目的是写文件的速度,要扣除掉Query执行时间。
NOPI
开始到结束:3秒,文件大小:7.25MB
2012-04-21 00:23:07.6900 BathExcel.Program INFO 开始
2012-04-21 00:23:12.2333 BathExcel.Program INFO 数据笔数 9849
2012-04-21 00:23:15.4474 BathExcel.Program INFO 结束
开始到结束:2秒,文件大小:12.8MB
2012-04-21 00:24:12.9077 BathExcel.Program INFO 开始
2012-04-21 00:24:22.5753 BathExcel.Program INFO 数据笔数 17681
2012-04-21 00:24:24.3514 BathExcel.Program INFO 结束
开始到结束:3秒,文件大小:21.4MB
2012-04-21 00:24:41.5194 BathExcel.Program INFO 开始
2012-04-21 00:24:56.1772 BathExcel.Program INFO 数据笔数 29368
2012-04-21 00:24:59.4544 BathExcel.Program INFO 结束
开始到结束:8秒,文件大小:31.6MB
2012-04-21 00:25:17.5354 BathExcel.Program INFO 开始
2012-04-21 00:25:38.9126 BathExcel.Program INFO 数据笔数 43178
2012-04-21 00:25:44.1159 BathExcel.Program INFO 结束
EEPLUS
开始到结束:2秒,文件大小:2.88MB
2012-04-21 00:26:51.8548 BathExcel.Program INFO 开始
2012-04-21 00:26:56.2361 BathExcel.Program INFO 数据笔数 9849
2012-04-21 00:26:58.7312 BathExcel.Program INFO 结束
开始到结束:4秒,文件大小:5.12MB
2012-04-21 00:27:16.2712 BathExcel.Program INFO 开始
2012-04-21 00:27:24.2037 BathExcel.Program INFO 数据笔数 17681
2012-04-21 00:27:28.8359 BathExcel.Program INFO 结束
开始到结束:8秒,文件大小:8.6MB
2012-04-21 00:27:45.5839 BathExcel.Program INFO 开始
2012-04-21 00:27:57.7826 BathExcel.Program INFO 数据笔数 29368
2012-04-21 00:28:05.7360 BathExcel.Program INFO 结束
开始到结束:13秒,文件大小:12.6MB
2012-04-21 00:28:23.6411 BathExcel.Program INFO 开始
2012-04-21 00:28:41.8771 BathExcel.Program INFO 数据笔数 43178
2012-04-21 00:28:54.2988 BathExcel.Program INFO 结束
看完这数据,我发现这跟网页上那篇评论有很大的落差,不知道是哪里造成就是,但是这个数据符合我的实际情况。
总结:在执行速度方面:NPOI小赢一点。
在文件大小方面:EEPLus大胜。
在撰写感受方面:可能都是刚接触不熟,但现阶段我个人认为EEPlus小胜一筹。
在资源支持方面:NPOI胜,因EEPlus目前大多还是英文较多,但NPOI已有中文的完整文档。
最后,你问我我会选择哪一套,答案是,我会选择EEPlus,因为我喜欢他的写作方式。
希望各位看完以后,有什么问题或可以指教我的地方尽量提出来,谢谢!
NPOI参考数据:NOPI官网范例
Tony Qu撰写的中文文章(1.2.2版)
Tony Qu撰写的中文文章(1.2.4版)
EPPlus参考数据:官网范例
官网Web范例
FryHard 外国人写的文章,不错还有提供范例
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/148795.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...