|
@@ -2,27 +2,31 @@ package org.springblade.manager.controller;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
|
|
-import com.spire.xls.FileFormat;
|
|
|
-import com.spire.xls.Worksheet;
|
|
|
+import com.spire.xls.*;
|
|
|
import io.swagger.annotations.*;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
+import lombok.SneakyThrows;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.apache.poi.ss.usermodel.CellStyle;
|
|
|
+import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
+import org.apache.poi.ss.util.RegionUtil;
|
|
|
+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.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
-import org.springblade.common.utils.CommonUtil;
|
|
|
import org.springblade.common.utils.SnowFlakeUtil;
|
|
|
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.utils.IoUtil;
|
|
|
+import org.springblade.core.tool.utils.ObjectUtil;
|
|
|
import org.springblade.core.tool.utils.ResourceUtil;
|
|
|
import org.springblade.manager.dto.WbsTreeContractDTO2;
|
|
|
import org.springblade.manager.entity.ContractInfo;
|
|
|
-import org.springblade.manager.entity.ExcelTab;
|
|
|
import org.springblade.manager.entity.WbsTreeContract;
|
|
|
import org.springblade.manager.feign.ContractClient;
|
|
|
import org.springblade.manager.service.IWbsTreeContractService;
|
|
@@ -32,10 +36,11 @@ import org.springblade.manager.vo.*;
|
|
|
import org.springblade.resource.feign.NewIOSSClient;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
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.multipart.MultipartFile;
|
|
|
+import org.springframework.web.bind.annotation.GetMapping;
|
|
|
+import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
import javax.servlet.ServletOutputStream;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
@@ -46,6 +51,7 @@ import java.nio.file.Path;
|
|
|
import java.nio.file.Paths;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
+import java.util.List;
|
|
|
import java.util.regex.Matcher;
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
@@ -274,71 +280,164 @@ public class WbsTreeContractController extends BladeController {
|
|
|
return R.data(list);
|
|
|
}
|
|
|
|
|
|
+ @SneakyThrows
|
|
|
@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 inputStream = CommonUtil.getOSSInputStream(excelTab.getFileUrl());
|
|
|
- if (inputStream != null) {
|
|
|
- response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
|
|
- response.setCharacterEncoding("UTF-8");
|
|
|
- response.setHeader("Content-disposition", ";filename=" + URLEncoder.encode(excelTab.getName().replace(" ", ""), "UTF-8") + ".xlsx");
|
|
|
- ServletOutputStream servletOutputStream = response.getOutputStream();
|
|
|
- byte[] buffer = new byte[4096];
|
|
|
- int bytesRead;
|
|
|
- while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
|
- servletOutputStream.write(buffer, 0, bytesRead);
|
|
|
+ public void downloadExcel(@RequestParam String pKeyId, HttpServletResponse response) {
|
|
|
+ com.spire.xls.Workbook workbook = null;
|
|
|
+ try {
|
|
|
+ WbsTreeContract tab = iWbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, pKeyId));
|
|
|
+ if (ObjectUtil.isEmpty(tab) || ObjectUtil.isEmpty(tab.getHtmlUrl())) {
|
|
|
+ throw new ServiceException("未获取到对应的表信息");
|
|
|
+ }
|
|
|
+
|
|
|
+ //将html转换为excel
|
|
|
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
|
+ InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(tab.getHtmlUrl());
|
|
|
+ workbook = new com.spire.xls.Workbook();
|
|
|
+ workbook.loadFromHtml(inputStreamByUrl);
|
|
|
+ workbook.saveToStream(byteArrayOutputStream, FileFormat.Version2007);
|
|
|
+ //将转换的spireExcel存储到流中
|
|
|
+ byte[] excelBytes = byteArrayOutputStream.toByteArray();
|
|
|
+
|
|
|
+ //把spireExcel转为poiExcel
|
|
|
+ try (InputStream inputStream = new ByteArrayInputStream(excelBytes)) {
|
|
|
+ org.apache.poi.ss.usermodel.Workbook poiWorkbook = new XSSFWorkbook(inputStream);
|
|
|
+ Sheet poiSheet = poiWorkbook.getSheetAt(0); //获取第一个工作表
|
|
|
+ //存储需要修改的单元格和相关信息的列表
|
|
|
+ List<CellModificationInfo> cellsToModify = new ArrayList<>();
|
|
|
+ for (Row row : poiSheet) {
|
|
|
+ for (Cell cell : row) {
|
|
|
+ int cellType = cell.getCellType();
|
|
|
+ if (cellType == CellType.STRING.getCode() && ObjectUtil.isNotEmpty(cell.getStringCellValue())) {
|
|
|
+ //存储需要修改的单元格信息
|
|
|
+ cellsToModify.add(new CellModificationInfo(cell, cell.getStringCellValue().trim()));
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取单元格所属的合并单元格区域
|
|
|
+ CellRangeAddress mergedRegion = findMergedRegion(poiSheet, cell.getRowIndex(), cell.getColumnIndex());
|
|
|
+ if (mergedRegion != null) {
|
|
|
+ // 存储需要修改的合并单元格信息
|
|
|
+ cellsToModify.add(new CellModificationInfo(cell, mergedRegion));
|
|
|
+ }
|
|
|
}
|
|
|
- servletOutputStream.flush();
|
|
|
- inputStream.close();
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- /*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 inputStream = CommonUtil.getOSSInputStream(excelTab.getFileUrl());
|
|
|
- if (inputStream != null) {
|
|
|
- try (Workbook workbook = parseExcelFile(inputStream)) {
|
|
|
- response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
|
|
- response.setCharacterEncoding("UTF-8");
|
|
|
- response.setHeader("Content-disposition", ";filename=" + URLEncoder.encode(excelTab.getName().replace(" ", ""), "UTF-8") + ".xlsx");
|
|
|
- ServletOutputStream servletOutputStream = response.getOutputStream();
|
|
|
- workbook.write(servletOutputStream);
|
|
|
- servletOutputStream.flush();
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
+ //遍历结束后,实际修改单元格样式和内容
|
|
|
+ for (CellModificationInfo info : cellsToModify) {
|
|
|
+ Cell cell = info.getCell();
|
|
|
+ if (info.hasStringContent()) {
|
|
|
+ cell.setCellValue(info.getStringContent());
|
|
|
}
|
|
|
+
|
|
|
+ //复制单元格样式
|
|
|
+ CellStyle cellStyle = poiWorkbook.createCellStyle();
|
|
|
+ CellStyle sourceCellStyle = cell.getCellStyle(); //获取原单元格的样式
|
|
|
+ cellStyle.cloneStyleFrom(sourceCellStyle); //复制样式
|
|
|
+ setBlackBorder(cellStyle); // 设置边框
|
|
|
+ cell.setCellStyle(cellStyle);
|
|
|
+
|
|
|
+ if (info.hasMergedRegion()) { //修改合并单元格边框线
|
|
|
+ CellRangeAddress mergedRegion = info.getMergedRegion();
|
|
|
+ RegionUtil.setBorderTop(BorderStyle.THIN, mergedRegion, poiSheet);
|
|
|
+ RegionUtil.setTopBorderColor(IndexedColors.BLACK.getIndex(), mergedRegion, poiSheet);
|
|
|
+ RegionUtil.setBorderBottom(BorderStyle.THIN, mergedRegion, poiSheet);
|
|
|
+ RegionUtil.setBottomBorderColor(IndexedColors.BLACK.getIndex(), mergedRegion, poiSheet);
|
|
|
+ RegionUtil.setBorderLeft(BorderStyle.THIN, mergedRegion, poiSheet);
|
|
|
+ RegionUtil.setLeftBorderColor(IndexedColors.BLACK.getIndex(), mergedRegion, poiSheet);
|
|
|
+ RegionUtil.setBorderRight(BorderStyle.THIN, mergedRegion, poiSheet);
|
|
|
+ RegionUtil.setRightBorderColor(IndexedColors.BLACK.getIndex(), mergedRegion, poiSheet);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //返回响应
|
|
|
+ try (ServletOutputStream outputStream = response.getOutputStream();
|
|
|
+ ByteArrayOutputStream byteArrayOutputStreamResult = new ByteArrayOutputStream()) {
|
|
|
+ //设置响应头
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(tab.getFullName(), "UTF-8") + ".xlsx");
|
|
|
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
|
+ poiWorkbook.write(byteArrayOutputStreamResult);
|
|
|
+ byte[] excelBytesResult = byteArrayOutputStreamResult.toByteArray();
|
|
|
+ outputStream.write(excelBytesResult);
|
|
|
+ } catch (IOException e) {
|
|
|
+ logger.error("下载excel时出现异常:" + e.getMessage(), e);
|
|
|
+ e.printStackTrace();
|
|
|
}
|
|
|
+ } catch (IOException e) {
|
|
|
+ logger.error("下载excel时出现异常:" + e.getMessage(), e);
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("下载excel时出现异常:" + e.getMessage(), e);
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ if (workbook != null) {
|
|
|
+ workbook.dispose();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //解析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);
|
|
|
- }
|
|
|
+ //在CellModificationInfo类中,根据需要存储单元格内容和合并单元格信息
|
|
|
+ static class CellModificationInfo {
|
|
|
+ private final Cell cell;
|
|
|
+ private String stringContent;
|
|
|
+ private CellRangeAddress mergedRegion;
|
|
|
+
|
|
|
+ //构造函数,用于存储单元格内容
|
|
|
+ public CellModificationInfo(Cell cell, String stringContent) {
|
|
|
+ this.cell = cell;
|
|
|
+ this.stringContent = stringContent;
|
|
|
+ }
|
|
|
+
|
|
|
+ //构造函数,用于存储合并单元格信息
|
|
|
+ public CellModificationInfo(Cell cell, CellRangeAddress mergedRegion) {
|
|
|
+ this.cell = cell;
|
|
|
+ this.mergedRegion = mergedRegion;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Cell getCell() {
|
|
|
+ return cell;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getStringContent() {
|
|
|
+ return stringContent;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean hasStringContent() {
|
|
|
+ return stringContent != null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public CellRangeAddress getMergedRegion() {
|
|
|
+ return mergedRegion;
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean hasMergedRegion() {
|
|
|
+ return mergedRegion != null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取合并单元格
|
|
|
+ private static CellRangeAddress findMergedRegion(Sheet sheet, int rowNum, int colNum) {
|
|
|
+ for (CellRangeAddress mergedRegion : sheet.getMergedRegions()) {
|
|
|
+ if (mergedRegion.isInRange(rowNum, colNum)) {
|
|
|
+ return mergedRegion;
|
|
|
}
|
|
|
}
|
|
|
- return workbook;
|
|
|
- }*/
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ //设置边框线
|
|
|
+ private static void setBlackBorder(CellStyle cellStyle) {
|
|
|
+ cellStyle.setBorderTop(BorderStyle.THIN);
|
|
|
+ cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
+ cellStyle.setBorderBottom(BorderStyle.THIN);
|
|
|
+ cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
+ cellStyle.setBorderLeft(BorderStyle.THIN);
|
|
|
+ cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
+ cellStyle.setBorderRight(BorderStyle.THIN);
|
|
|
+ cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex());
|
|
|
+ }
|
|
|
|
|
|
@PostMapping("/import-excel")
|
|
|
@ApiOperationSupport(order = 14)
|
|
@@ -393,8 +492,8 @@ public class WbsTreeContractController extends BladeController {
|
|
|
//String x1 = getX1Attribute(td1);
|
|
|
//String y1 = getY1Attribute(td1);
|
|
|
String keyName = getKeyNameFromChildElement(td1);
|
|
|
- if (StringUtils.isNotEmpty(keyName)/*&& StringUtils.isNotEmpty(x1) && StringUtils.isNotEmpty(y1)*/) {
|
|
|
- String divValue = td2.select("div").text();
|
|
|
+ if (StringUtils.isNotEmpty(keyName)) {
|
|
|
+ String divValue = td2.text(); //获取文本值
|
|
|
if (StringUtils.isNotEmpty(divValue)) {
|
|
|
//判断是否存在两个斜杠,且不在一起,那么视为日期格式
|
|
|
Pattern pattern_XG = Pattern.compile(doubleSlashRegex_XG);
|
|
@@ -449,7 +548,7 @@ public class WbsTreeContractController extends BladeController {
|
|
|
}
|
|
|
return R.data(sortedMap);
|
|
|
}
|
|
|
- return R.fail("没有获取到填写的数据");
|
|
|
+ return R.data(null, "没有获取到excel中的数据");
|
|
|
}
|
|
|
|
|
|
private static boolean deleteFolder(Path folderPath) throws IOException {
|