|
@@ -1,5 +1,6 @@
|
|
package org.springblade.manager.controller;
|
|
package org.springblade.manager.controller;
|
|
|
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
import com.aspose.cells.LoadFormat;
|
|
import com.aspose.cells.LoadFormat;
|
|
import com.aspose.cells.LoadOptions;
|
|
import com.aspose.cells.LoadOptions;
|
|
import com.aspose.cells.SaveFormat;
|
|
import com.aspose.cells.SaveFormat;
|
|
@@ -11,6 +12,7 @@ import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Lists;
|
|
import com.spire.xls.FileFormat;
|
|
import com.spire.xls.FileFormat;
|
|
import com.spire.xls.Worksheet;
|
|
import com.spire.xls.Worksheet;
|
|
|
|
+import com.spire.xls.collections.WorksheetsCollection;
|
|
import io.swagger.annotations.Api;
|
|
import io.swagger.annotations.Api;
|
|
import io.swagger.annotations.ApiImplicitParam;
|
|
import io.swagger.annotations.ApiImplicitParam;
|
|
import io.swagger.annotations.ApiImplicitParams;
|
|
import io.swagger.annotations.ApiImplicitParams;
|
|
@@ -636,6 +638,198 @@ public class WbsTreeContractController extends BladeController {
|
|
return R.data(null, "没有获取到excel中的数据");
|
|
return R.data(null, "没有获取到excel中的数据");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 客户端-导入excel数据到对应元素表中(批量)
|
|
|
|
+ *
|
|
|
|
+ * @author liuyc
|
|
|
|
+ * @date 2023年8月29日
|
|
|
|
+ */
|
|
|
|
+ @PostMapping("/import-excel-list")
|
|
|
|
+ @ApiOperationSupport(order = 14)
|
|
|
|
+ @ApiOperation(value = "客户端-导入excel数据到对应元素表中(批量)", notes = "传入表的pKeyId、excel文件file")
|
|
|
|
+ public R<Map<String, Object>> importExcelList(@RequestParam Long pKeyId,
|
|
|
|
+ @RequestParam Integer classify,
|
|
|
|
+ @RequestParam Integer number,
|
|
|
|
+ @RequestPart MultipartFile file){
|
|
|
|
+ WbsTreeContract byId = wbsTreeContractServiceImpl.getById(pKeyId);
|
|
|
|
+ //查询与当前表及所有复制表
|
|
|
|
+ List<WbsTreeContract> list = wbsTreeContractServiceImpl.list(Wrappers.<WbsTreeContract>lambdaQuery()
|
|
|
|
+ .eq(WbsTreeContract::getPId, byId.getPId())
|
|
|
|
+ .eq(WbsTreeContract::getInitTableName, byId.getInitTableName())
|
|
|
|
+ .in(WbsTreeContract::getTableOwner, byId.getTableOwner())
|
|
|
|
+ .orderByAsc(WbsTreeContract::getSort)
|
|
|
|
+ .orderByAsc(WbsTreeContract::getFullName)
|
|
|
|
+ .orderByAsc(WbsTreeContract::getCreateTime)
|
|
|
|
+ );
|
|
|
|
+ // 查找目标ID的索引
|
|
|
|
+ int targetIndex = -1;
|
|
|
|
+
|
|
|
|
+ //只记录当前这个表及它排序下的表
|
|
|
|
+ for (int i = 0; i < list.size(); i++) {
|
|
|
|
+ if(Objects.equals(pKeyId, list.get(i).getPKeyId())){
|
|
|
|
+ targetIndex = i;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (targetIndex != -1) {
|
|
|
|
+ list = list.subList(targetIndex, list.size());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ArrayList<Map<String, Object>> maps = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //日期格式正则
|
|
|
|
+ String doubleSlashRegex_XG = ".*\\/[^\\/]*\\/.*"; //匹配包含两个斜杠且不相邻的字符串
|
|
|
|
+ String dateFormatRegex_yyyyMdd = "\\d{4}/\\d{1,2}/\\d{1,2}"; //yyyy/M/dd格式
|
|
|
|
+ String dateFormatRegex_yyyyMMdd = "\\d{4}/\\d{2}/\\d{2}"; //yyyy/MM/dd格式
|
|
|
|
+ String dateFormatRegex_chinese = "(\\d{4}年\\d{1,2}月\\d{1,2}日|\\d{4}年\\d{2}月\\d{2}日)"; //“2023年1月1日、2023年01月01日”这两种格式
|
|
|
|
+ SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyy/M/dd");
|
|
|
|
+ SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //创建一个临时html路径
|
|
|
|
+ Long id = SnowFlakeUtil.getId();
|
|
|
|
+ String importExcelFilePath = FileUtils.getSysLocalFileUrl();
|
|
|
|
+ String importExcelTOHtmlPath = importExcelFilePath + "/pdf//" + id + ".html";
|
|
|
|
+
|
|
|
|
+ //解析匹配数据(rul_1为临时文件地址,接口执行后删除,用流读取会导致htmlString_2乱码,只能存储本地后再解析)
|
|
|
|
+ String url_1 = "";
|
|
|
|
+ //文件转workbook
|
|
|
|
+ com.spire.xls.Workbook workbook = null;
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ workbook = new com.spire.xls.Workbook();
|
|
|
|
+ workbook.loadFromHtml(file.getInputStream());
|
|
|
|
+ WorksheetsCollection worksheets = workbook.getWorksheets();
|
|
|
|
+ workbook.saveToFile(importExcelTOHtmlPath, FileFormat.HTML);
|
|
|
|
+ int size = worksheets.size();
|
|
|
|
+ //excel和表数据匹配
|
|
|
|
+ if(size > list.size()){
|
|
|
|
+ size = list.size();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //获取转换成功后的html路径
|
|
|
|
+ url_1 = importExcelTOHtmlPath.split("pdf//")[0];
|
|
|
|
+
|
|
|
|
+ for (int x = 0; x < size; x++) {
|
|
|
|
+ //结果集
|
|
|
|
+ Map<String, Object> stringStringMap = new HashMap<>();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ WbsTreeContract wbsTreeContract = list.get(x);
|
|
|
|
+ stringStringMap.put("pkeyId",wbsTreeContract.getPKeyId());
|
|
|
|
+ stringStringMap.put("nodeId",wbsTreeContract.getPId());
|
|
|
|
+ stringStringMap.put("projectId",wbsTreeContract.getProjectId());
|
|
|
|
+ stringStringMap.put("tabGroupId",wbsTreeContract.getTabGroupId());
|
|
|
|
+ stringStringMap.put("contractId",wbsTreeContract.getContractId());
|
|
|
|
+ stringStringMap.put("classify",classify);
|
|
|
|
+ stringStringMap.put("isCollapseLoad",true);
|
|
|
|
+ stringStringMap.put("isRenderForm",true);
|
|
|
|
+ //获取当前表htmlString
|
|
|
|
+ String htmlString_1 = wbsTreeContractServiceImpl.getHtmlString(String.valueOf(wbsTreeContract.getPKeyId()));
|
|
|
|
+
|
|
|
|
+ Worksheet sheet = worksheets.get(x);
|
|
|
|
+ String excelToHtmlFileUrl = url_1 + "/pdf/" + id + "_files/" + sheet.getName() + ".html";
|
|
|
|
+ String htmlString_2 = IoUtil.readToString(new FileInputStream(ResourceUtil.getFile(excelToHtmlFileUrl)));
|
|
|
|
+ //循环遍历解析两张html的tr、td
|
|
|
|
+ Document doc_1 = Jsoup.parse(htmlString_1); //合同段表的html
|
|
|
|
+ Document doc_2 = Jsoup.parse(htmlString_2); //导入excel转换的html
|
|
|
|
+ Elements trElements1 = doc_1.select("table tbody tr");
|
|
|
|
+ Elements trElements2 = doc_2.select("table tbody tr");
|
|
|
|
+ for (int i = 0; i < trElements1.size(); i++) {
|
|
|
|
+ Element tr1 = trElements1.get(i);
|
|
|
|
+ Element tr2 = trElements2.get(i);
|
|
|
|
+ Elements tdElements1 = tr1.select("td");
|
|
|
|
+ Elements tdElements2 = tr2.select("td");
|
|
|
|
+ for (int j = 0; j < tdElements1.size(); j++) {
|
|
|
|
+ Element td1 = tdElements1.get(j);
|
|
|
|
+ Element td2 = tdElements2.get(j);
|
|
|
|
+ String keyName = getKeyNameFromChildElement(td1);
|
|
|
|
+ if (StringUtils.isNotEmpty(keyName)) {
|
|
|
|
+ String divValue = td2.text(); //获取文本值
|
|
|
|
+ if (StringUtils.isNotEmpty(divValue)) {
|
|
|
|
+ if (parseDateRange(divValue).size() == 2) {
|
|
|
|
+ //判断范围日期
|
|
|
|
+ List<String> dateArr = parseDateRange(divValue);
|
|
|
|
+ stringStringMap.put(keyName, dateArr);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ //判断是否存在两个斜杠,且不在一起,那么视为日期格式
|
|
|
|
+ Pattern pattern_XG = Pattern.compile(doubleSlashRegex_XG);
|
|
|
|
+ Matcher matcher_XG = pattern_XG.matcher(divValue);
|
|
|
|
+ if (matcher_XG.matches()) {
|
|
|
|
+ //判断日期格式yyyy/M/dd、yyyy/MM/dd
|
|
|
|
+ Pattern pattern_yyyyMdd = Pattern.compile(dateFormatRegex_yyyyMdd);
|
|
|
|
+ Pattern pattern_yyyyMMdd = Pattern.compile(dateFormatRegex_yyyyMMdd);
|
|
|
|
+ Matcher matcher_yyyyMdd = pattern_yyyyMdd.matcher(divValue);
|
|
|
|
+ Matcher matcher_yyyyMMdd = pattern_yyyyMMdd.matcher(divValue);
|
|
|
|
+ if (matcher_yyyyMdd.matches()) {
|
|
|
|
+ Date date = inputDateFormat.parse(divValue);
|
|
|
|
+ divValue = outputDateFormat.format(date);
|
|
|
|
+ } else if (matcher_yyyyMMdd.matches()) {
|
|
|
|
+ Date date = inputDateFormat.parse(divValue);
|
|
|
|
+ divValue = outputDateFormat.format(date);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else if (divValue.contains("年") && divValue.contains("月") && divValue.contains("日")) {
|
|
|
|
+ //判断如:“2023年1月1日、2023年01月01日”这两种格式
|
|
|
|
+ Pattern pattern_chinese = Pattern.compile(dateFormatRegex_chinese);
|
|
|
|
+ Matcher matcher_chinese = pattern_chinese.matcher(divValue);
|
|
|
|
+ if (matcher_chinese.matches()) {
|
|
|
|
+ Date date = outputDateFormat.parse(divValue);
|
|
|
|
+ divValue = outputDateFormat.format(date);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ stringStringMap.put(keyName, divValue);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ maps.add(stringStringMap);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //删除临时文件信息
|
|
|
|
+ if (deleteFolder(Paths.get(importExcelTOHtmlPath))) {
|
|
|
|
+ logger.info("执行方法【importExcel】结束,删除临时文件成功!");
|
|
|
|
+ } else {
|
|
|
|
+ logger.info("执行方法【importExcel】结束,删除临时文件失败!");
|
|
|
|
+ }
|
|
|
|
+ if (StringUtils.isNotEmpty(url_1)) {
|
|
|
|
+ //删除临时文件夹
|
|
|
|
+ if (deleteFolderAndContents(Paths.get(url_1 + "/pdf/" + id + "_files"))) {
|
|
|
|
+ logger.info("执行方法【importExcel】结束,删除临时文件夹成功!");
|
|
|
|
+ } else {
|
|
|
|
+ logger.info("执行方法【importExcel】结束,删除临时文件夹失败!");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ HashMap<String, Object> map1 = new HashMap<>();
|
|
|
|
+ map1.put("orderList",maps);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
|
+ jsonObject.put("dataInfo",map1);
|
|
|
|
+
|
|
|
|
+ //调用保存接口
|
|
|
|
+ excelTabController.saveBussData2(jsonObject,null);
|
|
|
|
+
|
|
|
|
+ return R.data(jsonObject);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
+ } finally {
|
|
|
|
+ if (workbook != null) {
|
|
|
|
+ workbook.dispose();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 判断日期范围格式数据,以下12种格式
|
|
* 判断日期范围格式数据,以下12种格式
|
|
* 2023-01-01-2023-01-30 或 2023-01-01~2023-01-30
|
|
* 2023-01-01-2023-01-30 或 2023-01-01~2023-01-30
|