1、添加依赖:

        <!-- 现在已经更新到1.1.2-beta5 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.1</version>
</dependency>

导入:

2、添加监听:

package com.aikucun.goods.biz.easyexcel;

import com.aikucun.goods.dao.model.vo.SkuModel;
import com.aikucun.goods.dao.model.vo.SkuUploadFailModel;
import com.aikucun.sc.common.utils.BeanUtils;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils; import java.util.List; public class SkuUploadListener extends AnalysisEventListener { private List<SkuUploadFailModel> uploadFailList = Lists.newArrayList(); private List<SkuModel> skuModelList = Lists.newArrayList(); private int totalSize = 0; /**
* 每解析一行,执行一次该方法
*/
@Override
public void invoke(Object object, AnalysisContext context) {
totalSize++;
SkuModel skuModel = (SkuModel) object;
if (!checkData(skuModel)) {
return;
}
skuModelList.add(skuModel);
} @Override
public void doAfterAllAnalysed(AnalysisContext context) { } private boolean checkData(SkuModel skuModel) { // 失败原因
String failMessage = "";
// itemCode
String itemCode = skuModel.getItemCode(); if (null == skuModel) {
failMessage = "数据为空";
}
// 验证sku
if (StringUtils.isEmpty(itemCode)) {
failMessage = "itemCode为空!";
} else {
if (skuModelList.contains(itemCode)) {
failMessage = failMessage + "itemCode重复!";
}
}
//品牌名称
if (StringUtils.isEmpty(skuModel.getBrandName())) {
failMessage = failMessage + "品牌名称为空!";
}
//条码必填
if (StringUtils.isEmpty(skuModel.getBarCode())) {
failMessage = failMessage + "条码为空!";
} if (StringUtils.isNotEmpty(failMessage)) {
SkuUploadFailModel failModel = new SkuUploadFailModel();
//数量校验???
BeanUtils.convert(skuModel, failModel);
failModel.setFailMessage(failMessage); uploadFailList.add(failModel);
return false;
}
return true; } public List<SkuUploadFailModel> getUploadFailList(){
return uploadFailList;
} public List<SkuModel> getSkuModelList(){
return skuModelList;
} public int getTotalSize() {
return totalSize;
}
}

3、导入商品controller:

    @PostMapping("/import-sku-list-async")
@ApiOperation("批量导入商品(异步)")
public Result importSkuListAsync(@RequestBody MultipartFile file) {
return skuService.importSkuListAsync(file);
}

4、ServiceImpl

