springboot利用easyexcel在浏览器中下载excel

前言

项目中操作excel是一种很常用的功能,比如下载一份excel的报价单。这篇文章会介绍一款excel的处理工具以及导出遇到的三个常见异常(重要)。

之前遇到一个这样的需求:后台管理页面,点击下载按钮,下载一份excel格式的报价清单

在这里插入图片描述

是不是让人头疼? 别怕,往下看,很简单~

easyexcel

EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能,这是阿里开源项目,官方文档:https://easyexcel.opensource.alibaba.com/docs/current/

文档里面有"读Excel",“写Excel”,"填充Excel"这三个栏目,从上面的需求来看,我们导出的表格不是规则的表格,并且里面还有特定的样式,因此我们选择填充Excel

文档写得非常详细,又是中文,大家可以自己看文档。我这里给出一个简单的例子

引入依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version>
</dependency>

文档好像没有直接给出依赖

浏览器下载示例:

public void down(){ExcelWriter excelWriter = null; // Ⅰtry {//boards 数据省略//access 数据省略ServletRequestAttributes servletRequestAttributes =  (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletResponse response = servletRequestAttributes.getResponse();// ⅡString fileName = URLEncoder.encode(LocalDate.now() + " 测试.xlsx", StandardCharsets.UTF_8.toString()).replace("+", "%20"); // Ⅲresponse.setContentType("application/force-download");response.setCharacterEncoding("utf-8");response.setHeader("Content-Disposition", "attachment;filename=" + fileName);InputStream inputStream = this.getClass().getResourceAsStream("/static/price-template.xlsx");// ⅣexcelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(inputStream).excelType(ExcelTypeEnum.XLSX).build();WriteSheet writeSheet = EasyExcel.writerSheet().build();//ⅤFillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();excelWriter.fill(new FillWrapper("list1", boards), fillConfig, writeSheet);excelWriter.fill(new FillWrapper("list2", access), fillConfig, writeSheet);excelWriter.fill(orderEntity, writeSheet);Map<String, BigDecimal> map = new HashMap<>();map.put("boardsTotalPrice", boardsTotalPrice);map.put("accessTotalPrice", accessTotalPrice);map.put("totalPrice", boardsTotalPrice.add(accessTotalPrice));excelWriter.fill(map, writeSheet);} catch (Exception e){e.printStackTrace();} finally {if (!Objects.isNull(excelWriter)){excelWriter.close();}}
}

**Ⅰ:**try catch之前定义一个ExcelWriter,最后在finally里面关闭,释放资源

**Ⅱ:**HttpServletResponse response可以通过参数传入,这里直接通过对象获取

**Ⅲ:**输出格式如下的文件”2023-12-11 测试.xlsx“,因为是中文,所以使用URLEncoder,因为有空格,所以有这样的代.replace(“+”, “%20”)

**Ⅳ:**以流的形式读取模板,注意模板是放在resource下的static目录下

**Ⅴ:**这里就是填充数据了,因为有两个列表,因此定义list1和list2,下面看看填充的模板

在这里插入图片描述

总得来说大部分代码是固定的,只有填充数据那里是动态的

遇到的问题

这里讲讲开发过程中遇到的问题

1.依赖冲突

先看看会报什么错误

com.alibaba.excel.exception.ExcelGenerateException: java.lang.NoSuchMethodError: 'void org.apache.poi.ss.usermodel.Cell.setBlank()'

com.alibaba.excel.exception.ExcelGenerateException: java.lang.NoSuchMethodError: 'javax.xml.parsers.DocumentBuilder org.apache.poi.util.XMLHelper.newDocumentBuilder()'

出现这个问题大概率就是引入了

<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.0.0</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.0</version>
</dependency>

因为

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.1</version>
</dependency>

已经包含了上面的两个依赖。

2.模板文件编译后损坏

报错:

com.alibaba.excel.exception.ExcelGenerateException: Create workbook failureCaused by: org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException: No valid entries or contents found, this is not a valid OOXML (Office Open XML) fileat org.apache.poi.openxml4j.util.ZipArchiveThresholdInputStream.getNextEntry(ZipArchiveThresholdInputStream.java:145)
Caused by: java.util.zip.ZipException: Unexpected record signature: 0X9

因为文件损坏,无法创建workbook,如遇到这个问题在pom文件添加以下插件即可

