1、pom引用
<!--Lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<!--easyexcel依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.1</version>
</dependency>
2、实体类,@ColumnWidth()为设置标题单元格宽度,@ExcelProperty()为设置标题内容
@Data public class ExportData { @ColumnWidth(20) @ExcelProperty("类型") private String type; @ColumnWidth(20) @ExcelProperty("描述") private String description; @ColumnWidth(30) @ExcelProperty("备注信息") private String remarks; }
3、使用导出空数据模板用于下载导入模板
@ApiOperation("下载模板") @GetMapping("/downTemplate") public void downTemplate(HttpServletResponse response){ EasyExcelUtils.webWriteExcel(response, null, ExportData.class, "导入模板"); }
4、导出一个sheet数据模板
@ApiOperation("导出一个sheet数据模板") @GetMapping("/export") public void export(HttpServletResponse response){ List<ExportData> dataList = new ArrayList<>(); ExportData data = new ExportData(); data.setType("1"); data.setDescription("描述内容"); data.setRemarks("备注信息"); dataList.add(data); EasyExcelUtils.webWriteExcel(response,dataList,ExportData.class,"导出数据"); }
5、导出多个sheet数据模板
(1)HorizontalCellStyleStrategy设置数据样式,第一个参数设置头部的样式,第二个参数设置内容的样式
(2)writerSheet设置sheet信息,第一个参数为第几个sheet,第二个参数设置sheet名称
(3)head设置实体类
(4)write设置导出数据,第一个参数为导出的数据,第二个参数为导出到哪一个sheet
@ApiOperation("导出多个sheet数据模板") @GetMapping("/export") public void export(HttpServletResponse response){ try { String fileName = URLEncoder.encode("模板名称", "UTF-8"); response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); //内容样式策略 WriteCellStyle contentWriteCellStyle = new WriteCellStyle(); //垂直居中,水平居中 contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); contentWriteCellStyle.setBorderLeft(BorderStyle.THIN); contentWriteCellStyle.setBorderTop(BorderStyle.THIN); contentWriteCellStyle.setBorderRight(BorderStyle.THIN); contentWriteCellStyle.setBorderBottom(BorderStyle.THIN); //设置 自动换行 contentWriteCellStyle.setWrapped(true); // 字体策略 WriteFont contentWriteFont = new WriteFont(); // 字体大小 contentWriteFont.setFontHeightInPoints((short) 14); contentWriteCellStyle.setWriteFont(contentWriteFont); //头策略使用默认 WriteCellStyle headWriteCellStyle = new WriteCellStyle(); ServletOutputStream outputStream = response.getOutputStream(); try { //创建模板并设置样式 ExcelWriter excelWriter = EasyExcel.write(outputStream).registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle,contentWriteCellStyle)).build(); List<ExportData> dataList = new ArrayList<>(); ExportData data = new ExportData(); data.setType("1"); data.setDescription("描述内容"); data.setRemarks("备注信息"); dataList.add(data); //创建第一个sheet WriteSheet sheet1 = EasyExcel.writerSheet(0, "第一个sheet名称").head(ExportData.class).build(); excelWriter.write(dataList, sheet1); //创建第二个sheet WriteSheet sheet2 = EasyExcel.writerSheet(1, "第二个sheet名称").head(ExportData.class).build(); excelWriter.write(dataList, sheet2); excelWriter.finish(); } catch (Exception e) { e.printStackTrace(); } finally { outputStream.close(); } }catch (Exception e){ throw new RuntimeException("导出模板失败"); }}
6、导入数据模板,需要实现监听器,继承AnalysisEventListener类
@Slf4j public class ExportDataListener extends AnalysisEventListener<ExportData> { private ExportDataService exportDataService; /** * 每隔1条存储数据库,然后清理list ,方便内存回收 */ private static final int BATCH_COUNT = 1; /** * 缓存的数据 */ private List<ExportData> dataList = Lists.newArrayListWithExpectedSize(BATCH_COUNT); public ExportDataListener (ExportDataService exportDataService) { this.exportDataService = exportDataService; } @Override public void invoke(ExportData data, AnalysisContext context) { log.info("解析到一条导入数据:{}", JSON.toJSONString(data)); dataList.add(data); // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if (dataList.size() >= BATCH_COUNT) { saveData(); // 存储完成清理 list dataList = Lists.newArrayListWithExpectedSize(BATCH_COUNT); } } @Override public void doAfterAllAnalysed(AnalysisContext context) { log.info("导入数据解析完成"); // 这里也要保存数据,确保最后遗留的数据也存储到数据库 saveData(); } @Override public void onException(Exception exception, AnalysisContext context) throws Exception { // 不抛出异常,继续读取 log.error("处理导入数据失败,继续读取"); } //导入数据处理 private void saveData() { exportDataService.importData(dataList); } }
导入只有一个sheet的表数据方法
@Autowired private ExportDataService exportDataService;@PostMapping("/import") @ApiOperation("导入一个sheet数据") public Boolean importData(@RequestPart MultipartFile file){ try { InputStream in = file.getInputStream(); EasyExcel.read(in, ExportData.class, new ExportDataListener(exportDataService)).sheet().doRead(); } catch (Exception e) { e.printStackTrace(); } return true; }
导入多个sheet的表数据方法
(1)实现多个监听器
(2)readSheet为读取的sheet表,从0开始
(3)headRowNumber为从第几行开始读取,默认从0第一行开始,因去掉标题,则从1第二行开始
(4)head为读取时封装的实体类
(5)registerReadListener为监听器
@Autowired
private ExportDataService exportDataService;
@PostMapping("/import") @ApiOperation("导入多个sheet数据") public Boolean importData(@RequestPart MultipartFile file){ try { InputStream in = file.getInputStream(); ExcelReader excelReader = EasyExcel.read(in).build(); ReadSheet sheet1 = EasyExcel.readSheet(0).headRowNumber(1).head(ExportData.class).registerReadListener(new ExportDataListener(exportDataService)).build(); ReadSheet sheet2 = EasyExcel.readSheet(1).headRowNumber(1).head(ExportData.class).registerReadListener(new ExportDataListener(exportDataService)).build(); excelReader.read(sheet1,sheet2); excelReader.finish(); } catch (Exception e) { e.printStackTrace(); } return true; }