@Override
public Result importSkuListAsync(MultipartFile file) { //1.参数校验
if (file == null || file.isEmpty()) {
throw new GoodsException("导入文件为空");
}
// 判断文件格式
String filename = file.getOriginalFilename();
String suffixName = filename.substring(filename.indexOf("."));
if (!".xlsx".equalsIgnoreCase(suffixName) && !".xls".equalsIgnoreCase(suffixName)) {
throw new GoodsException("文件格式要求:.xlsx/.xls");
}
dealDataAsync(file, suffixName);
return Result.success();
} /**
* 异步处理excel数据校验、落库、上传文件服务器等
*
* @param file
*/
@Async
public void dealDataAsync(MultipartFile file, String suffixName) { InputStream inputStream = null;
try {
inputStream = file.getInputStream();
} catch (Exception e) {
e.printStackTrace();
}
//1.注册任务
String dataFlag = System.currentTimeMillis() + "";
// 任务注册
Long id = reg("{\"service\":\"goods-web\"}", getUserName(), dataFlag, getRealName(), DataFileTaskTypeEnum.IMPORT.getType());
if (id == null) {
log.error("【导入商品】 uploadSkuFile 数据版本号:" + dataFlag + ", 注册导入任务失败");
return;
}
//2.excel数据校验
SkuUploadListener listener = new SkuUploadListener();
dealExcel(listener, suffixName, id, dataFlag, inputStream); //3.把错误数据分装集合中,正确数据封装集合中
// 验证失败的数据
List<SkuUploadFailModel> uploadFailList = listener.getUploadFailList();
// 验证通过的数据
List<SkuModel> skuModeList = listener.getSkuModelList();
// 总数量
int totalSize = listener.getTotalSize();
//4.把成功集合插入数据库,错误数据上传文件服务器
try {
for (SkuModel skuModel : skuModeList) {
Sku sku = new Sku();
BeanUtils.copyProperties(skuModel, sku);
saveOrUpdateSku(sku);
}
}catch (Exception e){
log.error("【导入商品】 数据版本号:{},保存采购单报错:{},错误详情:{}", dataFlag, e.getMessage(), e);
finish(id, DataFileTaskStatusEnum.FAIL.getType(), "", totalSize, 0, "保存到数据库报错", dataFlag);
return;
}
//5.完成任务(上传失败数据到文件服务器)
// 导入状态
int status = DataFileTaskStatusEnum.SUCCESS.getType();
String fileUrl = "";
// 导入失败的数据,生成异常文件
if (!CollectionUtils.isEmpty(uploadFailList)) {
if (CollectionUtils.isEmpty(skuModeList)) {
status = DataFileTaskStatusEnum.FAIL.getType();
} else {
status = DataFileTaskStatusEnum.PART_SUCCESS.getType();
}
fileUrl = createErrFile(uploadFailList, dataFlag);
}
finish(id, status, fileUrl, totalSize, skuModeList.size(), "导入结束", dataFlag);
} private void dealExcel(SkuUploadListener listener, String suffixName, Long id, String dataFlag, InputStream file) {
ExcelTypeEnum excelTypeEnum;
if (ExcelTypeEnum.XLSX.getValue().equalsIgnoreCase(suffixName)) {
excelTypeEnum = ExcelTypeEnum.XLSX;
} else if (ExcelTypeEnum.XLS.getValue().equalsIgnoreCase(suffixName)) {
excelTypeEnum = ExcelTypeEnum.XLS;
} else {
log.error("【导入采购单】 uploadPurchaseFile 数据版本号:" + dataFlag + ",上传文件格式不是 " + ExcelTypeEnum.XLSX.getValue() + "/" + ExcelTypeEnum.XLS.getValue());
finish(id, DataFileTaskStatusEnum.FAIL.getType(), "", 0, 0, "文件格式不正确", dataFlag);
return;
}
// 解析文件
try {
ExcelReader excelReader = new ExcelReader(file, excelTypeEnum, null, listener);
excelReader.read(new Sheet(1, 1, SkuModel.class));
} catch (Exception e) {
log.error("【导入采购单】 uploadPurchaseFile 数据版本号:{},解析文件报错:{},错误详情:{}", dataFlag, e.getMessage(), e);
finish(id, DataFileTaskStatusEnum.FAIL.getType(), "", 0, 0, "解析文件报错", dataFlag);
return;
}
} /**
* 导入商品,异常文件生成
*
* @param modelList
* @param dataFlag
*/
private String createErrFile(List<SkuUploadFailModel> modelList, String dataFlag) {
// 生成文件类型
ByteArrayOutputStream out = null;
String fileUrl = "";
try {
out = new ByteArrayOutputStream();
ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
if (modelList.size() > FILE_SIZE) {
List<List<SkuUploadFailModel>> splitList = Lists.partition(modelList, FILE_SIZE);
for (int i = 0; i < splitList.size(); i++) {
//写一个sheet,
Sheet sheet = new Sheet(i + 1, 0, SkuUploadFailModel.class);
writer.write(splitList.get(i), sheet);
}
} else {
//写一个sheet,
Sheet sheet = new Sheet(1, 0, SkuUploadFailModel.class);
writer.write(modelList, sheet);
}
writer.finish();
CloudStorageService oss = oSSFactory.build();
String path = oss.getDefaultPath("/导入商品异常反馈.xlsx");
fileUrl = oss.upload((out).toByteArray(), path);
log.info("【导入商品】 createErrFile 数据版本号:" + dataFlag + ",生成文件url:" + fileUrl);
} catch (Exception e) {
log.error("【导入商品】 createErrFile 数据版本号:" + dataFlag + ",导出报错: " + e.getMessage(), e);
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return fileUrl;
} private Long reg(String param, String userName, String dataFlag, String realName, Integer type) { DataFileTaskDTO dataFileTaskDTO = new DataFileTaskDTO();
dataFileTaskDTO.setParams(param);
dataFileTaskDTO.setDataType(SystemModuleEnum.DOWNLOAD_GOODS.getType());
dataFileTaskDTO.setType(type);
dataFileTaskDTO.setRemark(SystemModuleEnum.DOWNLOAD_GOODS.getTypeName() + ",数据版本号:" + dataFlag);
dataFileTaskDTO.setSource(SystemModuleEnum.DOWNLOAD_GOODS.getSystem());
dataFileTaskDTO.setCreateUser(realName);
dataFileTaskDTO.setCreateUserJobNumber(userName); log.info("【导入商品】推送到磐石注册任务参数,dataFileTaskDTO:{}", JSONObject.toJSONString(dataFileTaskDTO));
Result ret = remote.reg(dataFileTaskDTO);
log.info("【导入商品】推送到磐石注册任务返回结果,ret:{}", JSONObject.toJSONString(ret));
if (!CheckUtils.isNull(ret) && ret.isSuccess() && ret.getData() != null) {
return Long.parseLong( ret.getData().toString());
}
return null;
} private Long finish(Long id, Integer taskStatus, String fileUrl, Integer total, Integer successTotal, String remark, String dataFlag) { DataFileTaskDTO taskDTO = new DataFileTaskDTO();
taskDTO.setId(id);
taskDTO.setTaskStatus(taskStatus);
taskDTO.setFileUrl(fileUrl);
taskDTO.setTotal(total == null ? 0 : total);
taskDTO.setSuccessTotal(successTotal == null ? 0 : successTotal);
taskDTO.setRemark(remark + ",数据版本号:" + dataFlag); log.info("【导入商品】推送到磐石完成任务参数,dataFileTaskDTO:{}", JSONObject.toJSONString(taskDTO));
Result ret = remote.finsh(taskDTO);
log.info("【导入商品】推送到磐石完成任务返回结果,ret:{}", JSONObject.toJSONString(ret));
if (!CheckUtils.isNull(ret) && ret.isSuccess()) {
return (Long) ret.getData();
}
return null;
} /**
* 获取用户名
*
* @return
*/
private String getUserName() {
// 获取当前用户
String userName = "";
LoginUserVo loginUserVo = UserVoThreadLocal.get();
if (Objects.nonNull(loginUserVo)) {
userName = loginUserVo.getUserName();
}
return userName;
} /**
* 获取真实姓名
*
* @return
*/
private String getRealName() {
// 获取当前用户
String realName = "";
LoginUserVo loginUserVo = UserVoThreadLocal.get();
if (Objects.nonNull(loginUserVo)) {
realName = loginUserVo.getRealName();
}
return realName;
}

导出:

1、导出controller

/**
* 导出维护记录
* @param vo
*/
@PostMapping("/download")
@ApiOperation(value = "采购单下载")
public Result<String> exportRecord(@RequestBody PurchaseOrderHeadVO vo) {
purchaseManageService.exportRecord(vo);
return Result.success("导出成功");
}

2、serviceImpl

@Async
public void createRecordFile(PurchaseOrderHeadVO vo, String currentUserName, String realName,Long id,String dataFlag) {
log.info("【导出采购单】 createRecordFile 开始,参数:{},用户:{},开始时间:{} ,数据版本号:{}", JSON.toJSONString(vo), currentUserName, System.currentTimeMillis(), dataFlag);
// 任务注册
if (id == null) {
return;
}
// 生成文件类型
ByteArrayOutputStream out = null;
Map<String, Object> map = getStringObjectMap(vo);
// 根据条件查询
List<PurchaseOrderModel> list = purchaseOrderExtendMapper.listForEceport(map);
if (CollectionUtils.isEmpty(list)) {
log.info("【导出采购单】 createRecordFile 未查询到需要导出的数据,数据版本号:" + dataFlag);
finish(id, DataFileTaskStatusEnum.FAIL.getType(), "", 0, 0, "查询数据为空", dataFlag);
return;
}
try {
// 批量生成文件,每个文件数据,最多 6万
List<PurchaseDownloadModel> modelList = new ArrayList<>();
for (PurchaseOrderModel entity : list) {
PurchaseDownloadModel model = new PurchaseDownloadModel();
BeanUtils.copyProperties(entity, model);
// 采购模型
model.setPurchaseMode(PurchaseModeDictEnum.getNameByCode(model.getPurchaseMode()));
// 采购类型
model.setPurchaseType(PurchaseTypeDictEnum.getNameByCode(model.getPurchaseType()));
// 采购状态
model.setStatus(PurchaseStatusEnum.getNameByCode(model.getStatus()));
// 业务线
model.setBusinessLine(PurchaseBusinessDictEnum.getNameByCode(model.getBusinessLine()));
modelList.add(model);
}
out = new ByteArrayOutputStream();
ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
if (modelList.size() > FILE_SIZE) {
List<List<PurchaseDownloadModel>> splitList = Lists.partition(modelList, FILE_SIZE);
for (int i = 0; i < splitList.size(); i++) {
//写一个sheet,
Sheet sheet = new Sheet(i + 1, 0, PurchaseDownloadModel.class);
writer.write(splitList.get(i), sheet);
}
} else {
//写一个sheet,
Sheet sheet = new Sheet(1, 0, PurchaseDownloadModel.class);
writer.write(modelList, sheet);
}
writer.finish();
CloudStorageService oss = oSSFactory.build();
String path = oss.getDefaultPath("/采购单导出.xlsx");
String url = oss.upload((out).toByteArray(), path);
finish(id, DataFileTaskStatusEnum.SUCCESS.getType(), url, list.size(), list.size(), "导出成功", dataFlag);
log.info("【导出采购单】 createRecordFile 数据版本号:" + dataFlag + ",生成文件url:" + url);
} catch (Exception e) {
log.error("【导出采购单】 createRecordFile 数据版本号:" + dataFlag + ",导出报错: " + e.getMessage(), e);
// 发生异常,删除文件
finish(id, DataFileTaskStatusEnum.FAIL.getType(), "", list.size(), 0, "导出报错,数版本号:" + dataFlag, dataFlag);
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
log.info("【导出采购单】 createRecordFile 数据版本号:" + dataFlag + ",结束,时间:" + System.currentTimeMillis());
}

另外建议参考:https://github.com/HowieYuan/easyexcel-encapsulation

easyExcel用于导入导出的更多相关文章

  1. 使用Layui、Axios、Springboot(Java) 实现EasyExcel的导入导出(浏览器下载)

    实现EasyExcel的导入导出(浏览器下载) 实现三个按钮的功能,但是却花费了一天的时间包括总结. 使用到的技术:springboot layui axios EasyExcel mybatis-p ...

  2. 使用VUE+SpringBoot+EasyExcel 整合导入导出数据

    使用VUE+SpringBoot+EasyExcel 整合导入导出数据 创建一个普通的maven项目即可 项目目录结构 1 前端 存放在resources/static 下 index.html &l ...

  3. PL/SQLDeveloper导入导出Oracle数据库方法

    前一篇博客介绍了Navicat工具备份Oracle的方法,这篇博客介绍一下使用PL/SQL Developer工具导入导出Oracle数据库的方法. PL/SQL Developer是Oracle数据 ...

  4. 分享一次Oracle数据导入导出经历

    最近工作上有一个任务要修改一个比较老的项目,分公司这边没有这个项目数据库相关的备份,所以需要从正式环境上面导出数据库备份出来在本地进行部署安装,之前在其它项目的时候也弄过这个数据库的部署和安装,也写了 ...

  5. PL/SQL Developer导入导出Oracle数据库方法

    前一篇博客介绍了Navicat工具备份Oracle的方法.这篇博客介绍一下使用PL/SQL Developer工具导入导出Oracle数据库的方法. PL/SQL Developer是Oracle数据 ...

  6. java使用户EasyExcel导入导出excel

    使用alibab的EasyExce完成导入导出excel 一.准备工作 1.导包 <!-- poi 相关--> <dependency> <groupId>org. ...

  7. SpringCloud微服务实战——搭建企业级开发框架(三十):整合EasyExcel实现数据表格导入导出功能

      批量上传数据导入.数据统计分析导出,已经基本是系统必不可缺的一项功能,这里从性能和易用性方面考虑,集成EasyExcel.EasyExcel是一个基于Java的简单.省内存的读写Excel的开源项 ...

  8. .Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) 通过MVC控制器导出导入Excel文件(可用于java SSH架构)

    .Net MVC  导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) [原文地址] 通过MVC控制器导出导入Excel文件(可用于java SSH架构)   public cl ...

  9. Sqoop -- 用于Hadoop与关系数据库间数据导入导出工作的工具

    Sqoop是一款开源的工具,主要用于在Hadoop相关存储(HDFS.Hive.HBase)与传统关系数据库(MySql.Oracle等)间进行数据传递工作.Sqoop最早是作为Hadoop的一个第三 ...

