全文对比-导出

This commit is contained in:
纪晓慧
2024-03-07 16:49:05 +08:00
parent e559e3d6e0
commit d1c793a9a2
3 changed files with 317 additions and 12 deletions
@@ -1,14 +1,17 @@
package com.jero.modules.compare.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.utils.IOUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jero.common.constant.enums.LanguageEnum;
import com.jero.common.exception.JeroBootException;
import com.jero.common.system.vo.LoginUser;
import com.jero.common.util.MessageUtils;
import com.jero.common.util.MinioUtil;
import com.jero.common.util.UUIDUtils;
import com.jero.modules.compare.entity.*;
import com.jero.modules.compare.enums.AssessConsistencyEnum;
import com.jero.modules.compare.enums.CompareTypeEnum;
import com.jero.modules.compare.enums.ReleaseConditionEnum;
import com.jero.modules.compare.mapper.SarFileCompareInfoMapper;
@@ -16,10 +19,7 @@ import com.jero.modules.compare.service.ISarFileCompareInfoService;
import com.jero.modules.compare.service.ISarFileCompareItemService;
import com.jero.modules.compare.service.ISarFileCompareMenuService;
import com.jero.modules.compare.service.ISarItemsCompareHisEOService;
import com.jero.modules.compare.utils.CompHanLPUtils;
import com.jero.modules.compare.utils.CompareConst;
import com.jero.modules.compare.utils.EventEditHistoryHighLightUtil;
import com.jero.modules.compare.utils.HtmlTextExcel;
import com.jero.modules.compare.utils.*;
import com.jero.modules.document.service.IBussDocumentLibraryEOService;
import com.jero.modules.split.common.ReadExcel;
import com.jero.modules.split.entity.SarFileSplitInfoEO;
@@ -33,12 +33,15 @@ import com.jero.modules.split.service.ISarFileSplitItemsValEOService;
import com.jero.modules.split.service.ISarFileSplitMenuEOService;
import com.jero.modules.sys.entity.LawsEnterpriseStandardLevel;
import com.jero.modules.system.util.MyStringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.jeecgframework.poi.excel.ExcelExportUtil;
@@ -48,11 +51,17 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -63,6 +72,7 @@ import java.util.stream.Collectors;
* @Version: V1.0
*/
@Service
@Slf4j
public class SarFileCompareInfoServiceImpl extends ServiceImpl<SarFileCompareInfoMapper, SarFileCompareInfo> implements ISarFileCompareInfoService {
@Autowired
@@ -570,7 +580,12 @@ public class SarFileCompareInfoServiceImpl extends ServiceImpl<SarFileCompareInf
List<SarFileCompareItem> leftData = itemMap.get(CompareConst.POS_LEFT);
if (CollectionUtils.isNotEmpty(leftData)) {
//记录需要合并的单元格
List<SarFileCompareExcelMergeCell> mergeCells = new ArrayList<>();
for (int rowNum = 0; rowNum < leftData.size(); rowNum++) {
SarFileCompareExcelMergeCell sarFileCompareExcelMergeCell = new SarFileCompareExcelMergeCell();
SarFileCompareItem sarFileCompareItem = leftData.get(rowNum);
HSSFRow row1 = sheetItemsLeft.createRow(rowNum + 1);
@@ -581,7 +596,7 @@ public class SarFileCompareInfoServiceImpl extends ServiceImpl<SarFileCompareInf
String itemText = sarFileCompareItem.getItemsText();
List<MarkTextVO> addList = new ArrayList<>();
List<MarkTextVO> delList = new ArrayList<>();
itemText = HtmlTextExcel.changeHtmlToExcel(itemText,addList,delList);
itemText = HtmlTextExcel.changeHtmlToExcel(sheetItemsLeft,workbook,request,itemText,addList,delList);
HSSFRichTextString ts= new HSSFRichTextString(itemText);
if (addList != null && !addList.isEmpty()) {
for (MarkTextVO markTextVO : addList) {
@@ -602,6 +617,44 @@ public class SarFileCompareInfoServiceImpl extends ServiceImpl<SarFileCompareInf
row1.getCell(3).setCellStyle(cellStyleBase);
row1.createCell(4).setCellValue(sarFileCompareItem.getRemark());
}
if (ObjectUtils.isNotEmpty(mergeCells)) {
log.info("-------------- 开始处理需要合并的单元格 -----------------");
Set<SarFileCompareExcelMergeCell> mergeCellSet = new HashSet<>(mergeCells);
for (SarFileCompareExcelMergeCell mergeCell : mergeCellSet) {
Integer leftCount = 0;
if (ObjectUtils.isNotEmpty(mergeCell.getLeftEnd())&&ObjectUtils.isNotEmpty(mergeCell.getLeftStart())) {
leftCount = mergeCell.getLeftEnd() - mergeCell.getLeftStart() + 1;
}
Integer rightCount = 0;
if (ObjectUtils.isNotEmpty(mergeCell.getRightEnd())&&ObjectUtils.isNotEmpty(mergeCell.getRightStart())) {
rightCount = mergeCell.getRightEnd() - mergeCell.getRightStart() + 1;
}
Integer start = leftCount - rightCount >= 0 ? mergeCell.getLeftStart() : mergeCell.getRightStart();
log.info("-------------- 合并开始行数:" + start + " -----------------");
Integer end = leftCount - rightCount >= 0 ? mergeCell.getLeftEnd() : mergeCell.getRightEnd();
log.info("-------------- 合并结束行数: " + end + " -----------------");
//合并
if (ObjectUtils.isNotEmpty(start)&&ObjectUtils.isNotEmpty(end)) {
CellRangeAddress region0 = new CellRangeAddress(start, end, 0, 0);
sheetItemsLeft.addMergedRegion(region0);
CellRangeAddress region1 = new CellRangeAddress(start, end, 1, 1);
sheetItemsLeft.addMergedRegion(region1);
CellRangeAddress region2 = new CellRangeAddress(start, end, 2, 2);
sheetItemsLeft.addMergedRegion(region2);
CellRangeAddress region4 = new CellRangeAddress(start, end, 4, 4);
sheetItemsLeft.addMergedRegion(region4);
CellRangeAddress region5 = new CellRangeAddress(start, end, 5, 5);
sheetItemsLeft.addMergedRegion(region5);
CellRangeAddress region6 = new CellRangeAddress(start, end, 6, 6);
sheetItemsLeft.addMergedRegion(region6);
CellRangeAddress region7 = new CellRangeAddress(start, end, 8, 8);
sheetItemsLeft.addMergedRegion(region7);
}
}
log.info("-------------- 单元格合并成功 -----------------");
}
}
List<SarFileCompareItem> rightData = itemMap.get(CompareConst.POS_RIGHT);
@@ -617,7 +670,7 @@ public class SarFileCompareInfoServiceImpl extends ServiceImpl<SarFileCompareInf
String itemText = sarFileCompareItem.getItemsText();
List<MarkTextVO> addList = new ArrayList<>();
List<MarkTextVO> delList = new ArrayList<>();
itemText = HtmlTextExcel.changeHtmlToExcel(itemText,addList,delList);
itemText = HtmlTextExcel.changeHtmlToExcel(sheetItemsRight,workbook,request,itemText,addList,delList);
HSSFRichTextString ts= new HSSFRichTextString(itemText);
if (addList != null && !addList.isEmpty()) {
for (MarkTextVO markTextVO : addList) {
@@ -250,7 +250,7 @@ public class SarFileCompareItemCommentServiceImpl extends ServiceImpl<SarFileCom
}
}
queryWrapper.orderBy(true, true, SarFileCompareItemComment::getCreateTime);
list = this.list(queryWrapper);
list = this.list(null);
}
Map<String, SarFileCompareItem> sfcItemMap = SarFileCompareItemServiceImpl.queryMapByInfoId(infoId);
@@ -1,13 +1,40 @@
package com.jero.modules.compare.utils;
import com.jero.common.util.MinioUtil;
import com.jero.modules.compare.entity.MarkTextVO;
import com.jero.modules.compare.entity.SarFileCompareExcelMergeCell;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Slf4j
public class HtmlTextExcel {
public static String changeHtmlToExcel (String itemContent, List<MarkTextVO> addList, List<MarkTextVO> delList) {
public static String changeHtmlToExcel (HSSFSheet sheetItemsLeft,HSSFWorkbook wb, HttpServletRequest request, String itemContent, List<MarkTextVO> addList, List<MarkTextVO> delList) {
//超链接样式
Workbook workbook = new HSSFWorkbook();
CellStyle cellStyleLink =workbook.createCellStyle();
HSSFFont font = ((HSSFWorkbook) workbook).createFont();
font.setColor(HSSFColor.HSSFColorPredefined.LIGHT_BLUE.getIndex());
cellStyleLink.setFont(font);
cellStyleLink.setWrapText(true);
if (StringUtils.isNotEmpty(itemContent)) {
itemContent = itemContent.replaceAll("<div>","");
itemContent = itemContent.replaceAll("<div class=\"compareBackgroundColor\">","");
@@ -58,7 +85,232 @@ public class HtmlTextExcel {
itemContent = itemContent.replaceAll("</span>","");
itemContent = itemContent.replaceAll("<span class=\"delClass\">","");
itemContent = itemContent.replaceAll("</span>","");
String rowDataAndPath = getSplitContent(request, itemContent);
// String dir = filePath + File.separator + UUID.randomUUID().toString().replace("-", "");
String sheetName = "对比结果";
Sheet sheet = workbook.createSheet(sheetName);
HSSFPatriarch patriarch = (HSSFPatriarch) sheet.createDrawingPatriarch();
String[] leftSplit = null;
leftSplit = rowDataAndPath.split("---");
int i = 1;
Row row = sheet.createRow(i);
if (leftSplit.length > 1) {
for (int j = 0; j < leftSplit.length; j++) {
if (ObjectUtils.isNotEmpty(leftSplit[j])) {
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
if (j > 0) {
Row row2 = sheet.getRow(j );
if (ObjectUtils.isEmpty(row2)) {
row2 = sheet.createRow(j);
}
log.info("-------------- 开始开始处理左侧图片、表格 -----------------");
try {
handleSpecificData(wb, patriarch, cellStyleLink, byteArrayOut, row2, i, j, leftSplit[j], 3);
} catch (IOException e) {
e.printStackTrace();
}
log.info("-------------- 左侧图片、表格 处理成功 -----------------");
} else {
log.info("-------------- 开始开始处理左侧图片、表格 -----------------");
try {
handleSpecificData(wb, patriarch, cellStyleLink, byteArrayOut, row, i, j, leftSplit[j], 3);
} catch (IOException e) {
e.printStackTrace();
}
log.info("-------------- 左侧图片、表格 处理成功 -----------------");
}
}
}
List<SarFileCompareExcelMergeCell> mergeCells = new ArrayList<>();
SarFileCompareExcelMergeCell sarFileCompareExcelMergeCell = new SarFileCompareExcelMergeCell();
sarFileCompareExcelMergeCell.setLeftStart(i);
sarFileCompareExcelMergeCell.setLeftEnd(i + leftSplit.length - 1);
sarFileCompareExcelMergeCell.setRightStart(0);
sarFileCompareExcelMergeCell.setRightEnd(0);
mergeCells.add(sarFileCompareExcelMergeCell);
}
}
return itemContent;
}
/**
* 处理图片跟表格类型的数据
* @param workbook
* @param patriarch
* @param cellStyleLink
* @param byteArrayOut
* @param row
* @param i
* @param j
* @param text
* @param cellNum
* @throws IOException
*/
private static void handleSpecificData(HSSFWorkbook workbook, HSSFPatriarch patriarch, CellStyle cellStyleLink, ByteArrayOutputStream byteArrayOut, Row row, int i, int j, String text, int cellNum) throws IOException {
if (text.contains("/upFiles")) {
String dir = "dcjd";
row.setHeight((short) 3000); //设置行高
//先将图片下载到本地
log.info("-------------------------将图片下载到本地文件夹中----------------------------");
String fileLastName = text.substring(text.lastIndexOf("/") + 1);
if (MinioUtil.doesObjectExist(text)) {
try (InputStream in = MinioUtil.download(text)) {
copyFile2(in, dir + File.separator + fileLastName);
} catch (IOException e) {
e.printStackTrace();
log.error(e.getMessage(), e);
}
}
File file = new File(dir + File.separator + fileLastName);
log.info("-------------------------图片下载成功:"+ file.getAbsolutePath() +"----------------------------");
if (file.exists()) {
log.info("-------------------------将图片插入excel指定单元格中----------------------------");
BufferedImage bufferImg = ImageIO.read(file);
//获取文件后缀
String fileName = file.getName();
String formatName = fileName.substring(fileName.lastIndexOf(".") + 1);
//如果是jpg或者是jpeg,需要重画一下,否则会变色
if (formatName.equalsIgnoreCase("jpg") || formatName.equalsIgnoreCase("jpeg")) { //重画一下,要么会变色
BufferedImage tag;
tag = new BufferedImage(bufferImg.getWidth(), bufferImg.getHeight(), BufferedImage.TYPE_INT_BGR);
Graphics g = tag.getGraphics();
g.drawImage(bufferImg, 0, 0, null); // 绘制缩小后的图
g.dispose();
bufferImg = tag;
}
ImageIO.write(bufferImg, formatName, byteArrayOut);
//anchor主要用于设置图片的属性
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 600, 200, (short) cellNum, j + i, (short) cellNum, j + i);
patriarch.createPicture(anchor, workbook.addPicture(byteArrayOut.toByteArray(), HSSFWorkbook.PICTURE_TYPE_JPEG));
log.info("-------------------------将图片插入成功----------------------------");
}
} else {
Cell cell = row.createCell(cellNum);
if (text.contains("<table")) {
log.info("-------------------------开始处理表格----------------------------");
tableAssociate(workbook, cellStyleLink, cell, text);
log.info("-------------------------表格处理完毕----------------------------");
} else {
cell.setCellValue(text);
}
}
}
public static void copyFile2(InputStream in, String destPath) throws IOException {
BufferedInputStream bis = new BufferedInputStream(in);
BufferedOutputStream bos =
new BufferedOutputStream(Files.newOutputStream(Paths.get(destPath),
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE));
// 打开输入流
// FileInputStream fis = new FileInputStream(srcPath);
// 打开输出流
// FileOutputStream fos = new FileOutputStream(destPath);
// 读取和写入信息
byte[] bytes = new byte[1024 * 1024];
int len;
while ((len = bis.read(bytes)) > 0) {
bos.write(bytes, 0, len);
}
// 关闭流 先开后关 后开先关
// 先开后关,先开的输入流,再开的输出流,那么应该先关输出流,再关输入流
// 先关外层,再关内层。如BufferedInputStream包装了一个FileInputStream,那么先关BufferedInputStream,再关FileInputStream。
bos.close(); // 后开先关
bis.close(); // 先开后关
}
/**
* 当前excel中新开sheet生成表格,并在指定单元格用超链接关联
* @param workbook
* @param cellStyleLink
* @param cell
* @param tableHtml
*/
private static void tableAssociate(Workbook workbook, CellStyle cellStyleLink, Cell cell, String tableHtml) {
cell.setCellValue("点击查看详情");
//新开sheet生成表格
log.info("-------------------------开始生成表格----------------------------");
if (org.apache.commons.lang3.StringUtils.isNotEmpty(tableHtml) && tableHtml.indexOf("<tbody>") < 0) {
if (tableHtml.indexOf("<thead>") < 0) {
tableHtml = tableHtml.replaceFirst("<tr>", "<tbody><tr>");
tableHtml = tableHtml.replaceFirst("</table>", "</tbody></table>");
} else {
tableHtml = tableHtml.replaceFirst("</thead>", "</thead><tbody>");
tableHtml = tableHtml.replaceFirst("</table>", "</tbody></table>");
}
}
String cnt = "\n";
tableHtml = tableHtml.replaceAll("<[\\s]*?br[^>]*?>|<[\\s]*?\\/[\\s]*?br[\\s]*?>", cnt);
String tableSheetName = "表格" + System.currentTimeMillis();
ConvertHtml2Excel.table2Excel(tableHtml, (HSSFWorkbook) workbook, tableSheetName);
log.info("-------------------------表格生产完毕----------------------------");
//添加超链接
log.info("-------------------------开始添加超链接---------------------------");
CreationHelper createHelper = workbook.getCreationHelper();
Hyperlink hyperlink1 = createHelper.createHyperlink(HyperlinkType.DOCUMENT);
String tableName = "#\'" + tableSheetName + "\'!A1";
hyperlink1.setAddress(tableName);
cell.setHyperlink(hyperlink1);// 链接
cell.setCellStyle(cellStyleLink);
log.info("-------------------------超链接添加完毕---------------------------");
}
/**
* 获取文字、图片、表格分割后的内容
* @param request
* @param text
* @return
*/
private static String getSplitContent(HttpServletRequest request, String text) {
text = text.replace("<p>", "").replace("</p>", "\r\n");
//分割图片
log.info("-------------------------开始分割文字与图片---------------------------");
splitImg(text, request.getSession());
log.info("-------------------------文字与图片分割完毕---------------------------");
//分割表格
log.info("-------------------------从剩余文字中开始分割表格---------------------------");
String txtAndImg = (String) request.getSession().getAttribute("txtAndImg");
txtAndImg = txtAndImg.replaceAll("table", "replaceTable");
splitTable(txtAndImg, request.getSession());
log.info("-------------------------表格分割完毕---------------------------");
return (String) request.getSession().getAttribute("textAndTableAndImg");
}
/**
* 分割表格
* @param textAndImg
* @param session
*/
private static void splitTable(String textAndImg,HttpSession session) {
if (textAndImg.contains("<replaceTable")) {
String left = textAndImg.substring(0, textAndImg.indexOf("<replaceTable"));
String right = textAndImg.substring(textAndImg.indexOf("/replaceTable>") + 14);
String table = textAndImg.substring(textAndImg.indexOf("<replaceTable"), textAndImg.indexOf("/replaceTable>")+14);
table = table.replaceAll("replaceTable", "table");
textAndImg = left + "---" + table + "---" + right;
splitTable(textAndImg, session);
} else {
session.setAttribute("textAndTableAndImg", textAndImg);
}
}
/**
* 分割图片
* @param text
* @param session
* @return
*/
private static void splitImg(String text, HttpSession session) {
if (text.contains("<img")) {
String txtLeft = text.substring(0, text.indexOf("<img"));
String txtRight = text.substring(text.indexOf("g\">") + 3);
String img = text.substring(text.indexOf("<img"), text.indexOf("g\">"));
String path = img.substring(img.lastIndexOf("=") + 1)+"g";
text = txtLeft + "---" + path + "---" + txtRight;
splitImg(text, session);
} else {
session.setAttribute("txtAndImg", text);
}
}
}