赞
踩
Excel的导入和导出一直以来都是很常用的功能之一,为了更加方便实现Excel的基本操作,特此引入EasyExcel。EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。能在不用考虑性能、内存等因素的情况下,快速完成Excel的读、写等功能。
说明:本文基于EasyExcel 3.1.0版本,JDK17.0.6版本。
//Gradle配置
implementation group: 'com.alibaba', name: 'easyexcel', version: '3.1.0'
<!-- maven配置 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.0</version>
</dependency>
/** * ID */ @ExcelIgnore private String id; /** * 名称 */ @ExcelProperty(value = "名称", index = 1) private String name; /** * 单位 */ @ExcelProperty(value = "状态", index = 2, converter = StatusConverter.class) private Integer status;
@ExcelProperty注解:
@ExcelProperty注解常用参数:
value=>导出字段的名称(Excel表的列头名称)
index=>导出的字段在Excel表格的顺序
converter=>导出的字段需要自定义映射的转换器
@Operation(summary = "导出数据") @PostMapping(value = "/exportData") public void exportData(HttpServletResponse response) throws IOException { //设置内容类型 response.setContentType("application/vnd.ms-excel;charset=utf-8"); //设置编码格式 response.setCharacterEncoding("UTF-8"); //设置导出文件名称(避免乱码) String fileName = java.net.URLEncoder.encode("data.xlsx", "UTF-8"); //设置返回头信息 response.setHeader("Content-Disposition", "attachment; filename=" + fileName); //冲刷缓存 response.flushBuffer(); //获取输出流 OutputStream out = response.getOutputStream(); EasyExcelFactory.write(out, ExportVo.class) //对应的导出实体类 .sheet("数据") //导出sheet页名称 //列宽度自适应设置 .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) .doWrite(result); //查询获取的数据集合List<T> out.flush(); out.close(); }
@Component public class StatusConverter implements Converter<Integer> { @Override public Class<Integer> supportJavaTypeKey() { return Integer.class; } @Override public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; } @Override public Integer convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { return "启用".equals(cellData.getStringValue()) ? 1 : 0; } @Override public WriteCellData<?> convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { return new WriteCellData<>(value.equals(1) ? "启用" : "停用"); } }
/** * ID */ @ExcelProperty(index = 0) private String id; /** * 名称 */ @ExcelProperty(index = 1) private String name; /** * 状态 */ @ExcelProperty(index = 2, converter = StatusConverter.class) private Integer status;
@ExcelProperty注解:
@ExcelProperty注解常用参数:
value=>导出字段的名称(Excel表的列头名称)
index=>导出的字段在Excel表格的顺序
converter=>导出的字段需要自定义映射的转换器
注意:导入时value和index尽量只使用一种,value是按名称映射,index是按列号映射(value和index混合使用不知道内部逻辑会将表格数据如何映射到实体上)
@Operation(summary = "导入数据")
//如果除了上传文件之外还需要其他参数,则需要如下设置
//consumes = MediaType.MULTIPART_FORM_DATA_VALUE
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public @ResponseBody Response importMonitorIndexData(MultipartFile file, @RequestParam("detail") String detail) throws IOException {
//获取文件的输入流
InputStream inputStream = file.getInputStream();
List<ImportVo> lst = EasyExcel.read(inputStream) //调用read方法
//注册自定义监听器,字段校验可以在监听器内实现
.registerReadListener(new CustomListener())
.head(ImportVo.class) //对应导入的实体类
.sheet(1) //导入数据的sheet页编号,0代表第一个sheet页
.headRowNumber(2) //列表头行数,2代表列表头有2行,第三行开始为数据行
.doReadSync(); //开始读Excel,返回一个List<T>集合,继续后续入库操作
}
public class CustomListener extends AnalysisEventListener { List<String> names = Lists.newArrayList(); /** * 每解析一行,回调该方法 * * @param data * @param context */ @Override public void invoke(Object data, AnalysisContext context) { //校验名称 String name = ((ImportVo) data).getName(); if (StringUtils.isEmpty(name)) { throw new RuntimeException(String.format("第%s行名称为空,请核实", context.readRowHolder().getRowIndex() + 1)); } if (names.contains(name)) { throw new RuntimeException(String.format("第%s行名称已重复,请核实", context.readRowHolder().getRowIndex() + 1)); } else { names.add(name); } } /** * 出现异常回调 * * @param exception * @param context * @throws Exception */ @Override public void onException(Exception exception, AnalysisContext context) throws Exception { if (exception instanceof ExcelDataConvertException) { Integer columnIndex = ((ExcelDataConvertException) exception).getColumnIndex() + 1; Integer rowIndex = ((ExcelDataConvertException) exception).getRowIndex() + 1; String message = "第" + rowIndex + "行,第" + columnIndex + "列" + "数据格式有误,请核实"; throw new RuntimeException(message); } else if (exception instanceof RuntimeException) { throw exception; } else { super.onException(exception, context); } } /** * 解析完全部回调 * * @param context */ @Override public void doAfterAllAnalysed(AnalysisContext context) { //解析完全部回调逻辑实现 names.clear(); } }
以上全部为EasyExcel实现导入导出的详细说明,如需要更多复杂的场景实现可参考EasyExcel官方网站 EasyExcel官网
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。