|
|
@@ -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
|