最近接手了一个需求,开启了一段苦逼的加班之路,也收获了不少,对于Excel导出的功能也更加熟悉了,接下来我就介绍一下我遇到的问题跟解决的方式。

问题一:

EasyExcel在Linux环境导出失败。

这是我在开发这个需求其中一个报表发现的问题——当我使用EasyExcel进行导出的时候本地导出没有问题,但是在测试环境与生产环境导出的时候就很不稳定,时常导出一个只有表头的空表,改了很多遍,想了很多种原因。

例如:

1.可能是实体类字段类型无法识别,尤其像LocalDateTime这种类型的字段

2.可能是pom依赖问题

3.可能是接口超时问题

4.可能是响应对象类型没有改成excel对应类型的问题

5.可能是数据量过大问题

如上类似问题全部都是有异常显示的,但是我的导出没有异常报错,这就令我的问题查找十分困难,并且我在另一个项目中完美导出,说明可能是服务器环境有一些配置导致EasyExcel导出出现了问题,公司的服务器确实不敢动呀,改起来也相对比较麻烦。

这时候我们就需要改变方式,使用另外一种方式导出,这种方式就是POI,虽然POI被诟病容易OOM内存溢出,但是确实是排除超大数据量导出之外的一种比较好的选择了(EasyExcel不好用且找不到问题的备用选择,毕竟工作没人会等你研究明白了再让你开发O(∩_∩)O),所以我找了几个POI灵活导出的例子,供大家选择,但是最好我推荐还是用EasyExcel,是又省事又好用。

正常使用POI导出,需要区分workbook对象。

  • HSSFWorkbook 用于Excel2003版及更早版本(扩展名为.xls)的导出。
  • XSSFWorkbook 用于Excel2007版(扩展名为.xlsx)的导出。
  • SXSSFWorkbook相对前面两种,会在导出数据达到万以上的数据,会报内存不足,导致失败的问题,所以用sxssf,简约sf来导出较大数据量

像上面这种区别的情况下,我们最好优先选择使用SXSSFWorkbook对象来进行Excel的导出,避免出现内存不足的情况。

首先我们还是要导入POI的依赖。

        <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>${poi.version}</version></dependency><dependency><artifactId>commons-compress</artifactId><groupId>org.apache.commons</groupId><version>1.19</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency>

