easyExcel用于导入导出
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用于导入导出的更多相关文章
- 使用Layui、Axios、Springboot(Java) 实现EasyExcel的导入导出(浏览器下载)
实现EasyExcel的导入导出(浏览器下载) 实现三个按钮的功能,但是却花费了一天的时间包括总结. 使用到的技术:springboot layui axios EasyExcel mybatis-p ...
- 使用VUE+SpringBoot+EasyExcel 整合导入导出数据
使用VUE+SpringBoot+EasyExcel 整合导入导出数据 创建一个普通的maven项目即可 项目目录结构 1 前端 存放在resources/static 下 index.html &l ...
- PL/SQLDeveloper导入导出Oracle数据库方法
前一篇博客介绍了Navicat工具备份Oracle的方法,这篇博客介绍一下使用PL/SQL Developer工具导入导出Oracle数据库的方法. PL/SQL Developer是Oracle数据 ...
- 分享一次Oracle数据导入导出经历
最近工作上有一个任务要修改一个比较老的项目,分公司这边没有这个项目数据库相关的备份,所以需要从正式环境上面导出数据库备份出来在本地进行部署安装,之前在其它项目的时候也弄过这个数据库的部署和安装,也写了 ...
- PL/SQL Developer导入导出Oracle数据库方法
前一篇博客介绍了Navicat工具备份Oracle的方法.这篇博客介绍一下使用PL/SQL Developer工具导入导出Oracle数据库的方法. PL/SQL Developer是Oracle数据 ...
- java使用户EasyExcel导入导出excel
使用alibab的EasyExce完成导入导出excel 一.准备工作 1.导包 <!-- poi 相关--> <dependency> <groupId>org. ...
- SpringCloud微服务实战——搭建企业级开发框架(三十):整合EasyExcel实现数据表格导入导出功能
批量上传数据导入.数据统计分析导出,已经基本是系统必不可缺的一项功能,这里从性能和易用性方面考虑,集成EasyExcel.EasyExcel是一个基于Java的简单.省内存的读写Excel的开源项 ...
- .Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) 通过MVC控制器导出导入Excel文件(可用于java SSH架构)
.Net MVC 导入导出Excel总结(三种导出Excel方法,一种导入Excel方法) [原文地址] 通过MVC控制器导出导入Excel文件(可用于java SSH架构) public cl ...
- Sqoop -- 用于Hadoop与关系数据库间数据导入导出工作的工具
Sqoop是一款开源的工具,主要用于在Hadoop相关存储(HDFS.Hive.HBase)与传统关系数据库(MySql.Oracle等)间进行数据传递工作.Sqoop最早是作为Hadoop的一个第三 ...
随机推荐
- 微信小程序开发者工具详解
一.微信小程序web开发工具下载地址 1.1 在微信公众平台-小程序里边去下载开发工具下载地址. 1.2 下载后安装一下就可以使用了: 二.创建项目 2.1 微信小程序web开发工具需要扫码登陆,所以 ...
- etcd常用命令记录
etcd常用命令记录 1.查看etcd的版本 [root@etcd01 ssl]# curl -L http://127.0.0.1:2379/version {"etcdserver& ...
- GridLayout: GridLayout使用简介(转)
Android 布局之GridLayout 1 GridLayout简介 GridLayout是Android4.0新提供的网格矩阵形式的布局控件. GridLayout的继承关系如下:java.la ...
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第7节 SpringBoot常用Starter介绍和整合模板引擎Freemaker、thymeleaf_28..SpringBoot Starter讲解
笔记 1.SpringBoot Starter讲解 简介:介绍什么是SpringBoot Starter和主要作用 1.官网地址:https://docs.spring.io/spring-b ...
- nginx报警:nginx: [warn] could not build optimal server_names_hash, you should increase either server_names_hash_max_size: 512 or server_names_hash_bucket_size: 64; ignoring server_names_hash_bucket_size
date: 2019-08-12 16:33:05 author: headsen chen notice :个人原创 告警现象: 解决办法:在http的部分添加hash缓冲值 测试:如下图, ...
- VsCode写Python代码!这代码简直和大神一样规范!太漂亮了!
VsCode写Python代码!这代码简直和大神一样规范!太漂亮了! 转 https://www.jianshu.com/p/636306763d89 VsCode虽然没有Pycharm的功能齐 ...
- Fiddler抓包显示请求时延
两种方式:配置和加代码.配置只是将隐藏的时延字段显现了出来,格式没法改:加代码就随你写了,格式自己说了算. 先说配置的,在左边框顶部字段名称右击鼠标 -> 点击Customize colums. ...
- 123457123456#1#----com.tym.DishuGame78--前拼后广--宝宝打地鼠_tym
com.tym.DishuGame78--前拼后广--宝宝打地鼠_tym
- 【serviceaccount 和 clusterrolebinding】
kubectl get clusterrolebinding kubectl create clusterrolebinding suosheng-rebinding --clusterrole=cl ...
- IIS7(Windows7)下最简单最强安装多版本PHP支持环境
最近调试程序,要在PHP5.2和5.3之间换来换去,而习惯了windows下的开发,就琢磨怎么在iis下安装多版本支持,赫然发现其实微软都为我们准备了好工具. 微软对PHP的支持越来越强,这点在IIS ...