<!-- 避免font文件的二进制文件格式压缩破坏 -->
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>3.2.0</version><configuration><nonFilteredFileExtensions><nonFilteredFileExtension>xlsx</nonFilteredFileExtension></nonFilteredFileExtensions></configuration>
</plugin>

3.线上无法读取模板

先看看报错

java.io.FileNotFoundException: file:/data2/xxx0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/static/template/price-template.xlsx (No such file or directory)

你本地是没有问题的,但是部署到线上却有问题

首先出现这样的问题大概率是你在读取模板的时候使用了以下的方式

ResourceUtils.getFile("classpath:static\xxx");ResourceUtils.getURL("/static/price-template.xlsx").getPath();

通过这种正常路径访问

比如说我上面的代码刚开始是这样写的

String path = ResourceUtils.getURL("/static/price-template.xlsx").getPath();
FileInputStream inputStream = new FileInputStream(path);

本地是没有问题的,因为price-template.xlsx文件就是真实的存储在磁盘里面的static目录下,但到线上就不一样了,因为当打成jar包,该文件是存在jar包文件资源里,而不是真实存在于磁盘路径上。

所以后面我把代码改成

InputStream inputStream = this.getClass().getResourceAsStream("/static/price-template.xlsx");

直接获取jar包里面的模板,并且输出文件流

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/214577.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《人工智能导论》知识思维导图梳理【1~5章节】

文章目录 说明第一章 绪论人工只能概述 第二章 知识表示和知识图谱一阶谓词逻辑和知识表示法产生式表示和框架表示法 第三章 确定性推理方法推理的基本概念自然演绎推理归结演绎推理谓词公式化子句集鲁宾孙归结原理归结反演归结反演求解问题 第四章 不确定性推理方法似然推理可…

npm run build时提示vue/types/jsx.d.ts中的错误

解决方法一&#xff1a; 可能是因为vue版本过高引起的 我直接将package.json中vue以及vue-template-compiler的版本的前面^去掉&#xff0c;安装指定的版本 注意&#xff1a;vue和vue-template-compiler需要版本一致 参考链接&#xff1a;链接 解决方法二&#xff1a; 如果如…

线上问题得解决

问题&#xff1a; 最近碰到一个比较棘手但是比较低级的问题&#xff0c;一直没有找到原因&#xff0c;苦找了两天才发现问题。场景就是订单做了某一个操作之后&#xff08;比如拣货完成&#xff09;然后到下一步&#xff08;下道口&#xff09;。 但是线上几万笔订单 &#xf…

QT使用SQLite 超详细(增删改查、包括对大量数据快速存储和更新)

QTSQLite 在QT中使用sqlite数据库&#xff0c;有多种使用方法&#xff0c;在这里我只提供几种简单&#xff0c;代码简短的方法&#xff0c;包括一些特殊字符处理。在这里也给大家说明一下&#xff0c;如果你每次要存储的数据量很大&#xff0c;建议使用事务&#xff08;代码中…

canvas 有趣的弹簧效果

先上效果 两个小球之间有一根弹簧&#xff0c;这里有一条线表示&#xff0c;其中左球固定&#xff0c;在点击开始后&#xff0c;右球开始做自由落体 思路 先做受力分析 经过受力分析可以发现&#xff0c;整个系统一共有三个力在起作用&#xff0c;我们分别把他们求出来并合成…

控制台打印如来佛图像

