解决java poi海量数据导出内存溢出问题
找了很多天的解决方法,一直被分页查询绕进去了,其实数据都能查出来的,真正卡的地方是ExcelExportUtil类下调错了方法。
最开始调用的方法是(标记的地方): workbook = new HSSFWorkbook();和 workbook = new XSSFWorkbook();
这两个方法就是导出Excel的最关键的方法,接下来我来说说这两个方法作用:
1.HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls;
2.XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx;
对于不同版本的EXCEL文档要使用不同的工具类,如果使用错了,会提示如下错误信息。
org.apache.poi.openxml4j.exceptions.InvalidOperationException
org.apache.poi.poifs.filesystem.OfficeXmlFileException
当数据量超出65536条后,在使用HSSFWorkbook或XSSFWorkbook,程序会报OutOfMemoryError:Javaheap space;内存溢出错误。
而我们的数据量达到了9W条数据,用这两个方法肯定是报内存溢出的错误的。
最终我找到的解决方法是:从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的API----SXSSFWorkbook。
3.SXSSFWorkbook-来至官方的解释:实现“BigGridDemo”策略的流式XSSFWorkbook版本。这允许写入非常大的文件而不会耗尽内存,因为任何时候只有可配置的行部分被保存在内存中。您可以提供用作书面数据基础的模板工作簿。有关详细信息,请参见https://poi.apache.org/spreadsheet/how-to.html#sxssf。请注意,仍然可能会消耗大量内存,这些内存基于您正在使用的功能,例如合并区域,注释......仍然只存储在内存中,因此如果广泛使用,可能需要大量内存。SXSSFWorkbook默认使用内联字符串而不是共享字符串表。这非常有效,因为没有文档内容需要保存在内存中,但也被称为制作与某些客户不兼容的文档。在启用共享字符串的情况下,文档中的所有唯一字符串必须保存在内存中。根据您的文档内容,这可能比共享字符串被禁用时使用更多的资源。在决定是否启用共享字符串之前,请仔细检查您的内存预算和兼容性需求。
而在poi架包中提供的方法用的是:
当数据量超过1000条时就会调用SXSSFWorkbook方法,从而解决了海量的数据导出会发生内存溢出的问题。
public void exportContacts(final PortalUserPage page, final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
final String name = "通讯录列表";
// 去掉分页
page.setPage(1);
page.setRows(Integer.MAX_VALUE);
final List<CmssPortalUser> dataList = (List<CmssPortalUser>) this.queryPortalUserListWithGroup(page);
final List<PortalUserExcelDto> userList = new ArrayList<>();
for (final CmssPortalUser user : dataList) {
final PortalUserExcelDto userDto = new PortalUserExcelDto();
userDto.setIndex(user.getIndex() != null ? user.getIndex().toString() : "0");
userDto.setRealName(user.getRealName());
userDto.setCompany(user.getCompany());
userDto.setCompanyBranch(user.getCompanyBranch());
userDto.setDepartment(user.getDepartment());
userDto.setTitle(user.getTitle());
userDto.setPhone(user.getPhone());
userDto.setLoginName(user.getLoginName());
userDto.setProducts(user.getProducts());
userDto.setEmail(user.getEmail());
userDto.setGroup(user.getGroup());
if (user.getOpenTime() != null) {
// 开通时间日期格式化
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
userDto.setOpenTime(format.format(user.getOpenTime()));
}
// 判断全局预览
// 根据创建者ID查询该用户是否可以浏览全局
user.setIfGlobelView(shareJedis.ifGlobelView(user.getId().longValue()) ? 1 : 0);
if (user.getIfGlobelView() != null) {
if (user.getIfGlobelView() == Constants.CURRENCY.ZERO) {
userDto.setIfGlobelView("否");
}
if (user.getIfGlobelView() == Constants.CURRENCY.ONE) {
userDto.setIfGlobelView("是");
}
}
// 判断状态
if (StringUtils.isNotBlank(user.getStatus())) {
if (Constants.CONTACTS_STATUS.UNAVAILABILITY.equals(user.getStatus())) {
userDto.setStatus("停用");
}
if (Constants.CONTACTS_STATUS.AVAILABILITY.equals(user.getStatus())) {
userDto.setStatus("启用");
}
}
// VIP类别
userDto.setVipCategory(user.getVipCategoryName() != null ? user.getVipCategoryName() : null);
// Vip级别
userDto.setVipLevel(user.getVipLevelName() != null ? user.getVipLevelName() : null);
// 判断短信通知
if (user.getIsSendSms() != null) {
if (Constants.UNIVERSAL_CONSTANT.ZERO.equals(user.getIsSendSms())) {
userDto.setIsSendSms("否");
}
if (Constants.UNIVERSAL_CONSTANT.ONE.equals(user.getIsSendSms())) {
userDto.setIsSendSms("是");
}
}
userList.add(userDto);
}
final ExportParams params = new ExportParams(name, name, ExcelType.XSSF);
final Workbook workbook = ExcelExportUtil.exportExcel(params, PortalUserExcelDto.class, userList);
try {
final String agent = request.getHeader("User-Agent").toLowerCase();
// 开始下载文件
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String filename = format.format(new Date().getTime()) + "-" + name + ".xlsx";
if (!StringUtils.isEmpty(agent) && agent.contains("msie") || agent.contains("like gecko")
|| (agent.indexOf("rv") > 0 && agent.indexOf("firefox") == -1)) {
filename = URLEncoder.encode(filename, "UTF-8");
} else {
filename = new String(filename.getBytes("UTF-8"), "ISO8859-1");
}
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=".concat(filename));
final OutputStream out = response.getOutputStream();
workbook.write(out);
out.flush();
out.close();
} catch (final Exception e) {
e.printStackTrace();
log.error(e.getMessage());
}
}
这部分代码是我所写的批量导出海量数据的部分代码,希望可以帮助和我遇到一样错误的人。
————————————————
版权声明:本文为CSDN博主「小姚同學」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/YiWangJiuShiXingFu/article/details/80258148
解决java poi海量数据导出内存溢出问题相关推荐
- java poi 图片 内存溢出_解决java poi海量数据导出内存溢出问题
找了很多天的解决方法,一直被分页查询绕进去了,其实数据都能查出来的,真正卡的地方是ExcelExportUtil类下调错了方法. 最开始调用的方法是(标记的地方): workbook = new H ...
- 超大数据量的xlsx格式的excel文件的读取和解析,解决了POI方式的内存溢出和性能问题
在之前的博文< POI读取并解析xlsx格式的excel文件>中,在小数据量的情况下是可以轻松愉快的处理的,但是当excel文件的数据量达到百万级的时候, InputStream is = ...
- 解决java poi导出excel2003不能超过65536行的问题
java poi在导出数据到excel2003工作表中时一个工作表只能存储65536行数据,如果超过这个数据就会失败,excel2007并没有这个问题,但是为了兼容性我们通常都是导出到2003版本上的 ...
- java中三种常见内存溢出错误的处理方法
转载自http://blog.csdn.net/zmken497300/article/details/52496189 相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError ...
- java中三种常见内存溢出错误的处理方法(good)
相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError的问题,这个问题曾困扰了我很长时间,随着解决各类问题经验的积累以及对问题根源的探索,终于有了一个比较深入的认识. 在解决j ...
- 通过BitmapFactory.Options解决activity之间传递图片出现内存溢出(OOM)问题
通过BitmapFactory.Options解决activity之间传递图片出现内存溢出(OOM)问题 参考文章: (1)通过BitmapFactory.Options解决activity之间传递图 ...
- java poi pdf 导出
java poi pdf 导出 (java poi pdf导出 文字+图片两张放置一行) 思路:流传入图片 ,pdf没有行的概念,只有列即为一行,两张图片可以先建立一列在一列总再建立两列各放置一张图片 ...
- 解决Vue运行报js内存溢出问题
解决Vue运行报js内存溢出问题 下载内存控制插件 npm install increase-memory-limit 在package.json中添加脚本 "fix-memory-limi ...
- 解决 Java poi 3.8 等版本 操作 word 插入 图片 不成功的问题
解决 Java poi 3.8等版本操作word插入图片不成功的问题 问题: 最近有一个需求是将Excel中的数据转换到word中,其中包括了文字和图片, 在使用 poi 3.8 向word中写入图片 ...
最新文章
- keyshot分辨率多少合适_惠普打印机型号有哪些 惠普打印机多少钱【详解】
- 云服务器+开发板搭建直播系统,自建流媒体服务器开直播
- Py之tornado:tornado库的简介、安装、使用方法之详细攻略
- 台式计算机的速度,台式电脑运行速度慢怎么处理
- scrapy爬虫-setting.py
- 华为mate10pro测试软件,华为Mate10和华为Mate10Pro的区别在哪里?华为Mate10和华为Mate10Pro对比测评告诉你(附全文)...
- BZOJ3238:[AHOI2013]差异——题解
- 顺序结构程序设计总结
- 网易云计算机系统有限公司,网易云音乐
- 计算机应用基础教程在线阅读,【精品】计算机应用基础教程
- intellij idea 修改字体 修改主题
- 安卓dumpsys SurfaceFlinger输出示例
- 大觉寺到鹫峰线路_体验古香道---从大觉寺过鹫峰到妙峰山涧沟村
- matlab解决根据营养成分表搭配营养配方
- 期货平仓是先开先平吗(期货怎么先平新仓)
- 目前工资最高的几家外包公司汇总!(2023最新版)
- 串口通信实验——RS-232
- linux下运行htk,Linux下HTk工具箱的安装
- 创新与融合 智能门禁市场的未来可期
- 网络安全等级保护测评高风险判定-安全管理中心-5
热门文章
- 4安全框_压花玻璃与安全玻璃有哪些特点?玻璃隔断的介绍
- 问题 | kali系统隐藏sshd的banner信息
- 工作说明书(Statement of Work,简称SOW)
- uniapp中qrcode生成二维码后传的参数不见了_二维码扫描登录,你必须知道的 3 件事...
- 5次方用计算机,用科学计算器来求三的五次方的值,按键顺序是( )?
- 2叉树排序缺失元素查找
- 港铁将更换信号系统 或影响日间列车服务冀乘客谅解
- CodeForces 257B Playing Cubes :两人轮流向已有序列后面放红蓝木块,一人想使相邻颜色相同多一人想不想同颜色多,最后得分? :博弈+思维...
- 重装系统的悲剧。。。。。
- WF4.0实战系列索引