|
@@ -1,26 +1,50 @@
|
|
package org.springblade.manager.controller;
|
|
package org.springblade.manager.controller;
|
|
|
|
|
|
-import com.alibaba.fastjson.JSON;
|
|
|
|
-import com.alibaba.fastjson.JSONArray;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
+import com.aspose.cells.Worksheet;
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
|
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
|
import io.swagger.annotations.*;
|
|
import io.swagger.annotations.*;
|
|
import lombok.AllArgsConstructor;
|
|
import lombok.AllArgsConstructor;
|
|
|
|
+import org.apache.commons.codec.Charsets;
|
|
import org.apache.commons.lang.StringUtils;
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
|
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
|
+import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
|
+import org.jsoup.Jsoup;
|
|
|
|
+import org.jsoup.nodes.Document;
|
|
|
|
+import org.jsoup.nodes.Element;
|
|
|
|
+import org.jsoup.select.Elements;
|
|
|
|
+import org.jsoup.select.Selector;
|
|
|
|
+import org.springblade.common.utils.CommonUtil;
|
|
import org.springblade.core.boot.ctrl.BladeController;
|
|
import org.springblade.core.boot.ctrl.BladeController;
|
|
|
|
+import org.springblade.core.log.exception.ServiceException;
|
|
import org.springblade.core.tool.api.R;
|
|
import org.springblade.core.tool.api.R;
|
|
|
|
+import org.springblade.core.tool.utils.IoUtil;
|
|
import org.springblade.manager.dto.WbsTreeContractDTO2;
|
|
import org.springblade.manager.dto.WbsTreeContractDTO2;
|
|
import org.springblade.manager.entity.ContractInfo;
|
|
import org.springblade.manager.entity.ContractInfo;
|
|
|
|
+import org.springblade.manager.entity.ExcelTab;
|
|
import org.springblade.manager.entity.WbsTreeContract;
|
|
import org.springblade.manager.entity.WbsTreeContract;
|
|
import org.springblade.manager.feign.ContractClient;
|
|
import org.springblade.manager.feign.ContractClient;
|
|
import org.springblade.manager.service.IWbsTreeContractService;
|
|
import org.springblade.manager.service.IWbsTreeContractService;
|
|
|
|
+import org.springblade.manager.service.impl.WbsTreeContractServiceImpl;
|
|
|
|
+import org.springblade.manager.utils.CssSelectorEscaper;
|
|
|
|
+import org.springblade.manager.utils.ExcelParser;
|
|
import org.springblade.manager.vo.*;
|
|
import org.springblade.manager.vo.*;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
|
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
|
|
|
+import org.springframework.jdbc.core.JdbcTemplate;
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.bind.annotation.*;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
-import java.io.IOException;
|
|
|
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
|
+import java.io.*;
|
|
|
|
+import java.net.URLEncoder;
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
+import java.text.ParseException;
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
@@ -30,10 +54,13 @@ import java.util.stream.Collectors;
|
|
@Api(value = "合同段wbs树", tags = "合同段wbs树接口")
|
|
@Api(value = "合同段wbs树", tags = "合同段wbs树接口")
|
|
public class WbsTreeContractController extends BladeController {
|
|
public class WbsTreeContractController extends BladeController {
|
|
|
|
|
|
- private final IWbsTreeContractService iWbsTreeContractService;
|
|
|
|
- private final ContractClient contractClient;
|
|
|
|
@Autowired
|
|
@Autowired
|
|
StringRedisTemplate redisTemplate;
|
|
StringRedisTemplate redisTemplate;
|
|
|
|
+ private final JdbcTemplate jdbcTemplate;
|
|
|
|
+ private final IWbsTreeContractService iWbsTreeContractService;
|
|
|
|
+ private final WbsTreeContractServiceImpl wbsTreeContractServiceImpl;
|
|
|
|
+ private final ContractClient contractClient;
|
|
|
|
+ private final ExcelTabController excelTabController;
|
|
|
|
|
|
@GetMapping("/search-node-tables")
|
|
@GetMapping("/search-node-tables")
|
|
@ApiOperationSupport(order = 1)
|
|
@ApiOperationSupport(order = 1)
|
|
@@ -207,7 +234,7 @@ public class WbsTreeContractController extends BladeController {
|
|
@ApiImplicitParams(value = {
|
|
@ApiImplicitParams(value = {
|
|
@ApiImplicitParam(name = "pKeyId", value = "节点pKeyId", required = true)
|
|
@ApiImplicitParam(name = "pKeyId", value = "节点pKeyId", required = true)
|
|
})
|
|
})
|
|
- public R<WbsTreeContract> getWbsContractById(@RequestParam("pKeyId") String pKeyId){
|
|
|
|
|
|
+ public R<WbsTreeContract> getWbsContractById(@RequestParam("pKeyId") String pKeyId) {
|
|
WbsTreeContract wbsTreeContract = iWbsTreeContractService.getOne(Wrappers.<WbsTreeContract>query().lambda()
|
|
WbsTreeContract wbsTreeContract = iWbsTreeContractService.getOne(Wrappers.<WbsTreeContract>query().lambda()
|
|
.eq(WbsTreeContract::getPKeyId, pKeyId).eq(WbsTreeContract::getIsDeleted, 0));
|
|
.eq(WbsTreeContract::getPKeyId, pKeyId).eq(WbsTreeContract::getIsDeleted, 0));
|
|
return R.data(wbsTreeContract);
|
|
return R.data(wbsTreeContract);
|
|
@@ -221,4 +248,137 @@ public class WbsTreeContractController extends BladeController {
|
|
return R.data(list);
|
|
return R.data(list);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @GetMapping("/download-excel")
|
|
|
|
+ @ApiOperationSupport(order = 13)
|
|
|
|
+ @ApiOperation(value = "客户端-下载元素表对应的excel模板", notes = "传入表的pKeyId")
|
|
|
|
+ public void downloadExcel(@RequestParam String pKeyId, HttpServletResponse response) throws Exception {
|
|
|
|
+ WbsTreeContract tab = iWbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, pKeyId));
|
|
|
|
+ if (tab != null && Objects.nonNull(tab.getExcelId())) {
|
|
|
|
+ ExcelTab excelTab = jdbcTemplate.queryForObject("select file_url,name from m_excel_tab where id = " + tab.getExcelId(), new BeanPropertyRowMapper<>(ExcelTab.class));
|
|
|
|
+ if (excelTab != null) {
|
|
|
|
+ InputStream ossInputStream = CommonUtil.getOSSInputStream(excelTab.getFileUrl());
|
|
|
|
+ Workbook workbook = parseExcelFile(ossInputStream);
|
|
|
|
+ String fileName = new String(excelTab.getName().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
|
|
|
|
+ response.setContentType("application/vnd.ms-excel");
|
|
|
|
+ response.setCharacterEncoding("UTF-8");
|
|
|
|
+ response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + ".xlsx\"");
|
|
|
|
+ try (OutputStream toClient = new BufferedOutputStream(response.getOutputStream())) {
|
|
|
|
+ workbook.write(toClient);
|
|
|
|
+ toClient.flush();
|
|
|
|
+ } finally {
|
|
|
|
+ workbook.close();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //解析Excel文件并设置单元格格式为文本
|
|
|
|
+ private Workbook parseExcelFile(InputStream inputStream) throws IOException, InvalidFormatException {
|
|
|
|
+ Workbook workbook = WorkbookFactory.create(inputStream);
|
|
|
|
+ DataFormat dataFormat = workbook.createDataFormat();
|
|
|
|
+ //遍历所有工作表和单元格,设置单元格格式为文本
|
|
|
|
+ for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
|
|
|
|
+ Sheet sheet = workbook.getSheetAt(sheetIndex);
|
|
|
|
+ for (Row row : sheet) {
|
|
|
|
+ for (Cell cell : row) {
|
|
|
|
+ CellStyle cellStyle = cell.getCellStyle();
|
|
|
|
+ cellStyle.setDataFormat(dataFormat.getFormat("@")); //设置单元格格式为文本
|
|
|
|
+ cell.setCellStyle(cellStyle);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return workbook;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @PostMapping("/import-excel")
|
|
|
|
+ @ApiOperationSupport(order = 14)
|
|
|
|
+ @ApiOperation(value = "客户端-导入excel数据到对应元素表中", notes = "传入表的pKeyId、excel文件file")
|
|
|
|
+ public R<Map<String, Object>> importExcel(@RequestParam String pKeyId, @RequestPart MultipartFile file) throws Exception {
|
|
|
|
+ //获取当前表htmlString
|
|
|
|
+ String htmlString = wbsTreeContractServiceImpl.getHtmlString(pKeyId);
|
|
|
|
+ if (StringUtils.isEmpty(htmlString)) {
|
|
|
|
+ throw new ServiceException("获取元素表html信息失败");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //获取excel数据
|
|
|
|
+ Map<String, String> stringStringMap = ExcelParser.parseExcel(file);
|
|
|
|
+
|
|
|
|
+ //匹配定位
|
|
|
|
+ Map<String, Object> resultDataMap = new LinkedHashMap<>();
|
|
|
|
+ Document doc = Jsoup.parse(htmlString);
|
|
|
|
+ for (Map.Entry<String, String> stringStringEntry : stringStringMap.entrySet()) {
|
|
|
|
+ String value = stringStringEntry.getValue();
|
|
|
|
+ if (StringUtils.isNotEmpty(value)) {
|
|
|
|
+ String escape = CssSelectorEscaper.escape(value);
|
|
|
|
+ String selectorTitle = "td:containsOwn(" + escape + ")";
|
|
|
|
+ Elements tdElementsTitle = doc.select(selectorTitle);
|
|
|
|
+ //如果找到了匹配的<td>元素,说明是固定的标题,跳过当前循环,只保留填写的excel数据
|
|
|
|
+ if (!tdElementsTitle.isEmpty()) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String[] split = stringStringEntry.getKey().split("_");
|
|
|
|
+ int row = Integer.parseInt(split[0]) + 1;
|
|
|
|
+ int cell = Integer.parseInt(split[1]) + 1;
|
|
|
|
+ String selectorValue = "td:has(el-date-picker[x1=" + cell + "][y1=" + row + "])," +
|
|
|
|
+ "td:has(el-input[x1=" + cell + "][y1=" + row + "])," +
|
|
|
|
+ "td:has(hc-form-select-search[x1=" + cell + "][y1=" + row + "])," +
|
|
|
|
+ "td:has(hc-table-form-upload[x1=" + cell + "][y1=" + row + "])," +
|
|
|
|
+ "td:has(hc-form-checkbox-group[x1=" + cell + "][y1=" + row + "])," +
|
|
|
|
+ "td:has(el-radio-group[x1=" + cell + "][y1=" + row + "])," +
|
|
|
|
+ "td:has(el-select[x1=" + cell + "][y1=" + row + "])";
|
|
|
|
+ Elements tdElementsValues = doc.select(selectorValue);
|
|
|
|
+ if (!tdElementsValues.isEmpty()) {
|
|
|
|
+ Elements childElements = tdElementsValues.select("el-input, el-date-picker, hc-form-select-search, hc-table-form-upload, hc-form-checkbox-group, el-radio-group, el-select");
|
|
|
|
+ for (Element childElement : childElements) {
|
|
|
|
+ String keyName = childElement.attr("keyname");
|
|
|
|
+ if (StringUtils.isNotEmpty(keyName)) {
|
|
|
|
+ //解析日期格式是否是范围格式
|
|
|
|
+ String dateFormatPattern = "yyyy年MM月dd日-yyyy年MM月dd日";
|
|
|
|
+ if (isValidDateFormat(value, dateFormatPattern)) {
|
|
|
|
+ String[] splitDate = value.split("-");
|
|
|
|
+ List<String> strings = Arrays.asList(splitDate[0], splitDate[1]);
|
|
|
|
+ resultDataMap.put(keyName, strings);
|
|
|
|
+ } else {
|
|
|
|
+ resultDataMap.put(keyName, value);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (resultDataMap.size() > 0) {
|
|
|
|
+ List<Map.Entry<String, Object>> entryList = new ArrayList<>(resultDataMap.entrySet());
|
|
|
|
+ entryList.sort(new KeyComparator());
|
|
|
|
+ LinkedHashMap<String, Object> sortedMap = new LinkedHashMap<>();
|
|
|
|
+ for (Map.Entry<String, Object> entry : entryList) {
|
|
|
|
+ sortedMap.put(entry.getKey(), entry.getValue());
|
|
|
|
+ }
|
|
|
|
+ return R.data(sortedMap);
|
|
|
|
+ }
|
|
|
|
+ return R.fail("操作失败");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static boolean isValidDateFormat(String dateString, String formatPattern) {
|
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat(formatPattern);
|
|
|
|
+ sdf.setLenient(false);
|
|
|
|
+ try {
|
|
|
|
+ Date date = sdf.parse(dateString);
|
|
|
|
+ return date != null && sdf.format(date).equals(dateString);
|
|
|
|
+ } catch (ParseException e) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static class KeyComparator implements Comparator<Map.Entry<String, Object>> {
|
|
|
|
+ @Override
|
|
|
|
+ public int compare(Map.Entry<String, Object> entry1, Map.Entry<String, Object> entry2) {
|
|
|
|
+ int num1 = Integer.parseInt(entry1.getKey().split("__")[0].split("_")[1]);
|
|
|
|
+ int num2 = Integer.parseInt(entry2.getKey().split("__")[0].split("_")[1]);
|
|
|
|
+ return Integer.compare(num1, num2);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|