【日常】EasyExcel按模板导出 踩坑日常

您所在的位置:网站首页 excel设置了模板如何去掉文字 【日常】EasyExcel按模板导出 踩坑日常

【日常】EasyExcel按模板导出 踩坑日常

2024-06-14 11:16| 来源: 网络整理| 查看: 265

需求

以指定格式导出数据,以方便运营人员后续修改后直接导入。 格式大概这样: 在这里插入图片描述

搜了下发现用EasyExcel的填充功能可以完美实现,导出后的格式与模板完全一致,不需要另外配置,只需要设置需要填充的部分,非常简单。

实现 模板

在这里插入图片描述 {name}是普通变量,调用时用Map填充 {.name}是列表变量,调用时用List填充

工具类 @Slf4j public class EasyExcelUtils { /** * 按照模板导出Excel * * @param response * @param tClass * @param templateFileName * @param fileName * @param list * @param headVariableMap * @param * @throws Exception */ public static void writeExcelWithTemplate(HttpServletResponse response, Class tClass, String templateFileName, String fileName, List list, Map headVariableMap) throws Exception { response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx"); //使用swagger可能会导致各种问题,请直接用浏览器或者用postman response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); // 分多次 填充 会使用文件缓存(省内存) try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(templateFileName).build()) { WriteSheet writeSheet = EasyExcel.writerSheet().build(); //填充普通变量 excelWriter.fill(headVariableMap, writeSheet); //填充list变量 excelWriter.fill(list, writeSheet); excelWriter.finish(); } } 调用工具类 //模板文件 String templateFileName = "./consignment_return_export_template.xlsx"; //导出文件名称 String fileName = "退供确认导入模板"; //主体信息 Map headVariableMap = MapUtils.newHashMap(); headVariableMap.put("orderDate", OrderUtils.convertTime(System.currentTimeMillis(), "yyyy-MM-dd")); List list = new ArrayList(); //这里随便写点数据用于测试 PlatformJdReturnExportExcelDTO dto = new PlatformJdReturnExportExcelDTO(); list.add(dto); EasyExcelUtils.writeExcelWithTemplate(response, PlatformJdReturnExportExcelDTO.class, templateFileName, fileName, list, headVariableMap); 参考的EasyExcel官方示例

示例代码1

/** * 最简单的填充 * * @since 2.1.1 */ @Test public void simpleFill() { // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替 String templateFileName = TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "simple.xlsx"; // 方案1 根据对象填充 String fileName = TestFileUtil.getPath() + "simpleFill" + System.currentTimeMillis() + ".xlsx"; // 这里 会填充到第一个sheet, 然后文件流会自动关闭 FillData fillData = new FillData(); fillData.setName("张三"); fillData.setNumber(5.2); EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(fillData); // 方案2 根据Map填充 fileName = TestFileUtil.getPath() + "simpleFill" + System.currentTimeMillis() + ".xlsx"; // 这里 会填充到第一个sheet, 然后文件流会自动关闭 Map map = MapUtils.newHashMap(); map.put("name", "张三"); map.put("number", 5.2); EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(map); }

示例代码2

/** * 填充列表 * * @since 2.1.1 */ @Test public void listFill() { // 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替 // 填充list 的时候还要注意 模板中{.} 多了个点 表示list // 如果填充list的对象是map,必须包涵所有list的key,哪怕数据为null,必须使用map.put(key,null) String templateFileName = TestFileUtil.getPath() + "demo" + File.separator + "fill" + File.separator + "list.xlsx"; // 方案1 一下子全部放到内存里面 并填充 String fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; // 这里 会填充到第一个sheet, 然后文件流会自动关闭 EasyExcel.write(fileName).withTemplate(templateFileName).sheet().doFill(data()); // 方案2 分多次 填充 会使用文件缓存(省内存) fileName = TestFileUtil.getPath() + "listFill" + System.currentTimeMillis() + ".xlsx"; try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) { WriteSheet writeSheet = EasyExcel.writerSheet().build(); excelWriter.fill(data(), writeSheet); excelWriter.fill(data(), writeSheet); } } 过程中遇到的问题: 不想在磁盘上保留导出文件

官方的例子是输出到本地文件的,去网上搜了一圈也都是保存下来以后再去读取放到Response里,不想那么复杂,为此还去翻了翻源码,结果发现已经有封装好的函数可以直接调,快乐。

//这样是输出到本地文件 ExcelWriter excelWriter = EasyExcel.write(fileName); //直接输出流 ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()); 导出的文件格式不对

去网上查了一下才发现,response 配置写错了,这里不多说

导出的中文文件名乱码 //这个设置只对文件内容有效, response.setCharacterEncoding("utf-8"); //文件名需要再单独设置一下 URLEncoder.encode(fileName, "UTF-8") response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx"); 发到dev环境后放在项目根目录下的模板文件无法读取

改把模板文件放到OSS 然后改从OSS url读取:

public static void writeExcelWithTemplate(HttpServletResponse response, Class tClass, String templateFileUrl, String fileName, List list, Map headVariableMap) throws Exception { response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx"); //使用swagger可能会导致各种问题,请直接用浏览器或者用postman response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); //读取模板文件 URL url = new URL(templateFileUrl); URLConnection conn = url.openConnection(); conn.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36"); InputStream templateInputStream = conn.getInputStream(); // 分多次 填充 会使用文件缓存(省内存) try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(templateInputStream).build()) { WriteSheet writeSheet = EasyExcel.writerSheet().build(); //填充普通变量 excelWriter.fill(headVariableMap, writeSheet); //填充list变量 excelWriter.fill(list, writeSheet); excelWriter.finish(); } } 参考链接

EasyExcel官方文档-填充

引申阅读

EasyExcel如何解决临时文件过大问题 填充Excel 遇到OOM



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3