springboot进行excel导出相关操作
- 前言
- 背景
- 遇到的问题
- 1.文件excel文件导出
前言
之前给工作做了一个自动发邮件的小工具在其中遇到了一些小问题,主要就是导出excel文件的相关问题
背景
这个项目虽小但是我用到的东西还是挺多的,由于是maven项目,直接上pom文件,看到pom文件就知道都用到什么了
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.sfis</groupId>
<artifactId>development_tool</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>development_tool</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<velocity.version>2.0</velocity.version>
<swagger.version>2.7.0</swagger.version>
<aliyun.oss.version>2.8.3</aliyun.oss.version>
<mybatis.version>2.1.3</mybatis.version>
<jodatime.version>2.10.1</jodatime.version>
<poi.version>3.17</poi.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-io.version>2.6</commons-io.version>
<httpclient.version>4.5.1</httpclient.version>
<jwt.version>0.9.0</jwt.version>
<aliyun-java-sdk-core.version>4.3.3</aliyun-java-sdk-core.version>
<aliyun-sdk-oss.version>3.1.0</aliyun-sdk-oss.version>
<aliyun-java-sdk-vod.version>2.15.2</aliyun-java-sdk-vod.version>
<aliyun-java-vod-upload.version>1.4.11</aliyun-java-vod-upload.version>
<aliyun-sdk-vod-upload.version>1.4.11</aliyun-sdk-vod-upload.version>
<fastjson.version>1.2.28</fastjson.version>
<gson.version>2.8.2</gson.version>
<json.version>20170516</json.version>
<commons-dbutils.version>1.7</commons-dbutils.version>
<canal.client.version>1.1.0</canal.client.version>
<docker.image.prefix>zx</docker.image.prefix>
<cloud-alibaba.version>0.2.2.RELEASE</cloud-alibaba.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--分页助手-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!--日期时间工具-->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>${jodatime.version}</version>
</dependency>
<!--xls-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--数据源的依赖-->
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>druid</artifactId>-->
<!-- <version>1.1.6</version>-->
<!-- </dependency>-->
<!--用于解析和处理excel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
<!--xlsx-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<!--commons-io-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<!--加密解密的工具Base64的工具包-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
<!--aliyun-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>${aliyun-java-sdk-core.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun-sdk-oss.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>${json.version}</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>10.2.0.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xlsx</include>
<include>**/*.xls</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
以上就是我的项目环境,自己抽空做的项目为了方便就这样吧
遇到的问题
1.文件excel文件导出
先上代码
private void outSpUpdate(HttpServletResponse response, @RequestBody Map<String ,String> map) throws Exception {
//设置用于下载文件的头
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
//fileName为浏览器下载后的文件名
// String tempalte = "static/SP更新记录.xlsx";
ClassPathResource classPathResource = new ClassPathResource("static/SP更新记录.xlsx");
InputStream tempalte =classPathResource.getInputStream();
String fileName = URLEncoder.encode("SP更新记录", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
List<Map> spUpdateList = spUpdateService.SpUpdateCondition(map);
//链式编程daWrite()的参数为List<Object>类型的数据
ExcelWriterSheetBuilder sheet = EasyExcel.write(response.getOutputStream()).withTemplate(tempalte).sheet();
sheet.doFill(spUpdateList);
}
关于easyexcel的使用我这里就不多介绍了很简单
主要是模板文件的引入,其实模板文件的位置只要是在resources下就都是可以的,根据自己的需求定义一个文件夹,然后把模板文件放进去我这里的位置是resources/static/SP更新记录.xlsx然后需要在导出的设置中添加此文件的导出
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xlsx</include>
<include>**/*.xls</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
其中用于用于导出excel文件的的就是**/**.xlsx前边的路径可以根据自己的路径写,resource.filtering一定要设为false,让maven不会对该文件进行重新编码,默认为true会导致模板文件无法打开
以下内容来自SpringBoot读取Resource下文件的几种方式 读取文件的方式主要来自以下四种:尝试了四种读取方式,并且测试了四种读取方式分别的windows开发环境下(IDE中)读取和生产环境(linux下jar包运行读取)。
第一种:
ClassPathResource classPathResource = new ClassPathResource("excleTemplate/test.xlsx");
InputStream inputStream =classPathResource.getInputStream();
1
2
第二种:
InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("excleTemplate/test.xlsx");
1
第三种:
InputStream inputStream = this.getClass().getResourceAsStream("/excleTemplate/test.xlsx");
第四种:
File file = ResourceUtils.getFile("classpath:excleTemplate/test.xlsx");
InputStream inputStream = new FileInputStream(file);
经测试:
前三种方法在开发环境(IDE中)和生产环境(linux部署成jar包)都可以读取到,第四种只有开发环境 时可以读取到,生产环境读取失败。
推测主要原因是springboot内置tomcat,打包后是一个jar包,无法直接读取jar包中的文件,读取只能通过类加载器读取。
前三种都可以读取到其实殊途同归,直接查看底层代码都是通过类加载器读取文件流,类加载器可以读取jar包中的编译后的class文件,当然也是可以读取jar包中的excle模板了。
用解压软件打开jar包查看结果如下:
在这里插入图片描述
其中cst文件中是编译后class文件存放位置,excleTemplate是模板存放位置,类加载器读取的是cst下class文件,同样可以读取excleTemplate下的模板的文件流了。
所以总结一下:假如文件是在jar包中,读取方式应当使用基于类加载器读取文件流的方式,比如前三种方法;使用基于java中File方式的读取,在jar包情况下是读取不到的,比方说第四种。
本次解决问题也参考了一些其他的文章,非常感谢分享
SpringBoot项目部署开发环境,Excel模板下载文件损坏,提示恢复问题处理