默认导出方式:

    /*** list 入参查询条件* service 业务层对象**/@PostMapping("/poi/excel")public void getExcelByPoi(@RequestBody @ApiParam list inDto, HttpServletResponse response) {InputStream inputStream = null;try{List<Object> excelList = service.queryToExcel(inDto);// 判断返回集合内容不为空if (CollectionUtils.isEmpty(excelList)) {return;}String fileType = ".xlsx";String fileName = "fileName";// keep 100 rows in memory, exceeding rows will be flushed to disktry (SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(100);OutputStream os = response.getOutputStream();ByteArrayOutputStream byteStream = new ByteArrayOutputStream()) {//创建一个Sheet页SXSSFSheet sheet1 = sxssfWorkbook.createSheet("Sheet1");CellStyle cellStyle = service.headFont(sheet1.getWorkbook());//第一行是标题行Row titleRow = sheet1.createRow(0);// 写表头service.writerHeaderOne(titleRow);// 写表体for (int i = 1; i < excelList.size() + 1; i++) {SXSSFRow contentRow = sheet1.createRow(i);contentRow.createCell(0).setCellValue(i);service.writerContent(contentRow, excelList.get(i - 1));}response.setContentType("application/vnd.ms-excel"); // 设置下载类型response.setHeader("Content-Disposition", "attachment;filename=" + fileName + fileType); // 设置文件的名称sheet1.setForceFormulaRecalculation(true);//创建临时文件  文件输出流sxssfWorkbook.write(byteStream);byteStream.flush();sxssfWorkbook.dispose();// 释放workbook所占用的所有windows资源*/byte[] b = new byte[4096];// 必须在这里创建,否则获取不到行数inputStream = new ByteArrayInputStream(byteStream.toByteArray());int size = inputStream.read(b);while (size > 0) {os.write(b, 0, size);size = inputStream.read(b);}}} catch (Exception e) {e.printStackTrace();log.info("报表导出失败", e);}finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {log.error(e.getLocalizedMessage());}}}}

写表头方法

     /*** 写标题** @param titleRow 表头行对象*/public void writerHeaderOne(Row titleRow) {titleRow.createCell(0).setCellValue("id");titleRow.createCell(1).setCellValue("姓名");titleRow.createCell(2).setCellValue("年龄");}

写表体方法

    /*** 导出写入数据** @param contentRow 表体行* @param result 结果对象*/public void writerContent(SXSSFRow contentRow, Object result) {contentRow.createCell(0).setCellValue(result.getId());contentRow.createCell(1).setCellValue(result.getName());contentRow.createCell(2).setCellValue(result.getAge());}

这种方法确实可以导出,但是缺少了表头的样式,看起来很不舒服,但是SXSSFWorkbook对象的表头样式修改我简单尝试了一下没有实现,所以又出现了如下方式。

DIY特殊表头方式:

这种方式可以随心所欲的设置表头样式,关键是还很简单,我们只需要创建一个只有表头的Excel,设置好我们想要的样式。如下图:

创建好的Excel保存到项目中的resources ——> template 目录下

然后我们创建导出方法

    /*** service为业务类对象* @param inDto 导出查询条件* @param response*/@PostMapping("/excel")public void getExcelByPoi(@RequestBody @ApiParam list inDto, HttpServletResponse response) {try {List<Object> excelList = service.queryToExcel(inDto);// 判断返回列表不为空if (CollectionUtils.isEmpty(excelList)) {return;}//导出数据列表List<Map<String, Object>> dataList = new ArrayList<>();SXSSFWorkbook workbook = null;InputStream inputStream = null;XSSFWorkbook workbookBuff = null;//处理try {//获取流inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/Excel.xlsx");//读表格workbookBuff = new XSSFWorkbook(inputStream);workbook = new SXSSFWorkbook(workbookBuff, 100);//获取sheetSXSSFSheet sheet = workbook.getSheetAt(0);//sheet页,从第几行开始写数据,数据内容service.putData(sheet, 1, excelList);//设置格式response.setContentType("application/vnd.ms-excel");//编码response.setCharacterEncoding("utf-8");//设置文件格式response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + "Excel" + ExcelTypeEnum.XLSX.getValue());workbook.write(response.getOutputStream());} catch (Exception e) {e.printStackTrace();log.info("生产单报表查询失败", e);}finally {//判断if(workbook != null){try {//关闭workbook.close();}catch (Exception e){//异常e.printStackTrace();}}//判断if(inputStream != null){try {//关闭inputStream.close();}catch (Exception e){//异常e.printStackTrace();}}//判断if(response.getOutputStream() != null){try {//关闭response.getOutputStream().close();}catch (Exception e){//异常e.printStackTrace();}}}}catch (Exception e) {e.printStackTrace();log.error("导出查询失败 {}", e.getMessage());}}

写表体数据方法

    public void putData(SXSSFSheet sheet, int start, List<Object> dataList) {// 循环处理for (int i = 0; i < dataList.size(); i++) {// 获取当前数据Object obj = dataList.get(i);// 创建Row row = sheet.createRow(i + start);// 列坐标int col = 0;// idCell getIdCell = row.createCell(col++, CellType.STRING);// 数据getIdCell .setCellValue(obj.getId());// 名称Cell getNameCell = row.createCell(col++, CellType.STRING);// 数据getNameCell .setCellValue(obj.getName());// 年龄Cell getAgeCell = row.createCell(col++, CellType.STRING);// 数据getAgeCell.setCellValue(obj.getAge());}}

这样也可以导出。

下面给大家放上POI根据RGB来修改单元格颜色的代码:

        // 创建ExcelSXSSFWorkbook wb = new SXSSFWorkbook(100);// 创建Sheet页Sheet sheet = wb.createSheet();// 获取单元格的对象,去设置他的格式XSSFCellStyle groupFieldStyle =(XSSFCellStyle) wb.createCellStyle();groupFieldStyle.setBorderBottom(BorderStyle.THIN);//下边框样式groupFieldStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());//下边框颜色groupFieldStyle.setBorderLeft(BorderStyle.THIN);//左边框groupFieldStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());//左边框颜色groupFieldStyle.setBorderTop(BorderStyle.THIN);//上边框groupFieldStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());//上边框颜色groupFieldStyle.setBorderRight(BorderStyle.THIN);//右边框groupFieldStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());//右边框颜色groupFieldStyle.setAlignment(HorizontalAlignment.CENTER); // 设置单元格水平方向对其方式为居中groupFieldStyle.setVerticalAlignment(VerticalAlignment.CENTER);//设置单元格垂直方向对其方式为居中// 设置单元格RGB颜色groupFieldStyle.setFillForegroundColor(new XSSFColor(new java.awt.Color(248, 203, 173), new DefaultIndexedColorMap()));groupFieldStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 创建行,i表示第几行Row row = sheet.createRow(i);// 获取该行中的第几个单元格Cell cell = row.createCell(j);// 给单元格添加样式cell.setCellStyle(groupFieldStyle);

最后放上EasyExcel的文章连接,希望能够解决小伙伴们导出的问题。如果还有小伙伴们有问题 可以私信问我,日常在线哦

EasyExcel的导出与导入

JavaPOI导出Excel合集——Java导出全内容相关推荐

  1. Java POI 导出EXCEL经典实现 Java导出Excel

    转自http://blog.csdn.net/evangel_z/article/details/7332535 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者 ...

  2. Java POI 导出EXCEL经典实现 Java导出Excel弹出下载框

    原文转载:http://blog.csdn.net/evangel_z/article/details/7332535 目录(?)[+] 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数 ...

  3. java导出excel表头跨行,java导出Excel并对表头做定制

    1.核心代码 package cn.doofen.service.impl; import java.io.OutputStream; import java.text.DecimalFormat; ...

  4. java利用poi导出excel功能-附带图片导出

    java利用poi导出excel功能-附带图片导出 写在前面 最近刚离职,闲来无事,于是把上两家公司都有碰到过的需求但都没有去研究实现:即导出带图片的excel报表.于是就折腾了一下这个功能,研究出来 ...

  5. QQ空间将不再支持免费备份原图?附QQ空间相册导出工具合集

    感谢您抽出 .. 阅读本文 小伙伴们注意:公众号的推送机制不再按照时间前后推送了,微信公众号信息流乱序.君哥建议大家把科技毒瘤君公众号置顶(设为星标⭐),以便第一时间看到推送,非常感谢~,方法如下图: ...

  6. aspose使用合集java(Word、Excel、PPT转PDF)

    aspose使用合集java(Word.Excel.PPT转PDF) aspose使用合集java(Word.Excel.PPT转PDF 文档所需jar包 Word转为PDF 获取license 简单 ...

  7. html导出excel 内存不足,web导出excel那些坑

    背景介绍 昨天在一个前端的微信公众号看到一篇文章介绍导出cvs文件的,想想之前做导出excel的踩过的坑,心想记录一下,或许可以帮助别人吧! 需求很简单,在某个报表页面需要把table导出excel. ...

  8. asp.net中使用excel类导出Excel文件,并导出到web客户端中遇到的问题

    asp.net中使用excel类导出Excel文件,并导出到web客户端中遇到错误: 检索Com类工厂中CLSID为{000245-0000-0000-C000-000000000046}的组件失败, ...

  9. java 导出如何合并列_Java导出excel时合并同一列中相同内容的行思路详解

    一.有时候导出Excel时需要按类别导出,一大类下好几个小类,小类下又有好几个小小类,就像下图: 要实现这个也不难, 思路如下:按照大类来循环,如上就是按照张江校区.徐汇校区.临港校区三个大类循环,然 ...

最新文章

  1. 干货 | 5个常用的深度学习框架
  2. 北大OJ百练——3179:最长单词(C语言)
  3. 如何无缝迁移 SpringCloud/Dubbo 应用到 Serverless 架构
  4. 淘宝网消费者年维权成功金额达1.69亿
  5. python人脸关键点识别_用Face++实现人脸关键点检测
  6. python按月分组_python-将行按两列分组并通过比较过滤值
  7. MVVM教程(2):
  8. JUnit5 @BeforeEach注解示例
  9. maven不引入parent_Maven从入门到放弃
  10. 突发,Spring框架发现重大漏洞!
  11. C++ for (auto it:myset) 是什么意思 引用
  12. jackson改变json值_使用jackson处理json数据
  13. 数学建模之统计回归模型详解
  14. List转Map的几种方式
  15. 人民币对美元汇率中间价报6.7774元 下调109个基点
  16. 电脑系统怎么重装?PE系统安装教程一键系统重装
  17. Vue的生命周期钩子函数之activated
  18. win11如何快速关机 windows11快捷键关机的设置方法
  19. 奇闻 为什么Xenophon DAO 社区人人都想戴 绿帽子
  20. 数字化是指用计算机,数字化

热门文章

  1. 美食杰(个人主页) 下
  2. 微星电脑不能u盘引导linux,微星电脑设置从U盘启动的三种方式
  3. 使用Android Studio将开源库发布到Jcenter中央库
  4. Android手机的USB
  5. 2022-Arch安装(详细)
  6. 图片怎么转换成PDF格式?这两种方法赶紧记下
  7. “创药网”-创新药领域专业资讯网站​
  8. STM32单片机串口空闲中断+DMA接收不定长数据
  9. 国内图像处理相关期刊
  10. GameOff2022参与有感