大数据量,在线生成excel的解决方案 不管是从用户体验还是从技术方案上,都应该避免大数据放到excel里,用户看不过来,没有存在的意义 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 但用户确实有这样的需求。那你就必须弄明白用户为什么会有这样的需求是否是因为你们数据库备份功能不完善,还是数据查询筛选功能不完善,还是图表功能不完善,总之就是你提供的系统里没有用户想要的功能,所以他们才想把那么多数据导出到excel里自己去玩 大数据填充excel慢,下载到客户机也慢用户除非是闲的蛋疼,否则不会弄10W+数据自己没事在那看的,看一天也看不完 因为需要一个存档留底的功能,尽管几乎不会有人用office打开去看,但针对该应用的需求,作为对历史业务的留底,是有必要的。退一步,要是以后出什么问题,客户有个原始数据留底,相当于备份。 因为需要一个存档留底的功能,尽管几乎不会有人用office打开去看,但针对该应用的需求,作为对历史业务的留底,是有必要的。退一步,要是以后出什么问题,客户有个原始数据留底,相当于备份。那你就做个服务程序,或者控制台程序,放服务器上,设置任务计划,定时每天执行一次,导出一个excel,然后定期copy走就好了不要等用户访问你网站的时候才去导出 反正逐行写入是最慢的一种,其他需要你自己尝试,比如数据流写入,OLEDB写入,RANGE写入,剪切板copy,其中剪切板方式速度很快,但不一定满足格式要求,总之快慢不是凭空想,你得做出来实际测试才知道 试试这个第三方组件,直接对文件进行操作,比调用office进程是快多了而且服务器上也不需要安装office组件,兼容32位和64位,支持webform和winform 对Excel的导出, 稍有研究。 如果数量不大(一万条以下), 随便怎么样都可以。象你这样在十万条以上左右, 如果还要并发, 服务器绝对死掉 —— 一个用户导出就可能就占几个G的内存。 NPOI和CloseXML导出都很占内存的。如果数据并不复杂, 你可以试着导出 .CSV 文件。 这样导出的文件并不大, 而且速度非常快, 下载时用户体验也很好。 数据量太大了,excel一个表才65536行,超过64M就打不开了,还是说服客户换成access,导出还快些,开销也小 excel单个工作表早就可以放160多万行了。而且一个工作簿可以放多个工作表。 笨啊,人家说什么就什么啊,就为了备份数据,至于导出excel吗?这种低性能,弱类型,还得小心被篡改数据类型。合适用来备份数据吗? 用自动递增变化的数据填充Excelprivate void tsbtn_Query_Click(object sender, EventArgs e) { CloseProcess("EXCEL");//关闭所有Excel进程 string P_str_Excel = tstxt_Excel.Text;//记录Excel文件路径 string P_str_SheetName = tscbox_Sheet.Text;//记录选择的工作表名称 object P_obj_Start = tstxt_Start.Text;//记录开始单元格 object P_obj_End = tstxt_End.Text;//记录结束单元格 object missing = System.Reflection.Missing.Value;//定义object缺省值 Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();//实例化Excel对象 //打开Excel文件 Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Open(P_str_Excel, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing); Microsoft.Office.Interop.Excel.Worksheet worksheet;//声明工作表 worksheet = ((Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[P_str_SheetName]);//获取选择的工作表 Microsoft.Office.Interop.Excel.Range searchRange = worksheet.get_Range(P_obj_Start, missing);//定义查找范围 switch (tscbox_Type.Text)//按照下拉列表中的文本进行条件判断 { case "数字"://以数字序列填充 searchRange.AutoFill(worksheet.get_Range(P_obj_Start, P_obj_End), Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillSeries); break; case "工作日"://以工作日填充 searchRange.AutoFill(worksheet.get_Range(P_obj_Start, P_obj_End), Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillWeekdays); break; case "月份"://以月份填充 searchRange.AutoFill(worksheet.get_Range(P_obj_Start, P_obj_End), Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillMonths); break; case "年份"://以年份填充 searchRange.AutoFill(worksheet.get_Range(P_obj_Start, P_obj_End), Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillYears); break; default://以默认方式填充 searchRange.AutoFill(worksheet.get_Range(P_obj_Start, P_obj_End), Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillDefault); break; } excel.DisplayAlerts = false;//设置保存Excel时不显示对话框 workbook.Save();//保存工作簿 workbook.Close(false, missing, missing);//关闭工作簿 CloseProcess("EXCEL");//关闭所有Excel进程 WBrowser_Excel.Navigate(P_str_Excel);//在窗体中重新显示Excel文件内容 } 多谢帮我更新知识点,我还停留在excel2003,嘿嘿客户提这种要求其实是为了留个凭据(如果只是备份,我想客户不会关心你用什么方式的),万一数据库里的数据出现问题,用这个凭据去对照,如果是单表容量能达到160多万,那导出是没什么问题,不过接下来的问题是,用户可能会跟你提要求,要在excel里查找数据,对应上了,可能还要更新回数据库,这个情况我以前是碰到过,挺麻烦的 web主要是给互联网“冲浪”用户看的网页。如果给熟练的统计人员,你应该提供一个高性能的c/s程序。 如果你说你只是做网页 OA 的,不擅长开发企业 c/s 软件,那么我建议你就把这个功能“收费”,然后找人设计一个 c/s 版的客户端软件。这样,你们公司还多一项产品呢,可以推广给几千个、上万企业使用。不要在网页上净搞一些高大上的项目。 如上面所言,就是把10w级的数据导出到Excel文件(当然是.xlsx)而已。因为web网页是对于所有公众开放的,随意访问的,那实时生成Excel就不是好办法了,每次访问页面都执行一次导出,这是严重的设计错误啊,除非附加了动态的筛选条件的,否则都应该后台导出,然后提供URL下载。我只坐过剪切板copy方式导出Excel,是COM组件实现的。Oracle+winform。查询数据-创建COM示例-创建工作表-打开sheet-复制粘贴数据-保存xlsx-释放COM资源-返回。12个字段,6w行,20秒左右。xlsx文件大小约5MB /// <summary> /// 使用粘贴板进行写入 /// 此函数需要依赖office实例,运行的OS要安装office /// </summary> /// <param name="data"></param> /// <param name="filename"></param> /// <param name="exportHeader"></param> public void Export2Xls(DataTable data, string filename, bool exportHeader = true) { if (System.IO.File.Exists(filename)) System.IO.File.Delete(filename); Excel14._Application xlsApp = null; Excel14._Workbook xlsBook = null; Excel14._Worksheet xstSheet = null; try { //xlsApp = new Excel14.ApplicationClass(); //xlsApp = new Excel14.Application(); xlsApp = new Excel14.Application(); xlsBook = xlsApp.Workbooks.Add(); xstSheet = (Excel14._Worksheet)xlsBook.Worksheets[1]; var buffer = new StringBuilder(); if (exportHeader) { // Excel中列与列之间按照Tab隔开 foreach (DataColumn col in data.Columns) buffer.Append(col.ColumnName + "\t"); buffer.AppendLine(); } foreach (DataRow row in data.Rows) { foreach (DataColumn col in data.Columns) buffer.Append(row[col].ToString() + "\t"); buffer.AppendLine(); } System.Windows.Forms.Clipboard.SetDataObject(""); // 放入剪切板 System.Windows.Forms.Clipboard.SetDataObject(buffer.ToString()); var range = (Excel14.Range)xstSheet.Cells[1, 1]; range.Select(); xstSheet.Paste(); // 清空剪切板 System.Windows.Forms.Clipboard.SetDataObject(""); xlsBook.SaveAs(filename); } catch (Exception e) { throw e; } finally { try { if (xlsBook != null) xlsBook.Close(); if (xlsApp != null) xlsApp.Quit(); // finally里清空Com对象 lock(this) { System.Runtime.InteropServices.Marshal.ReleaseComObject(xstSheet); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsBook); System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsApp); xstSheet = null; xlsBook = null; xlsApp = null; GC.Collect(); } } catch (System.Exception ex) { throw ex; } } } Aspose,epplus,openxml,npoi,spire.xls几个三方都测测看哪个速度快点用哪个 对,大数据量操作excel不太可以去,需要查看,你让他在线查看不就得了,按时间段查询,按时间段导出用NPOI操作,服务器不用安装office 十万级别的excel用POI轻松搞定的。很多时候,不是程序员说什么就什么的,客户有很多愚蠢的要求,你没办法的.................. 在iis服务器上如何配置“暂无图片” 怎样获取dropdownlist里的值? SqlServer 索引 提交时自动复制的剖问题 iis是 什么 异步提交不能用COOKIE吗 PagedDataSource 分页类如何实现带 查询呢?? APS.NET写好的项目怎么删除? 用DreamweaverMX写的.aspx界面在VS.net里为什么显示不相符??? asp.net 树形列表 使用.NET的MVC框架,配合EF使用时,将业务封装在Service层时如何解决“按需查询”问题 【asp.net】 XML读取问题
但用户确实有这样的需求。
那你就必须弄明白用户为什么会有这样的需求
是否是因为你们数据库备份功能不完善,还是数据查询筛选功能不完善,还是图表功能不完善,总之就是你提供的系统里没有用户想要的功能,所以他们才想把那么多数据导出到excel里自己去玩
用户除非是闲的蛋疼,否则不会弄10W+数据自己没事在那看的,看一天也看不完
退一步,要是以后出什么问题,客户有个原始数据留底,相当于备份。
退一步,要是以后出什么问题,客户有个原始数据留底,相当于备份。
那你就做个服务程序,或者控制台程序,放服务器上,设置任务计划,定时每天执行一次,导出一个excel,然后定期copy走就好了
不要等用户访问你网站的时候才去导出
第三方组件,直接对文件进行操作,比调用office进程是快多了
而且服务器上也不需要安装office组件,兼容32位和64位,支持webform和winform
如果数量不大(一万条以下), 随便怎么样都可以。象你这样在十万条以上左右, 如果还要并发, 服务器绝对死掉 —— 一个用户导出就可能就占几个G的内存。
NPOI和CloseXML导出都很占内存的。如果数据并不复杂, 你可以试着导出 .CSV 文件。
这样导出的文件并不大, 而且速度非常快, 下载时用户体验也很好。
private void tsbtn_Query_Click(object sender, EventArgs e)
{
CloseProcess("EXCEL");//关闭所有Excel进程
string P_str_Excel = tstxt_Excel.Text;//记录Excel文件路径
string P_str_SheetName = tscbox_Sheet.Text;//记录选择的工作表名称
object P_obj_Start = tstxt_Start.Text;//记录开始单元格
object P_obj_End = tstxt_End.Text;//记录结束单元格
object missing = System.Reflection.Missing.Value;//定义object缺省值
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();//实例化Excel对象
//打开Excel文件
Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Open(P_str_Excel, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
Microsoft.Office.Interop.Excel.Worksheet worksheet;//声明工作表
worksheet = ((Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[P_str_SheetName]);//获取选择的工作表
Microsoft.Office.Interop.Excel.Range searchRange = worksheet.get_Range(P_obj_Start, missing);//定义查找范围
switch (tscbox_Type.Text)//按照下拉列表中的文本进行条件判断
{
case "数字"://以数字序列填充
searchRange.AutoFill(worksheet.get_Range(P_obj_Start, P_obj_End), Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillSeries);
break;
case "工作日"://以工作日填充
searchRange.AutoFill(worksheet.get_Range(P_obj_Start, P_obj_End), Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillWeekdays);
break;
case "月份"://以月份填充
searchRange.AutoFill(worksheet.get_Range(P_obj_Start, P_obj_End), Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillMonths);
break;
case "年份"://以年份填充
searchRange.AutoFill(worksheet.get_Range(P_obj_Start, P_obj_End), Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillYears);
break;
default://以默认方式填充
searchRange.AutoFill(worksheet.get_Range(P_obj_Start, P_obj_End), Microsoft.Office.Interop.Excel.XlAutoFillType.xlFillDefault);
break;
}
excel.DisplayAlerts = false;//设置保存Excel时不显示对话框
workbook.Save();//保存工作簿
workbook.Close(false, missing, missing);//关闭工作簿
CloseProcess("EXCEL");//关闭所有Excel进程
WBrowser_Excel.Navigate(P_str_Excel);//在窗体中重新显示Excel文件内容
}
客户提这种要求其实是为了留个凭据(如果只是备份,我想客户不会关心你用什么方式的),万一数据库里的数据出现问题,用这个凭据去对照,如果是单表容量能达到160多万,那导出是没什么问题,不过接下来的问题是,用户可能会跟你提要求,要在excel里查找数据,对应上了,可能还要更新回数据库,这个情况我以前是碰到过,挺麻烦的
web主要是给互联网“冲浪”用户看的网页。如果给熟练的统计人员,你应该提供一个高性能的c/s程序。
因为web网页是对于所有公众开放的,随意访问的,那实时生成Excel就不是好办法了,每次访问页面都执行一次导出,这是严重的设计错误啊,除非附加了动态的筛选条件的,否则都应该后台导出,然后提供URL下载。我只坐过剪切板copy方式导出Excel,是COM组件实现的。
Oracle+winform。查询数据-创建COM示例-创建工作表-打开sheet-复制粘贴数据-保存xlsx-释放COM资源-返回。
12个字段,6w行,20秒左右。xlsx文件大小约5MB /// <summary>
/// 使用粘贴板进行写入
/// 此函数需要依赖office实例,运行的OS要安装office
/// </summary>
/// <param name="data"></param>
/// <param name="filename"></param>
/// <param name="exportHeader"></param>
public void Export2Xls(DataTable data, string filename, bool exportHeader = true)
{
if (System.IO.File.Exists(filename))
System.IO.File.Delete(filename); Excel14._Application xlsApp = null;
Excel14._Workbook xlsBook = null;
Excel14._Worksheet xstSheet = null;
try
{
//xlsApp = new Excel14.ApplicationClass();
//xlsApp = new Excel14.Application(); xlsApp = new Excel14.Application(); xlsBook = xlsApp.Workbooks.Add();
xstSheet = (Excel14._Worksheet)xlsBook.Worksheets[1]; var buffer = new StringBuilder();
if (exportHeader)
{
// Excel中列与列之间按照Tab隔开
foreach (DataColumn col in data.Columns)
buffer.Append(col.ColumnName + "\t"); buffer.AppendLine();
}
foreach (DataRow row in data.Rows)
{
foreach (DataColumn col in data.Columns)
buffer.Append(row[col].ToString() + "\t"); buffer.AppendLine();
}
System.Windows.Forms.Clipboard.SetDataObject("");
// 放入剪切板
System.Windows.Forms.Clipboard.SetDataObject(buffer.ToString());
var range = (Excel14.Range)xstSheet.Cells[1, 1];
range.Select();
xstSheet.Paste();
// 清空剪切板
System.Windows.Forms.Clipboard.SetDataObject(""); xlsBook.SaveAs(filename);
}
catch (Exception e)
{
throw e;
}
finally
{
try
{
if (xlsBook != null)
xlsBook.Close(); if (xlsApp != null)
xlsApp.Quit(); // finally里清空Com对象
lock(this)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(xstSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsApp); xstSheet = null;
xlsBook = null;
xlsApp = null; GC.Collect();
} }
catch (System.Exception ex)
{
throw ex;
} }
}
用NPOI操作,服务器不用安装office