Excel处理
章节简介
此章节介绍系统中Excel导入、导出功能。系统Excel相关操作基于FastExcel,详情可参阅官方文档
无模板导出
本方法可以在不创建模板的情况下,根据实体类定义的字段,导出Excel,但是导出的Excel样式会比较单一,适合对样式没有要求的场景。
如果要调整样式,请参考FastExcel官方文档
- 定义实体类,通过
@ExcelProperty注解定义字段名称
@Data
public class DemoExcelDto {
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "年龄")
private int age;
//BoolConvert转换布尔型数据为中文
@ExcelProperty(value = "意向")
@BoolConvert(trueText = "愿意", falseText = "不愿意")
private Boolean willing;
//日期转换器,可自定义格式
@ExcelProperty(value = "生日")
@LocalDateConvert(pattern = "yyyy年MM月dd")
private LocalDate birthday;
//日期转换器,可自定义格式
@ExcelProperty(value = "申请时间")
@LocalDateTimeConvert(pattern = "yyyy年MM月dd HH时mm")
private LocalDateTime applyTime;
}
- 在
Controller中调用ExcelUtil.writeExcelToResponse()方法导出Excel,writeExcelToResponse可以直接将Excel写入到HTTP的输出流中,从而实现下载功能。
@GetMapping(value = "/writeExcel", produces = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
public void writeExcel() {
ExcelUtil.writeExcelToResponse(createMockList(), "下载文件名称", DemoExcelDto.class);
}
按模板导出
在大部分场景下,客户对于导出Excel样式的需求比较高,如果通过Java代码去调整样式会比较繁琐,此时可以制作导出模板,直接去填充数据即可。
- 制作模板,放入代码
/resources/data/excelTemplate目录下 - 在
Controller中调用ExcelUtil.fillExcelToResponse()方法读取模板,填充数据,导出Excel
注意
模板名称要和文件名一致,但是不需要加/data前缀。class要和实体类一致,否则会报错。
@ApiOperation(value = "填充excel")
@GetMapping("/fillExcel")
public void fillExcel() {
ExcelUtil.fillExcelToResponse(createMockList(), "下载文件名称", "模板名称.xlsx", DemoExcelDto.class);
}
导入
用户体验问题
导入功能如果没有做的好,用户体验会很差,无故报错,不知道导入结果等问题会接踵而至。在提升用户体验时,一方面需要给定用户模板,方便用户填写。第二是由于导入时数据多,当遇到有问题数据时,一定要给用户友好的提示,辅导其修正数据 ,由于本章节对Excel相关功能的基础介绍,篇幅有限,关于如何做好导入功能,请参考优秀案例模块的的导入案例
系统提供了对读取Excel的封装方法,可以直接读取Excel文件中的数据。在做导入业务时,一定要配合下载模板功能,否则用户很容易乱填数据。
- 先制作模板,放入代码
/resources/data/excelTemplate目录下 - 提供下载模板的方法,前端提供下载功能,
SystemUtil.downloadClassPathFile方法可以直接读取classpath下的文件,并输出到Response输出流中,从而实现下载功能。
@ApiOperation("下载模板")
@GetMapping("/downloadTemplate")
public void downloadTemplate() {
SystemUtil.downloadClassPathFile("/data/excelTemplate/duty_meeting_import_template.xlsx");
}
- 提供导入接口,通过
ExcelUtil.readExcel方法读取文件,并转换为实体类列表
@PostMapping("/readExcel")
public Result readExcel(MultipartFile file) {
List<DemoExcelDto> list = ExcelUtil.readExcel(file, DemoExcelDto.class);
return new JsonResult<>(list);
}
扩展方法
ExcelUtil提供了非常多方法扩展,以下详细介绍
- 导出时,通过注解可以自动实现自动对日期,布尔值进行转换 通过实现FastExcel的
cn.idev.excel.converters.Converter<T>接口,可以按需求自己实现转换器,在导出方法中,传入自己的转换器即可。
示例中生日和申请时间会自动转换为yyyy年MM月dd格式,意向字段会根据willing的值自动填充为愿意或不愿意。
@Data
public class DemoExcelDto {
@ExcelProperty(value = "姓名")
private String name;
@ExcelProperty(value = "年龄")
private int age;
@ExcelProperty(value = "意向")
@BoolConvert(trueText = "愿意", falseText = "不愿意")
private Boolean willing;
@ExcelProperty(value = "生日")
@LocalDateConvert(pattern = "yyyy年MM月dd")
private LocalDate birthday;
@ExcelProperty(value = "申请时间")
@LocalDateTimeConvert(pattern = "yyyy年MM月dd HH时mm")
private LocalDateTime applyTime;
}
ExcelUtil提供了多种读取和写入Excel的方法,以下是部分方法的签名:
// 从HTTP上传的MultipartFile中 读取 Excel(默认读取第一个 sheet,从第2行开始作为数据行)
readExcel(MultipartFile excel, Class<T> clazz);
// 从HTTP上传的MultipartFile中 读取 Excel 的指定 sheet(从第2行开始作为数据行)
readExcel(MultipartFile excel, Class<T> clazz, int sheetNo);
// 从输入流中 读取 Excel(默认读取第一个 sheet,从第2行开始作为数据行)
readExcel(InputStream excel, Class<T> clazz);
// 从输入流中 读取 Excel 的指定 sheet(从第2行开始作为数据行)
readExcel(InputStream excel, Class<T> clazz, int sheetNo);
// 从输入流中 读取 Excel 的指定 sheet 和表头起始行号
readExcel(InputStream excel, Class<T> clazz, int sheetNo, int headLineNum);
// 将数据写入 Excel 并通过 HttpServletResponse 输出
writeExcelToResponse(List<?> list, String fileName, Class<?> clazz);
// 将数据写入 Excel 并通过 HttpServletResponse 输出(支持自定义转换器)
writeExcelToResponse(List<?> list, String fileName, Class<?> clazz, List<? extends Converter<?>> converters);
// 将数据写入 Excel 并输出到指定 OutputStream
writeExcel(List<?> list, Class<?> clazz, OutputStream outputStream);
// 将数据写入 Excel 并输出到指定 OutputStream(支持自定义转换器)
writeExcel(List<?> list, Class<?> clazz, List<? extends Converter<?>> converters, OutputStream outputStream);
// 使用模板导出 Excel 并通过 HttpServletResponse 输出
fillExcelToResponse(List<?> list, String fileName, String template, Class<?> clazz);
// 使用模板导出 Excel 并通过 HttpServletResponse 输出(支持自定义转换器)
fillExcelToResponse(List<?> list, String fileName, String template, Class<?> clazz, List<? extends Converter<?>> converters);
// 使用模板导出 Excel 到指定 OutputStream
fillExcel(List<?> list, String template, Class<?> clazz, OutputStream outputStream);
// 使用模板导出 Excel 到指定 OutputStream(支持自定义转换器)
fillExcel(List<?> list, String template, Class<?> clazz, List<? extends Converter<?>> converters, OutputStream outputStream);
