当前位置:   article > 正文

vue2/ElementUi+Springboot+EsayExcel导出表格,“Excel无法打开文件”填坑_springboot导出excel无法打开文件,因为文件格式或扩展名无效

springboot导出excel无法打开文件,因为文件格式或扩展名无效

以上是症状,实际的关键做法是在发送请求的时候,加上一个参数:responseType:"blob"

网上的做法或者声称的解决方案,好多都没用,所以我整理了一个保姆教程。

因为我是基于vue2+ElementUi做的前端  Maven+springboot做的后台,所以技术栈不契合的,请自行补课。

前端代码:

vue页面:

  1. <!--elementUi中的按钮组件-->
  2. <el-button type="primary" @click="exportData">导出今日数据</el-button>

vue生命周期中的methods内,完成导出函数

  1. //导入请求api,这里解构的方法是下方调用的方法
  2. import { exportData } from '@/api/orders'
  3. //这个是自定义的文件下载js,下面会贴出完整代码
  4. import { download } from '@/utils/downloadfile'
  5. methods: {
  6. exportData(){
  7. let _this=this;
  8. //api中声明请求后台的方法
  9. exportData().then(response => {
  10. download(response,"data.xlsx"); //启动下载方法,这里的文件名可自定义,但是后缀一定得是“.xlsx”
  11. })
  12. }
  13. }

@/api/orders.js中的请求方法

  1. //网络请求及鉴权组件(elementUi自带)
  2. import request from '@/utils/request'
  3. import { getToken,setToken } from '@/utils/auth'
  4. const state = {
  5. token: getToken()
  6. }
  7. //api请求
  8. export function exportData(){
  9. return request({
  10. url: '/orders/exportData',//因为要用后台的response返回文件流,所以这个跳转的后台方法返回值要设置为void
  11. method: 'get',
  12. responseType:"blob",//我在这里卡了2个多小时,几乎95%以上的教程都没提到需要设置这个参数
  13. params:{
  14. token:getToken() //也可在封装的request.js中挂载token,看个人爱好
  15. }
  16. })
  17. }

上面还会有个问题,因为ElementUi集成的网络请求,要求服务端返回响应状态码。但是后端方法设置返回值为void,导致框架无法正常获取响应状态码,所以在处理响应的时候,要考虑一下这里的特殊情况!!!

@/unit/request.js

  1. // response interceptor
  2. service.interceptors.response.use(
  3. /**
  4. * If you want to get http information such as headers or status
  5. * Please return response => response
  6. */
  7. /**
  8. * Determine the request status by custom code
  9. * Here is just an example
  10. * You can also judge the status by HTTP Status Code
  11. */
  12. response => {
  13. const res = response.data;
  14. //如果没有返回code则直接向调用端返回response.data
  15. //当然我这里只是做个提醒,相关返回操作您可以根据自己的实际需要,做的更优雅一些
  16. if (res.code==undefined){
  17. return res;
  18. }
  19. // if the custom code is not 200, it is judged as an error.
  20. if (res.code !== 200) {
  21. Message({
  22. message: res.message || 'Error',
  23. type: 'error',
  24. duration: 5 * 1000
  25. })
  26. return Promise.reject(new Error(res.message || 'Error'))
  27. } else {
  28. return res
  29. }
  30. },
  31. error => {
  32. console.log('err' + error) // for debug
  33. Message({
  34. message: error.message,
  35. type: 'error',
  36. duration: 5 * 1000
  37. })
  38. return Promise.reject(error)
  39. }
  40. )

@/utils/downloadfile.js 下载工具

  1. //主要作用是将返回的文件流以blob的方式,模拟生成下载链接并模拟点击,完成下载
  2. export function download(data, filename) {
  3. let blob = new Blob([data], { type: 'application/x-www-form-urlencoded' });
  4. let blobUrl = window.URL.createObjectURL(blob);
  5. const aElement = document.createElement('a');
  6. document.body.appendChild(aElement);
  7. aElement.style.display = 'none';
  8. aElement.href = blobUrl;
  9. aElement.download = filename;
  10. aElement.click();
  11. document.body.removeChild(aElement);
  12. }

