开发中,导出 excel 是经常会遇到的,如果你使用 spring 框架,那么 easypoi 再适合不过了,它是对 Apache POI 的封装,但是使用起来却非常简单,唯一的缺点是包有点大,二十M左右,可能 Apache POI 本身就比较大吧,具体不清楚。
由于有 easypoi-spring-boot-starter 所以集成非常简单,在你的 pom 文件里新增:
<dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-spring-boot-starter</artifactId> <version>4.1.3</version> </dependency>
至于版本号,你可以在 https://mvnrepository.com/artifact/cn.afterturn/easypoi-spring-boot-starter 查看最新版本。
然后,我们新建一个类,比如 VisitRecordModel.java 大致代码如下:
@Data public class VisitRecordModel { @Excel(name = "标识", orderNum = "1") private String visitedFlag; @Excel(name = "计划回访时间", orderNum = "2", width = 12.0, exportFormat = "yyyy-MM-dd") private Date visitPlanDate; }
然后 新建一个 EasyPoiUtil 类,代码如下:
public class EasyPoiUtil { public static void exportExcel(String title, String sheetName, boolean isCreateHeader, Class<?> pojoClass, List<?> data, HttpServletResponse response, String fileName) throws ExcelExportException { ExportParams exportParams = new ExportParams(title, sheetName); exportParams.setCreateHeadRows(isCreateHeader); Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, data); if (workbook == null) throw new ExcelExportException(); try { downloadExcel(response, fileName, workbook); } catch (ExcelExportException e) { throw new ExcelExportException(); } } private static void downloadExcel(HttpServletResponse response, String fileName, Workbook workbook) throws ExcelExportException { fileName = fileName + ".xls"; try { String encodeFileName = URLEncoder.encode(fileName, "UTF-8"); response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=" + encodeFileName); workbook.write(response.getOutputStream()); } catch (Exception e) { throw new ExcelExportException(); } } }
这里的 download 方法支持 下载 中文的文件名哦,前提是你用 get 请求来下载,即 controller 层用 get 请求即可。调用如下:
private void downloadVisitRecord(ArrayList<HashMap<String, Object>> result, HttpServletResponse response) { List<VisitRecordModel> list = new ArrayList<>(); for (HashMap<String, Object> map : result) { list.add(VisitRecordModel.fromMap(map)); } try { EasyPoiUtil.exportExcel("xxxx - 回访记录", "回访记录", true, VisitRecordModel.class, list, response, "回访记录_" + DateUtils.formatDate(new Date(), "yyyy-MM-dd_HH-mm-ss")); } catch (ExcelExportException e) { throw new ExcelExportException(); } }
这里,传入 model 的 class 类型 以及 一个 list 数组,这个数组包含若干个 model 即可。如果使用 post 请求,那么 vue 部分代码需要修改,请求结束后,将返回保存为 blob 然后下载,即请求结束后代码如下:
const link = document.createElement("a"); let blob = new Blob([res], { type: "application/vnd.ms-excel" }); link.style.display = "none"; link.href = URL.createObjectURL(blob); link.setAttribute("download", "统计.xls"); document.body.appendChild(link); link.click(); document.body.removeChild(link);
请求部分的代码也需要修改,具体如下:
return request({ method: "post", url: "/xxx/xxx/export", data: params, responseType: "blob", headers: { "Content-Type": "multipart/form-data" } })
如果请求部分代码不这样写,下载下来的 excel 会乱码哦,主要是 responseType 和 headers 吧!