EasyExcel对于导入导出的操作十分简洁,记录一下多个sheet且内容不一致的导入导出。
引入 easyExcel依赖
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.1</version></dependency>
- 导出下载
提示:其中部分代码操作Dao层可以删除,可以自己创建ExportUserExcel 对象进行测试,思路数据映射到excel中。
这里ExportUserExcel .class 映射的模板替换下面代码中
@AllArgsConstructor
@NoArgsConstructorUser
@Builder
@HeadRowHeight(value = 20)
public class ExportUserExcel {@ExcelProperty(value = "姓名",index = 0)@ColumnWidth(value = 10)private String userName;@ExcelProperty(value = "年龄",index = 1)@ColumnWidth(value = 20)private String age;@ExcelProperty(value = "性别",index = 2)@ColumnWidth(value = 20)private String gender;
}
- 导出下载 ExportUserExcel.class 模板
public void modelExport(HttpServletResponse response, Long id) {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码try {String fileName = URLEncoder.encode("Physical", "UTF-8");response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");//新建ExcelWriterExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();//获取sheet0对象WriteSheet mainSheet = EasyExcel.writerSheet(0, "模型信息").head(ExportUserExcel.class).build();//获取模型信息,向sheet0写入数据DmmPhysicalModel dmmPhysicalModel = dmmPhysicalModelMapper.selectById(id);List<DmmPhysicalModel> dmmPhysicalModels1 = Arrays.asList(dmmPhysicalModel);excelWriter.write(dmmPhysicalModels1, mainSheet);//获取sheet1对象WriteSheet detailSheet = EasyExcel.writerSheet(1, "词条信息").head(ExportUserExcel.class).build();HashMap entryHashMap = new HashMap<>();entryHashMap.put("model_id", id);//获取词条信息,向sheet1写入数据List<DmmPhysicalEntry> list = dmmPhysicalEntryMapper.selectByMap(entryHashMap);excelWriter.write(list, detailSheet);//关闭流excelWriter.finish();} catch (IOException e) {log.error("导出异常{}", e.getMessage());}}
-
导入excel 存入数据库,
2.1 接收excel实体数据类
注意:一定要和excel表标题内容一致 ,
@ExcelProperty(value = “标题名称”)
/*** Copyright 2022 bejson.com */
package com.dtyunxi.yundt.cube.biz.item.svr.rest;import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;/*** Auto-generated: 2022-07-20 14:18:43** @author bejson.com (i@bejson.com)* @website http://www.bejson.com/java2pojo/*/
@Data
public class ModelImportVO{@ExcelProperty(value = "标题名称")private String title;@ExcelProperty(value = "标题名称")private String merchant_no;@ExcelProperty(value = "标题名称")private String terminal_id;@ExcelProperty(value = "标题名称")private String token;}
这里很多博客的代码没有贴全,少了一个监视器读取excel的类!
package com.infinitus.dmm.service.impl;import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;import java.util.ArrayList;
import java.util.List;/*** excel表格读取监视器*/
public class ExcelListener extends AnalysisEventListener {//可以通过实例获取该值private List<Object> datas = new ArrayList<Object>();public void invoke(Object o, AnalysisContext analysisContext) {datas.add(o);doSomething(o);}private void doSomething(Object object) {}public List<Object> getDatas() {return datas;}public void setDatas(List<Object> datas) {this.datas = datas;}public void doAfterAllAnalysed(AnalysisContext analysisContext) {}
}
2.excel导入到数据库 多个sheet、
ModelImportVO.class这也是模板,自己可以定义,对应的值。
@PostMapping("test/excel/import")public void modelImport(MultipartFile serviceFile) throws IOException {//输入流InputStream inputStream = serviceFile.getInputStream();//监视器ExcelListener listener = new ExcelListener();ExcelReader excelReader = EasyExcel.read(inputStream, listener).build();// 第一个sheet读取类型ReadSheet readSheet1 = EasyExcel.readSheet(0).head(ModelImportVO.class).build();// 第二个sheet读取类型ReadSheet readSheet2 = EasyExcel.readSheet(1).head(EntryImportVO.class).build();// 开始读取第一个sheetexcelReader.read(readSheet1);//excel sheet0 信息List<Object> list = listener.getDatas();//List<object> 转 List<实体类>List<JsonRootBean> dtoList = new ArrayList<>();//List object for 转换 实体类for (Object objects : list) {JsonRootBean dto = (JsonRootBean) objects;dtoList.add(dto);}//List 转JOSNString json = JSON.toJSONString(dtoList);System.out.println("json = " + json);// 清空之前的数据listener.getDatas().clear();// 开始读取第二个sheetexcelReader.read(readSheet2);//excel sheet1 信息List<Object> entry = listener.getDatas();//copy上面作法}
执行psotman接口请求
补充获取sheet名称 长度等信息方法
//获取从第二个sheet读取类型 词条多个sheet
//监视器
ExcelListener listener = new ExcelListener();
ExcelReader excelReader = EasyExcel.read(inputStream, listener).build();
//弃用方法 List sheets = excelReader.getSheets();
// 新方法
List sheets = excelReader.excelExecutor().sheetList();
导入文件没有创建实例类模板
兼容任何标题的Excel
//文件获取流InputStream inputStream = checkDTO.getFile().getInputStream();//excel监听器NoModelDataListener noModelDataListener = new NoModelDataListener(tableType);EasyExcel.read(inputStream, noModelDataListener).sheet().doRead();
数据统一在监听器进行插入更新
package io.sugo.cdp.upload.download.config;import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import io.sugo.cdp.upload.download.util.RegularUtils;
import lombok.Data;
import org.apache.commons.lang.StringUtils;import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;/*** easyExcel监听器* 不创建实体读取excel方式泛型用map:<Map<Integer, String>>** @author*/
@Data
public class NoModelDataListener extends AnalysisEventListener<Map<Integer, String>> {/*** excel标题字段类型*/private List<String> excelType;/*** 统计对比错误次数*/private AtomicInteger rowCountError = new AtomicInteger();/*** 执行总条数*/private AtomicLong rowCount = new AtomicLong();/*** 返回错误信息的结果集*/List<String> results = new ArrayList<>();@Overridepublic void invoke(Map<Integer, String> data, AnalysisContext context) {//mapfor (Map.Entry<Integer, String> next : data.entrySet()) {String message = next.getValue();if (message != null) {message = message.replaceAll("[\\t\\n\\r]", "");}//正则检验每一列String result = RegularUtils.excelRegular(excelType.get(next.getKey()), message);if (StringUtils.isNotBlank(result)) {//返回前10条校验错误信息if (rowCountError.get() < 10) {long numberOfRows = rowCount.get() + 1L;String stringResult = "校验失败 - 第" + numberOfRows + "行:" +"(" + next.getValue() + ") " + result;String jsonString = JSON.toJSONString(stringResult);results.add(jsonString);rowCountError.incrementAndGet();}}}//统计总行数rowCount.incrementAndGet();}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {saveData();System.out.println("rowCount = " + rowCount.get());}/*** 加上存储数据库*/private void saveData() {}public NoModelDataListener(List<String> excelType) {this.excelType = excelType;}}
常用excel导入 数据转JSON 格式 快速构建工具代码 配合上面的监视器
package com.dtyunxi.yundt.cube.biz.item.svr.rest;import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSON;
import com.dtyunxi.yundt.cube.biz.item.svr.rest.ExcelListener;
import com.dtyunxi.yundt.cube.biz.item.svr.rest.ModelImportVO;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;/*** @author 瑾秋* @date 2022-08-05 9:56*/
@RestController
public class Test11 {@PostMapping("test/excel/import")public void modelImport(MultipartFile serviceFile) throws IOException {//输入流InputStream inputStream = serviceFile.getInputStream();//监视器ExcelListener listener = new ExcelListener();ExcelReader excelReader = EasyExcel.read(inputStream, listener).build();// 第一个sheet读取类型ReadSheet readSheet1 = EasyExcel.readSheet(0).head(ModelImportVO.class).build();// 开始读取第一个sheetexcelReader.read(readSheet1);//excel sheet0 信息List<Object> list = listener.getDatas();//List<object> 转 List<实体类>List<ModelImportVO> dtoList = new ArrayList<>();//List object for 转换 实体类for (Object objects : list) {ModelImportVO dto = (ModelImportVO) objects;dtoList.add(dto);}List<ModelImportVO> ten = new ArrayList<>();//每个二十个输出一次for (ModelImportVO modelImportVO : dtoList) {if (ten.size() == 20) {System.out.println( JSON.toJSONString(ten));ten.clear();}ten.add(modelImportVO);}//最后不足二十输出一次System.out.println(JSON.toJSONString(ten));}}