后台代码:

pom.xml中引入Excel相关依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.apache.poi</groupId>
  4. <artifactId>poi</artifactId>
  5. <version>4.1.2</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.apache.poi</groupId>
  9. <artifactId>poi-ooxml</artifactId>
  10. <version>4.1.2</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.apache.poi</groupId>
  14. <artifactId>poi-ooxml-schemas</artifactId>
  15. <version>4.1.2</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>com.alibaba</groupId>
  19. <artifactId>easyexcel</artifactId>
  20. <version>2.2.6</version>
  21. </dependency>
  22. </dependencies>

设置导出实体类,其中继承了Excel设置

注意:该类可以是项目原来的对象类加Excel注解,如果有需要的话,也可以自己写一个导出类,方便导出数据格式化。

  1. import com.alibaba.excel.annotation.ExcelProperty;
  2. import com.alibaba.excel.annotation.write.style.ColumnWidth;
  3. import lombok.AllArgsConstructor;
  4. import lombok.Data;
  5. import lombok.NoArgsConstructor;
  6. import lombok.ToString;
  7. import java.io.Serializable;
  8. @Data
  9. @AllArgsConstructor
  10. @NoArgsConstructor
  11. @ToString
  12. public class exportData implements Serializable {
  13. @ColumnWidth(10)
  14. @ExcelProperty(value = "序号", index = 0)
  15. private Integer id;
  16. @ColumnWidth(15)
  17. @ExcelProperty(value = "用户姓名", index = 1)
  18. private String cusname;
  19. @ColumnWidth(25)
  20. @ExcelProperty(value = "用户电话", index = 2)
  21. private String cusphoneNo;
  22. }

这里还有个坑:如果导出的数据中有null值,也会导致Excel导出异常,所以sql语句配置要处理一下null值。

下方为mybatis/Mapper文件中的查询设置:

  1. <!--(@i:=@i+1) AS 'id'/(SELECT @i:=0) AS itable 这部分是生成行号的操作,因为数据id不一定是连续的,导出的文件中不加行号比较不易阅读-->
  2. <!--IFNULL(cusphoneNo,'') AS 'cusphoneNo' 将空值转为空字符串,用来填充文件-->
  3. <select id="toexport" resultType="com.hz.entity.exportData">
  4. SELECT (@i:=@i+1) AS 'id',cusname AS 'cusname',IFNULL(cusphoneNo,'') AS 'cusphoneNo' from orders,(SELECT @i:=0) AS itable;
  5. </select>

后台导出方法

  1. @GetMapping("/exportData")
  2. @ApiOperation(value = "导出数据")
  3. @ResponseBody //实现数据接口
  4. public void exportData(HttpServletResponse response) {
  5. try{
  6. response.setContentType("application/vnd.ms-excel");
  7. response.setCharacterEncoding("utf-8");
  8. // URLEncoder.encode防止中文乱码
  9. String filName = URLEncoder.encode("导出的数据表", "utf-8");
  10. response.setHeader("Content-disposition", "attachment;filename=" + filName +".xlsx");
  11. //用model层处理数据,mybatis做相关数据操作,这里就不细说了,别说你连不上数据库
  12. List<exportData> etlst = ordersService.toexport();
  13. EasyExcel.write(response.getOutputStream(),exportData.class).excelType(ExcelTypeEnum.XLSX).sheet("sheet1").doWrite(etlst);
  14. }catch (Exception e){
  15. System.out.println(e.getMessage());
  16. }
  17. }

注意的坑:

1、前端请求时一定要带要求返回的类型,即responseType:"blob"

2、因为要用后台的response返回文件流,所以后台导出方法返回值要设置为void,让EasyExcel的write和response输出流进行主动返回。

3、mybatis中的查询及返回给导出类的映射数据不能为空,所以如果可能出现空值的字段,要提前做好处理。

总之,导出的Excel文件无法打开,不是数据格式有问题,就是文件格式有问题,但是照我写的来,基本都能成功。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/998860
推荐阅读
相关标签
  

闽ICP备14008679号