Просмотр исходного кода

开票预设—导入调整,拦截重复数据

ZhangWenQiang 3 лет назад
Родитель
Сommit
31c971a312

+ 1 - 1
happy-cloud-wisdom/happy-cloud-wisdom-biz/src/main/java/org/jeecg/modules/hlwinvoice/controller/HlwInvoiceCategoryController.java

@@ -220,7 +220,7 @@ public class HlwInvoiceCategoryController extends JeecgController<HlwInvoiceCate
             try {
                 getLock = redissonLockClient.tryLock(lockName, 0, 60);
                 if (getLock) {
-                    result = hlwInvoiceCategoryService.importExcelGeneral(file);
+                    result = hlwInvoiceCategoryService.importExcel(file);
                     return result;
                 } else {
                     return Result.error("排队中,请稍后重试!");

+ 2 - 0
happy-cloud-wisdom/happy-cloud-wisdom-biz/src/main/java/org/jeecg/modules/hlwinvoice/service/IHlwInvoiceCategoryService.java

@@ -20,4 +20,6 @@ public interface IHlwInvoiceCategoryService extends IService<HlwInvoiceCategory>
     Page<HlwInvoiceCategory> pageList(Page<HlwInvoiceCategory> page, HlwInvoiceCategory hlwInvoiceCategory, QueryWrapper<HlwInvoiceCategory> queryWrapper);
 
     Result<?> importExcelGeneral(MultipartFile file) throws IOException;
+
+    Result<?> importExcel(MultipartFile file) throws IOException;
 }

+ 179 - 3
happy-cloud-wisdom/happy-cloud-wisdom-biz/src/main/java/org/jeecg/modules/hlwinvoice/service/impl/HlwInvoiceCategoryServiceImpl.java

@@ -1,21 +1,34 @@
 package org.jeecg.modules.hlwinvoice.service.impl;
 
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.exception.ExcelAnalysisException;
+import com.alibaba.excel.exception.ExcelDataConvertException;
+import com.alibaba.excel.metadata.data.ReadCellData;
+import com.alibaba.excel.read.listener.ReadListener;
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.modules.hlwinvoice.entity.HlwInvoiceCategory;
 import org.jeecg.modules.hlwinvoice.mapper.HlwInvoiceCategoryMapper;
 import org.jeecg.modules.hlwinvoice.service.IHlwInvoiceCategoryService;
 import org.jeecg.modules.utils.excel.ExcelUtil;
 import org.jeecg.modules.utils.excel.ImportDataListener;
+import org.jeecg.modules.utils.excel.validation.group.ExcelImport;
 import org.springframework.stereotype.Service;
-
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
 import java.io.IOException;
-import java.util.List;
+import java.text.MessageFormat;
+import java.util.*;
 
 /**
  * @Description: hlw_invoice_category
@@ -34,6 +47,169 @@ public class HlwInvoiceCategoryServiceImpl extends ServiceImpl<HlwInvoiceCategor
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result<?> importExcel(MultipartFile file) throws IOException {
+        //获取validator对象
+        final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
+        /**
+         * 头部行数
+         */
+        final Integer headRowNumber = 2;
+        /**
+         * easyexcel监听器,逐行读取excel
+         */
+        EasyExcel.read(file.getInputStream(), HlwInvoiceCategory.class, new ReadListener<HlwInvoiceCategory>() {
+            /**
+             * 临时存储
+             */
+            private List<HlwInvoiceCategory> cachedDataList = new ArrayList<>();
+            /**
+             * 头部信息集合
+             */
+            Map<Integer, ReadCellData<?>> headRowMap = new HashMap<>();
+
+            /**
+             * 这个每一条数据解析都会来调用
+             *
+             * @param hlwInvoiceCategory
+             * @param analysisContext
+             */
+            @Override
+            public void invoke(HlwInvoiceCategory hlwInvoiceCategory, AnalysisContext analysisContext) {
+                log.info("当前行{}", analysisContext.readRowHolder().getRowIndex() + 1);
+                /**
+                 * 解析该行数据
+                 */
+                if (StringUtils.isBlank(hlwInvoiceCategory.getInvoiceCategoryCode())) {
+                    //终止解析
+                    throw new ExcelAnalysisException(MessageFormat.format("您的数据的第{0}行有问题-{1},请检查后再进行导入",
+                            analysisContext.readRowHolder().getRowIndex() + 1, "开票内容代码不能为空"));
+                }
+                if (StringUtils.isBlank(hlwInvoiceCategory.getInvoiceCategoryName())) {
+                    //终止解析
+                    throw new ExcelAnalysisException(MessageFormat.format("您的数据的第{0}行有问题-{1},请检查后再进行导入",
+                            analysisContext.readRowHolder().getRowIndex() + 1, "开票内容不能为空"));
+                }
+                if (StringUtils.isBlank(hlwInvoiceCategory.getTaxCategoryCode())) {
+                    //终止解析
+                    throw new ExcelAnalysisException(MessageFormat.format("您的数据的第{0}行有问题-{1},请检查后再进行导入",
+                            analysisContext.readRowHolder().getRowIndex() + 1, "税收分类代码不能为空"));
+                }
+                if (StringUtils.isBlank(hlwInvoiceCategory.getTaxCategoryName())) {
+                    //终止解析
+                    throw new ExcelAnalysisException(MessageFormat.format("您的数据的第{0}行有问题-{1},请检查后再进行导入",
+                            analysisContext.readRowHolder().getRowIndex() + 1, "税收分类名称不能为空"));
+                }
+                cachedDataList.add(hlwInvoiceCategory);
+            }
+
+            /**
+             * 检查导入数据的完整性
+             *
+             * @param data
+             * @param context
+             */
+            private void checkBean(HlwInvoiceCategory data, AnalysisContext context) {
+                Set<ConstraintViolation<HlwInvoiceCategory>> set = validator.validate(data, ExcelImport.class);
+                if (set != null && !set.isEmpty()) {
+                    StringBuilder stringBuilder = new StringBuilder();
+                    set.forEach(item -> {
+                        stringBuilder.append(item.getMessage());
+                        stringBuilder.append(",");
+                        throw new ExcelAnalysisException(MessageFormat.format("您的数据的第{0}行有问题-{1}请检查后再进行导入",
+                                context.readRowHolder().getRowIndex() + 1, stringBuilder.toString()));
+                    });
+                }
+            }
+
+            /**
+             * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行
+             *
+             * @param exception
+             * @param context
+             */
+            @Override
+            public void onException(Exception exception, AnalysisContext context) {
+                log.error("解析失败,但是继续解析下一行:{}", exception.getMessage());
+                // 如果是某一个单元格的转换异常 能获取到具体行号
+                // 如果要获取头的信息 配合invokeHead使用
+                ExcelDataConvertException excelDataConvertException = null;
+                if (exception instanceof ExcelDataConvertException) {
+                    excelDataConvertException = (ExcelDataConvertException) exception;
+                    log.error(MessageFormat.format("您的数据的第{0}行有问题-{1},请检查后再进行导入",
+                            excelDataConvertException.getRowIndex() + 1, headRowMap.get(excelDataConvertException.getColumnIndex()).getStringValue() + "解析异常"));
+                    throw new ExcelAnalysisException(MessageFormat.format("您的数据的第{0}行有问题-{1},请检查后再进行导入",
+                            excelDataConvertException.getRowIndex() + 1, headRowMap.get(excelDataConvertException.getColumnIndex()).getStringValue() + "解析异常"));
+                }
+                throw new ExcelAnalysisException(exception.getMessage());
+            }
+
+            /**
+             * 这里会一行行的返回头
+             *
+             * @param headMap
+             * @param context
+             */
+            @Override
+            public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
+                log.info("解析到第{}行头数据: {}", context.readRowHolder().getRowIndex() + 1, JSON.toJSONString(headMap));
+                headRowMap = headMap;
+            }
+
+            /**
+             * 所有数据解析完成了 会来调用
+             * @param analysisContext
+             */
+            @Override
+            public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+                List<HlwInvoiceCategory> list1 = new ArrayList<HlwInvoiceCategory>();
+                list1.addAll(cachedDataList);
+                Set<HlwInvoiceCategory> set1 = new TreeSet<HlwInvoiceCategory>((hlwInvoiceCategory1, hlwInvoiceCategory2) -> StringUtils.isNotBlank(hlwInvoiceCategory1.getInvoiceCategoryName()) && StringUtils.isNotBlank(hlwInvoiceCategory2.getInvoiceCategoryName()) ? hlwInvoiceCategory1.getInvoiceCategoryName().compareTo(hlwInvoiceCategory2.getInvoiceCategoryName()) : 1);
+                set1.addAll(cachedDataList);
+                list1.removeAll(new ArrayList<>(set1));
+                for (int j = 0; j < cachedDataList.size(); j++) {
+                    //循环找出重复项只报重复错误
+                    if (list1.size() > 0) {
+                        for (int i = 0; i < list1.size(); i++) {
+                            if (cachedDataList.get(j).getInvoiceCategoryName().equals(list1.get(i).getInvoiceCategoryName())) {
+                                throw new ExcelAnalysisException(MessageFormat.format("您的数据的第{0}行有问题-{1},请检查后再进行导入",
+                                        j + headRowNumber + 1, "该行数据开票内容重复"));
+                            }
+                        }
+                    }
+                }
+                saveData();
+            }
+
+            /**
+             * 加上存储数据库
+             */
+            private void saveData() {
+                log.info("{}条数据,开始存储数据库!", cachedDataList.size());
+                //update-begin-author:taoyan date:20190528 for:批量插入数据
+                long start = System.currentTimeMillis();
+                List<HlwInvoiceCategory> newCachedDataList = new ArrayList<>();
+                for (HlwInvoiceCategory hlwInvoiceCategory : cachedDataList) {
+                    QueryWrapper<HlwInvoiceCategory> queryWrapper = new QueryWrapper<>();
+                    queryWrapper.eq("invoice_category_code", hlwInvoiceCategory.getInvoiceCategoryCode());
+                    queryWrapper.eq("invoice_category_name", hlwInvoiceCategory.getInvoiceCategoryName());
+                    int count = baseMapper.selectCount(queryWrapper);
+                    if (count == 0) {
+                        newCachedDataList.add(hlwInvoiceCategory);
+                    }
+                }
+                saveBatch(newCachedDataList);
+                //400条 saveBatch消耗时间1592毫秒  循环插入消耗时间1947毫秒
+                //1200条  saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒
+                log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
+                //update-end-author:taoyan date:20190528 for:批量插入数据
+                log.info("存储数据库成功!");
+            }
+        }).sheet().headRowNumber(headRowNumber).doRead();
+        return Result.ok("文件导入成功!");
+    }
+
+    @Override
     public Result<?> importExcelGeneral(MultipartFile file) throws IOException {
         ExcelUtil.importExcel(file.getInputStream(), HlwInvoiceCategory.class, 2, new ImportDataListener(true) {
             @Override