报表导出有很多种方法,像之前我有写过的jxl,poi,jasperreport又或者各种商业软件,这次来简单介绍下用了许久的开源轮子easypoi。
easypoi的底层原理就不介绍了。因为官方文档的不足,本次简单记录下使用easypoi导出excel的各种方法。
首先在具体介绍前,建议大家先看一看easypoi的官方文档,http://easypoi.mydoc.io/
文档中基础使用上的介绍还是比较详细的。
本次我以目前流行的springboot项目为例。
第一步我们需要引入easypoi的依赖,一个自定义的starter
<dependency> <groupId>cn.afterturngroupId> <artifactId>easypoi-spring-boot-starterartifactId> <version>3.3.0version> dependency>
注意:引入了这个就不用再引入poi的包了,自定义的starter已经包含相关依赖了。
1、默认导出方式
导出类的配置
@Getter @Setter public class GroupCtrlVO { @Excel(name = "操作人", orderNum = "1", width = 30) private String ctrlUser; @Excel(name = "操作时间", orderNum = "2", width = 30, format = "yyyy-MM-dd HH:mm:ss") private Date ctrlTime; @Excel(name = "标签名称", orderNum = "3", width = 30) private String groupName; @Excel(name = "操作类型", orderNum = "4", width = 30) private String ctrlOperation; }
service的配置
@Override public void export(String login, HttpServletResponse response) { OutputStream output = null; try { WebUserDO userDO = cmWebUserMapper.getWebUserByLogin(login); Listlist = crmCustomerInfoGroupMapper.listCtrlVo(userDO.getId()); Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), GroupCtrlVO.class, list); response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(login+ "标签操作记录.xls", "UTF-8")); response.setContentType("application/msexcel"); output = response.getOutputStream(); workbook.write(output); } catch (Exception e) { log.error("标签操作记录导出失败!", e); } finally { try { output.close(); } catch (IOException e) { log.error("标签操作记录输出流关闭失败!", e); } } }
2、模板导出方式
excel模板:相关循环参数参考官方文档
service配置:
@Override public void export(String startDate, String endDate, HttpServletResponse response) { OutputStream output = null; try { Listlist = testMapper.list(startDate,endDate); TemplateExportParams params = new TemplateExportParams(ExcelPathUtils.convertTemplatePath("static/report/template_test_report.xlsx")); Map data = new HashMap (); data.put("list", list); Workbook workbook = ExcelExportUtil.exportExcel(params, data); response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(startDate+"~"+endDate + "测试报表.xlsx", "UTF-8")); response.setContentType("application/msexcel"); output = response.getOutputStream(); workbook.write(output); } catch (Exception e) { e.printStackTrace(); } finally { try { output.close(); } catch (IOException e) { log.error("测试报表输出流关闭失败!", e); } } }
注意:导出的字段要和模板循环到字段相同
3、模板多sheet导出
多sheet模板:
service配置:
@Override public void export(String startDate, String endDate, String strategyName, HttpServletResponse response) { OutputStream output = null; try { //查表1数据 Listlist = testMapper.listStrategy(strategyName, startDate, endDate); //查表2数据 List listDetail = test2Mapper.listStrategy(strategyName, startDate, endDate); TemplateExportParams params = new TemplateExportParams(ExcelPathUtils.convertTemplatePath("static/report/template_test_two_sheet_report.xlsx"),true); Map data = new HashMap (); data.put("list", list); data.put("listDetail", listDetail); Workbook workbook = ExcelExportUtil.exportExcel(params, data); response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(startDate+"~"+endDate + "测试多表单报表.xlsx", "UTF-8")); response.setContentType("application/msexcel"); output = response.getOutputStream(); workbook.write(output); } catch (Exception e) { log.error("测试多表单导出失败!", e); } finally { try { output.close(); } catch (IOException e) { log.error("测试多表单输出流关闭失败!", e); } } }
因为springboot打成jar包,文件读取路径的问题,上述案例中ExcelPathUtils是我按照自己需求重写的,有需要的同学可以参考下。
/** * poi导出路径获取,解决jar包找不到路径的问题 * 思路:将文件写入tomcat临时文件夹中 * @author 小卖铺的老爷爷 * @date 2018年12月26日 */ public class ExcelPathUtils { public static String convertTemplatePath(String path) { // 如果是windows 则直接返回 // if (System.getProperties().getProperty("os.name").contains("Windows")) { // return path; // } Resource resource = new ClassPathResource(path); FileOutputStream fileOutputStream = null; // 将模版文件写入到 tomcat临时目录 String folder = System.getProperty("catalina.home"); File tempFile = new File(folder + File.separator + path); // System.out.println("文件路径:" + tempFile.getPath()); // 文件存在时 不再写入 if (tempFile.exists()) { return tempFile.getPath(); } File parentFile = tempFile.getParentFile(); // 判断父文件夹是否存在 if (!parentFile.exists()) { parentFile.mkdirs(); } try { BufferedInputStream bufferedInputStream = new BufferedInputStream(resource.getInputStream()); fileOutputStream = new FileOutputStream(tempFile); byte[] buffer = new byte[10240]; int len = 0; while ((len = bufferedInputStream.read(buffer)) != -1) { fileOutputStream.write(buffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (fileOutputStream != null) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return tempFile.getPath(); } }