springboot easyexcel 导出excel案例及文件无法打开 您所在的位置:网站首页 打开excel显示不能识别的文件格式怎么解决 springboot easyexcel 导出excel案例及文件无法打开

springboot easyexcel 导出excel案例及文件无法打开

2024-07-01 20:59| 来源: 网络整理| 查看: 265

文章目录 背景介绍easyexcel 表头及数据表头简单合并 web项目导出方式 实践出真知简单动态表头案例遇到的问题前端联调时excel无法打开下载文件接口有时返回文件流有时返回json的情况   导出数据是后端经典模块之一,从原有的poi到现在的easyexcel等等都在努力的帮助开发们缩小数据与excel之间的鸿沟。但是在简单的导出也会遇到一些有的没的问题,特地写个文章记录下~

背景介绍

一般导出流程图如下:

组装数据 导出

组装数据: 包括excel中表头、数据及样式 导出: 文件流

easyexcel 表头及数据

官方文档总结的都是经典~

表头: 分为固定表头和动态表头,然后再可以继续划分简单版本和复杂版本,其中复杂版本类似有三四级表头(以前写poi硬编码写到爆炸=_=||)~ 示例如下(图片来源): 在这里插入图片描述 数据: 随表头变更

表头 简单

在这里插入图片描述

固定表头,可声明一个实体类进行定义,如下:

@Data public class TitleData { @ExcelProperty("字符串标题") private String string; @ExcelProperty("日期标题") private Date date; @ExcelProperty("数字标题") private Double doubleData; }

动态表头,只能自己手动写代码进行定义,如下:

// 外层数组,一个值代表一列 List headList = new ArrayList(); List head0 = new ArrayList(); head0.add("字符串标题"); headList.add(head0); List head1 = new ArrayList(); head1.add("日期标题"); headList.add(head1); List head2 = new ArrayList(); head2.add("数字标题"); headList.add(head2); 合并

在这里插入图片描述

@Data public class ComplexHeadData { @ExcelProperty({"主标题", "字符串标题"}) private String string; @ExcelProperty({"主标题", "日期标题"}) private Date date; @ExcelProperty({"主标题", "数字标题"}) private Double doubleData; } web项目导出方式

web项目一般有两种导出方式:

提供下载链接(异步):先生成excel并上传至oss/文件服务器,返回文件链接给前端,由前端自行下载文件流(同步):生成excel并塞入response流中

本文主要关注文件流方式,示例代码如下:

// 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 String fileName = URLEncoder.encode("测试", "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data()); 实践出真知 简单动态表头案例

本案例比较简单,根据请求参数time来动态定义表头和创建数据,并以文件流方式返回给前端。 效果如下: 效果图 pom中添加依赖:

com.alibaba easyexcel 2.2.7

业务逻辑代码如下:

@RestController public class ResultController { @PostMapping(value = "/export") public void export(@RequestParam Integer time) { try { HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); response.setHeader("Content-Disposition", "attachment; filename=export.xlsx"); // 响应类型,编码 response.setContentType("application/vnd.ms-excel;charset=utf-8"); response.setCharacterEncoding("utf-8"); EasyExcel.write(response.getOutputStream()).head(getHead(time)).sheet("数据").doWrite(getData(time)); } catch (IOException e) { log.error("导出问卷数据失败!错误信息为:{}", e.getMessage()); e.printStackTrace(); } } /** * 获取excel标题栏(姓名、手机号、提交时间) * @param questionnaireId * @return */ private List getHead(Integer time) { // 外层数组,一个值代表一列 List headList = new ArrayList(); List nameList = new ArrayList(); nameList.add("姓名"); headList.add(nameList); List telList = new ArrayList(); telList.add("手机号"); headList.add(telList); List submitDTList = new ArrayList(); submitDTList.add("提交时间"); headList.add(submitDTList); for (int i = 0 ; i // 将填写结果 + 提交时间合并为一行数据 List resultList = new ArrayList(); for (int i = 0 ; i list.add("动态内容" + j); } resultList.add(list); } return resultList; } } 遇到的问题 前端联调时excel无法打开

问题描述: 后台用postman调试都ok,能正常打开excel!但是前端调试时下载的excel提示有破损,无法打开!!! Tips: 勇敢(不怕死)的质疑前端,你代码有BUG! 解决方案: 前端需在request和response中添加responseType: blob设置

(以下伪代码,请重点关注responseType设置即可)

前端request应该设置responseType为arraybuffer或blob return request({ url: '/platform/export', method: 'post', responseType: 'blob', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: qs.stringify(data) }) 前端以blob格式接收response,并设置type为application/msexcel handleExport(){ exportData({id: this.id}).then(res => { if(res){ const fileName = this.name + '.xlsx'; var blob = new Blob([res], { type: "application/msexcel;charset=utf-8", }); const URL = window.URL || window.webkitURL; const downloadElement = document.createElement("a"); const href = URL.createObjectURL(blob); // 创建下载的链接 downloadElement.href = href; downloadElement.download = fileName; // 下载后文件名 document.body.appendChild(downloadElement); downloadElement.click(); // 点击下载 document.body.removeChild(downloadElement); // 下载完成移除元素 URL.revokeObjectURL(href); // 释放掉blob对象 } }) }, 下载文件接口有时返回文件流有时返回json的情况

测试小姐姐提了个单,token超时后,点击下载按钮还是能正常导出,excel内容是后端认证系统返回的错误码json串 =_=|| ,网上查找一番也找大佬们讨论了下,对于将文件流封装成系统设定的统一返回json方式不可取,最后抱着前端小姐姐的细腿求解决喽 解决方法:前端获取response后根据 content-type进行区分 网上参考文档 在这里插入图片描述

未完待续......


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有