代码 System.out.println(" _ooOoo_ \n"" o8888888o \n"" 88 \".\" 88 …

python——第十七天

方法重写(overwrite) 、方法覆盖(override )&#xff1a;在继承的基础上&#xff0c;子类继承了父类的方法&#xff0c;如果不能满足自己使用&#xff0c;我们就可以重写或覆盖该方法 函数重载(overload)&#xff1a; 在强数据类型的编程语言中(如Java、C、C等等): 函数名称…

转换 pytorch 格式模型为 caffe格式模型 pth2caffemodel

基于 GitHub xxradon/PytorchToCaffe 源码&#xff0c;修改 example\resnet_pytorch_2_caffe.py 如下 import os import sys sys.path.insert(0, .)import torch from torch.autograd import Variable from torchvision.models import resnet import pytorch_to_caffe"&q…

PDI/Kettle-9.4.0.0-343源码下载及编译

目录 &#x1f351;一、概要&#x1f34a;最新版本10.x&#xff08;2023-11-30&#xff09; &#x1f351;二、下载&#x1f351;三、编译&#x1f34a;3.1、导入开发工具&#x1f34a;3.2、开始编译&#x1f34a;3.3、编译报错&#x1f34a;3.4、报错原因&#xff1a;jdk版本低…

centos7安全防护_CPU占用率超过百分之300_centos7.4中毒CPU百分之百_清理毒源---Linux工作笔记068

执行top命令的时候看到有个进程: sshd占用cpu百分之300多...而且就算是kill -9 杀掉进程以后,进程又会自动启动 ll /proc/7298 我们执行这个命令,可以看到有个/var/tmp/sshd的文件 我们进入cd /var/tmp 然后我们执行 rm -rf sshd删除这个文件,然后我们再去top可以看到 cpu就…

【数仓理论】

一、数仓建模方法论 1.1 ER模型&#xff08;Entity Relationship、实体关系模型、范式模型&#xff09; ER模型是Bill Inmon提出的一种建模方法&#xff0c;实体关系模型将复杂的数据抽象为两个概念 ---- 实体和关系 该模型在范式理论上符合3NF&#xff0c;这种模型目的是减少…

测距传感器

测距传感器 电子元器件百科 文章目录 测距传感器前言一、测距传感器是什么二、测距传感器的类别三、测距传感器的应用实例四、测距传感器的作用原理总结前言 测距传感器广泛应用于自动化控制、机器人导航、无人驾驶、测量仪器等领域。不同类型的测距传感器具有不同的测距范围、…

xtu oj 1178 Rectangle

题目描述 给你两个平行于坐标轴的矩形&#xff0c;请判断两者是不是相交&#xff08;面积有重合的部分&#xff09;&#xff1f; 输入 第一行是一个整数K&#xff0c;表示样例数。 每个样例占两行&#xff0c;每行是4个整数&#xff0c;表示一个矩形的对角线点的坐标&#x…

重磅!2023中国高校计算机大赛-人工智能创意赛结果出炉

目录 中国计算机大赛-人工智能创意赛现场C4-AI大赛颁奖及留影800个AI应用&#xff1f;这届大学生真能“搞事情”AI原生时代&#xff0c;百度要再培养500万大模型人才 中国计算机大赛-人工智能创意赛现场 12月8日&#xff0c;杭州&#xff0c;一位“白发老人”突然摔倒在地&…

[基础IO]文件描述符{C库函数\系统接口\初识fd}

文章目录 1.基础知识1.1对文件的认识1.2对系统调用接口的认识1.3如何理解LInux下一切皆文件? 2.C语言的库函数2.1FILE *fopen(const char *path, const char *mode);2.2对fopen()的mode的w/a的深层认识2.3fclose()2.4size_t fwrite(const void *ptr, size_t size, size_t nmem…

测试经理主管面试题

测试专业技能 请谈谈您对软件测试生命周期&#xff08;STLC&#xff09;的理解 需求分析&#xff1a;在这个阶段&#xff0c;测试团队仔细分析项目需求&#xff0c;理解产品功能和非功能需求。这有助于确定测试的范围和目标&#xff0c;为后续阶段奠定基础。测试计划&#xf…

【桌面应用开发】Tauri是什么?基于Rust的桌面应用

自我介绍 做一个简单介绍&#xff0c;酒架年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【…

深入.NET平台和C#编程总结大全

第一章 简单认识.NET框架 &#xff08;1&#xff09;首先我们得知道 .NET框架具有两个主要组件&#xff1a;公共语言进行时CLR&#xff08;Common Language Runtime&#xff09;和框架类库FCL&#xff08;Framework Class Library&#xff09; 配图&#xff1a; &#xff08;…

JSON

JSON指的是 JavaScript 对象表示法&#xff08;JavaScript Object Notation&#xff09; javascript对象&#xff1a;javascript中&#xff0c;除开JavaScript原始值(字符串&#xff0c;数字&#xff0c;布尔值&#xff0c;null&#xff0c;正则表达式)的都是javascript对象 JS…

Java - JVM内存区域的划分

Java 程序运行时&#xff0c;需要在内存中分配空间。为了提高运算效率&#xff0c;就对空间进行了不同区域的划分&#xff0c;因为每一片区域都有特定的处理数据方式和内存管理方式。 分配&#xff1a;通过关键字new创建对象分配内存空间&#xff0c;对象存在堆中。 释放 &…