随机推荐

  1. 阿里云yii2 composer update 很慢的解决办法

    先执行如下语句 composer global require "fxp/composer-asset-plugin:dev-master" 再执行 composer update

  2. nginx 80 下的一个路径 到 8888

    # For more information on configuration, see:# * Official English Documentation: http://nginx.org/en ...

  3. hadoop 参数调优重点参数

    yarn的参数调优,必调参数 28>.yarn.nodemanager.resource.memory-mb  默认为8192.每个节点可分配多少物理内存给YARN使用,考虑到节点上还 可能有其 ...

  4. Leetcode: Campus Bikes II

    On a campus represented as a 2D grid, there are N workers and M bikes, with N <= M. Each worker a ...

  5. Dart抽象类和多态

    /* Dart中抽象类: Dart抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口. 1.抽象类通过abstract 关键字来定义 2.Dart中的抽象方法不能用abstract声明, ...

  6. Java8的时间日期API

    原先的时间 api  大部分已经过时了 Date构造器 需要传入年月日  但是对时间的加减操作比较麻烦 Calenda  加减比较方便 使用 LocalDate. LocalTime. LocalDa ...

  7. 【444】Data Analysis (shp, arcpy)

      ABS suburbs data of AUS 1. Dissolve Merge polygons with the same attribute of "SA2_NAME16&quo ...

  8. Linux的桌面虚拟化技术KVM(五)——virsh常用命令

    Linux的桌面虚拟化技术KVM(一)——新建KVM虚拟机 Linux的桌面虚拟化技术KVM(二)——远程桌面管理 Linux的桌面虚拟化技术KVM(三)——KVM虚拟机克隆和快照 Linux的桌面虚 ...

  9. layui select渲染获取选中的option

    关键代码如下: form.on('select(groupCode)', function(data){ console.log($(data.elem).find("option:sele ...

  10. sqoop import mysql to hive table:GC overhead limit exceeded

    1. Scenario description when I use sqoop to import mysql table into hive, I got the following error: ...