第一步:先导包。网上很多版本,我用的1.1版本
org.apache.poi poi${poi.version} org.apache.poi poi-ooxml${poi.version} com.alibaba easyexcel1.1.2-beta5 org.projectlombok lombok1.18.2
第二步:工具类,里面包含了两个版本的工具类,1.1版本和3.02版本,这个可以不用看,下面的方法,不用它
package com.tufang.erp.util; import com.alibaba.excel.EasyExcelFactory; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.baseRowModel; import com.alibaba.excel.metadata.Sheet; import lombok.Data; import lombok.Getter; import lombok.Setter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.io.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class EasyExcelUtil{ private static final Logger LOGGER = LoggerFactory.getLogger(EasyExcelUtil.class); // // public staticList read(String filePath, final Class> clazz) { // File f = new File(filePath); // try (FileInputStream fis = new FileInputStream(f)) { // return read(fis, clazz); // } catch (FileNotFoundException e) { // LOGGER.error("文件{}不存在", filePath, e); // } catch (IOException e) { // LOGGER.error("文件读取出错", e); // } // // return null; // } // // public static List read(InputStream inputStream, final Class> clazz) { // if (inputStream == null) { // throw new BusinessException("解析出错了,文件流是null"); // } // // // 有个很重要的点 DataListener 不能被spring管理,要每次读取excel都要new,然后里面用到spring可以构造方法传进去 // DataListener listener = new DataListener<>(); // // // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 // EasyExcel.read(inputStream, clazz, listener).sheet().doRead(); // return listener.getRows(); // } // // public static void write(String outFile, List> list) { // Class> clazz = list.get(0).getClass(); // // 新版本会自动关闭流,不需要自己 *** 作 // EasyExcel.write(outFile, clazz).sheet().doWrite(list); // } // // public static void write(String outFile, List> list, String sheetName) { // Class> clazz = list.get(0).getClass(); // // 新版本会自动关闭流,不需要自己 *** 作 // EasyExcel.write(outFile, clazz).sheet(sheetName).doWrite(list); // } // // public static void write(OutputStream outputStream, List> list, String sheetName) { // Class> clazz = list.get(0).getClass(); // // 新版本会自动关闭流,不需要自己 *** 作 // // sheetName为sheet的名字,默认写第一个sheet // EasyExcel.write(outputStream, clazz).sheet(sheetName).doWrite(list); // } // // // public static void download(HttpServletResponse response, List> list, String sheetName) throws IOException { // Class> clazz = list.get(0).getClass(); // // // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman // response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // response.setCharacterEncoding("utf-8"); // // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 // String fileName = URLEncoder.encode(sheetName, "UTF-8").replaceAll("\+", "%20"); // response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); // EasyExcel.write(response.getOutputStream(), clazz).sheet(sheetName).doWrite(list); // } private static Sheet initSheet; static { initSheet = new Sheet(1, 0); initSheet.setSheetName("sheet"); //设置自适应宽度 initSheet.setAutoWidth(Boolean.TRUE); } public static List
第三步,监听类,必须写。这是监听和获取数据的
package com.tufang.erp.manage.controller.excel; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.tufang.erp.dao.object.ManagePurchaseSupplierPriceDO; import com.tufang.erp.dao.object.excel.PriceExcelInputRequest; import com.tufang.erp.util.BeanUtil; import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; public class PurchasePriceExcelListener extends AnalysisEventListener{ private static final int BATCH_COUNT = 5; List list = new ArrayList (); private static int count = 1; @Override @Transactional public void invoke(PriceExcelInputRequest inputRequest, AnalysisContext context) { //新建采购价目表对象 ManagePurchaseSupplierPriceDO priceDO = new ManagePurchaseSupplierPriceDO(); priceDO.setPurchasePrice(inputRequest.getPurchasePrice()); BeanUtil.copy(inputRequest,priceDO); System.out.println("解析到一条数据:{ "+ inputRequest.toString() +" }"); list.add(inputRequest); count ++; // if (list.size() >= BATCH_COUNT){ // saveData( count ); // list.clear(); // } } @Override public void doAfterAllAnalysed(AnalysisContext context) { // priceMapper.insertPurchasePriceList(priceDOList); saveData( count ); // System.out.println("所有数据解析完成!"); // System.out.println(" count :" + count); } private void saveData(int count) { // System.out.println("{ "+ count +" }条数据,开始存储数据库!" + list.size()); // System.out.println("存储数据库成功!"); } //通过这个方法获取数据 public List getDatas() { // System.out.println("{ "+ count +" hahahahhahahhah }条数据,开始存储数据库!" + list.size()); return list; } }
PriceExcelInputRequest 是自定义的类,根据业务需求新建。
第四步,控制层(controller层)
@PostMapping("addPurchasePriceExcelInput") @ApiOperation(value = "excel数据导入", httpMethod = "POST") @PublicInterface public ResultResponseaddPurchasePriceExcelInput(@RequestBody MultipartFile file) throws IOException { //获取登录信息 ManageUserDO user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser(); //上传过来excel文件 Sheet sheet = new Sheet(1,1, PriceExcelInputRequest.class); //监听器 PurchasePriceExcelListener listener = new PurchasePriceExcelListener(); //读取数据 EasyExcelFactory.readBySax(file.getInputStream(),sheet,listener); //数据 List datas = listener.getDatas(); //数据校验 List priceDOS = checkExcelDatas(datas, user.getId()); //新增数据库 priceService.insertPurchasePriceList(priceDOS); return ResultResponse.successResponse(); }
第五步,获取到数据,必须进行数据校验(校验很繁琐,但必须写,没办法), *** 作自己的数据库,这个就不用教了吧。
下面是我的数据校验,你们要根据自己的写。
public ListcheckExcelDatas(List datas, Long id){ //返回集合 List priceDOList = new ArrayList (); //循环 for (PriceExcelInputRequest inputRequest :datas){ ManagePurchaseSupplierPriceDO priceDO = new ManagePurchaseSupplierPriceDO(); BigDecimal purchasePrice = inputRequest.getPurchasePrice(); Long supplierId = inputRequest.getSupplierId(); String supplierName = inputRequest.getSupplierName(); String materialName = inputRequest.getMaterialName(); Date startTime = inputRequest.getStartTime(); Date endTime = inputRequest.getEndTime(); Long materialId = inputRequest.getMaterialId(); //校验数据类型 //必填项校验 if (supplierId ==null || materialId==null || startTime==null || endTime==null || purchasePrice==null ){ throw new BusinessException("供应商编码,产品编码,采购价格,生效日期,失效日期,为必填"); } //第一步,校验供应商id 本库有无 if (supplierId !=null){ ManageBasicSupplierDO manageBasicSupplierDO = supplierMapper.selectByPrimaryKey(supplierId); if (Objects.isNull(manageBasicSupplierDO)){ throw new BusinessException("请填写正确的供应商编码 "+supplierName+"的编码 "+supplierId+"错误"); }else if (manageBasicSupplierDO.getStatus()!=1){ throw new BusinessException("供应商名称为 "+supplierName+"未审核通过 "); } }else { throw new BusinessException("供应商编码,必填"); } //第二步,校验商品id正确否 if (materialId !=null){ ManageBasicMaterialDO manageBasicMaterialDO = materialMapper.selectByPrimaryKey(materialId); if (Objects.isNull(manageBasicMaterialDO)){ throw new BusinessException("产品编码为"+materialId+"填写错误"); }else if (!materialName.equals(manageBasicMaterialDO.getName())){ throw new BusinessException("产品编码和产品名称必须对应"); }else if (!"2".equals(manageBasicMaterialDO.getStatus())){ throw new BusinessException("产品id 为"+materialId+"商品库审核未通过"); } }else { throw new BusinessException("产品编码,必填"); } //生效时间和失效时间校验 Date nowDate = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()); if (startTime ==null || endTime==null){ throw new BusinessException("生效时间和失效时间必填"); } if (startTime.getTime() > endTime.getTime()){ throw new BusinessException("失效时间必须小于生效时间"); }else if (endTime.getTime() managePurchasePriceMaterialDOS = priceExtMapper.selectMaterialListByMaterialId(supplierId, materialId); if (managePurchasePriceMaterialDOS !=null && managePurchasePriceMaterialDOS.size()>0){ throw new BusinessException("供应商名称 "+supplierName+" 对应的产品 "+materialName+" 已经存在"); } priceDO.setPurchasePrice(inputRequest.getPurchasePrice()); BeanUtil.copy(inputRequest,priceDO); //获取登录信息 // list.add(inputRequest); priceDO.setCreateUserId(id); priceDO.setUpdateUserId(id); priceDO.setCreateTime(Date.from(LocalDateTime.now().atZone( ZoneId.systemDefault()).toInstant())); priceDOList.add(priceDO); } return priceDOList; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)