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的一个第三 ...
随机推荐
- gogs 实现webhook钩子(php接口形式)
1.概要流程 2.准备工作 gogs服务器 linux网站服务器(宝塔) 本地客户端 3.编写钩子访问的接口 在public下新建githook.php文件,代码如下: <?php $cmd = ...
- qemu通过控制台向虚拟机输入组合键
ctrl+alt+2 开启控制台 ctrl+alt+1 关闭控制台 在控制台中输入 sendkey ctrl-alt-delete 发送指令
- centos7搭建maven私服
Linux:CentOS7安装maven私服Nexus https://blog.csdn.net/plei_yue/article/details/78616267 搭建nexus3版的maven私 ...
- openresty开发系列27--openresty中封装redis操作
openresty开发系列27--openresty中封装redis操作 在关于web+lua+openresty开发中,项目中会大量操作redis, 重复创建连接-->数据操作-->关闭 ...
- C++类成员存储大小
1.对象分布图 2.解析 每个类的大小只有其成员变量大小,其中包括:类成员属性,虚函数指针: 而其他没有如:静态变量[静态区],普通函数.静态函数[代码区] 3.总结 类对象的sizeof只包含成员变 ...
- 基于Broadcast 状态的Flink Etl Demo
接上文: [翻译]The Broadcast State Pattern(广播状态) 最近尝试了一下Flink 的 Broadcase 功能,在Etl,流表关联场景非常适用:一个流数据量大,一个流数据 ...
- delphi中我用定时器每隔一段时间执行操作
delphi中,我用定时器每隔一段时间执行数据库插入及更新工作!adoquery.close;adoquery.sql.cleare;adoquery.connection:=con1;adoquer ...
- 一份 Tomcat 和 JVM 的性能调优经验总结!拿走不谢
Tomcat性能调优 找到Tomcat根目录下的conf目录,修改server.xml文件的内容.对于这部分的调优,我所了解到的就是无非设置一下Tomcat服务器的最大并发数和Tomcat初始化时创建 ...
- CompletableFuture Quasar 等并发编程
CompletableFuture基本用法 https://www.cnblogs.com/cjsblog/p/9267163.html Quasar https://blog.csdn.net/ma ...
- docker 之网络配置
Docker 网络实现 首先,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)来收发数据包:此外,如果不同子网之间要进行通信,需要路由机制. Docker 中的网络接口默认都是虚拟的接口 ...