100万行数据导出到Excel的优化方案

1》场景

  项目中需要从数据库中导出100万行数据,以excel形式下载并且只要一张sheet(打开这么大文件有多慢另说,呵呵)。

  ps:xlsx最大容纳1048576行 ,csv最大容纳1048576行,xls最大容纳65536行,但是存放相同的数据量 文件大小排序:xls>csv>xlsx ;xls是biff8的二进制文件,就是个B+树而xlsx是 xml的zip压缩文件。

2》常规做法

  按照平常的做法,先到数据库中取数然后循环组装成一个list,然后用excel工具(我用的是POI)生成excel。

3》遇到的问题

  1' 内存经常溢出。

  2' 组装list,生成excel慢,50万的数据花了一个小时都没见完成。

4》解决方法

  1' POI 改用 SXSSFWorkbook 参看 比如SXSSFWorkbook wb = new SXSSFWorkbook(100);在内存中只保留100行记录,超过100就将之前的存储到磁盘里,

      2' 调整JVM 相关的参数 -Xmx....

    3' 循环中减少使用new,尽量复用;String改为StringBuffer就不说了,重点是在组装一行数据时,一直比较喜欢用map来拼装,但是在我功能上发现还是耗内存的,后来的GC时间太长,造成严重拖累组装数据的效率,后来发现由HashMap改为用StringBuffer拼接行数据效率直接就上去了,当然指定合理的StringBuffer的起始容量效率就更好了。

  ps:StringBuffer 的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建 StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。

      4' 下载任务由同步改为异步,用户提交了后只要等待邮件通知即可,我用了quartz。

5》效果

    100万数据组装以及生成excel大概要10分钟,平均下来1分钟10万条,我的小黑腰不酸腿不疼了。

好了就这些,我也看了,网上导出很多是分批导出或者用csv的解决的,但是我就这样的需求,人家任性没办法,我的方法还有待完善的地方,欢迎交流。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在将100万条数据导出Excel文件时,最好采用分批次写入的方式,以避免内存溢出或性能问题。下面是一个示例代码,可以将数据分为多批次写入Excel文件: ```csharp using Excel = Microsoft.Office.Interop.Excel; // 每批次写入的数据量 int batchSize = 100000; // 创建Excel对象 Excel.Application excel = new Excel.Application(); excel.Visible = false; Excel.Workbook workbook = excel.Workbooks.Add(System.Reflection.Missing.Value); Excel.Worksheet sheet = (Excel.Worksheet)workbook.ActiveSheet; // 写入表头 for (int col = 1; col <= data.Columns.Count; col++) { sheet.Cells[1, col] = data.Columns[col - 1].ColumnName; } // 分批次写入数据 int rowCount = 1; for (int batch = 0; batch < Math.Ceiling((double)data.Rows.Count / batchSize); batch++) { int startRow = batch * batchSize + 1; int endRow = Math.Min(startRow + batchSize - 1, data.Rows.Count); for (int row = startRow; row <= endRow; row++) { rowCount++; for (int col = 1; col <= data.Columns.Count; col++) { sheet.Cells[rowCount, col] = data.Rows[row - 1][col - 1].ToString(); } } } // 自适应列宽 sheet.Columns.AutoFit(); // 保存Excel文件 workbook.SaveAs("data.xlsx", Excel.XlFileFormat.xlOpenXMLWorkbook, System.Reflection.Missing.Value, System.Reflection.Missing.Value, false, false, Excel.XlSaveAsAccessMode.xlNoChange, Excel.XlSaveConflictResolution.xlUserResolution, true, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value); workbook.Close(); excel.Quit(); ``` 在上述代码中,我们将数据分为多批次,每批次写入`batchSize`条数据,然后保存Excel文件。同时,我们也自适应了Excel文件中的列宽,以便更好地呈现数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

油炸小波

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值