fix: 合同签章支持页眉页脚

This commit is contained in:
zzs 2025-02-28 10:11:06 +08:00
parent 8e3806fdd3
commit eb0d2b24ee

View File

@ -7,18 +7,26 @@ import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import java.awt.*;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.List;
/**
* @Description: 合同盖章
@ -31,11 +39,51 @@ public class ContactSignUtils {
private static final Logger logger = LoggerFactory.getLogger(ContactSignUtils.class);
public static List<CTBookmark> getFileBookMarks(InputStream in) {
List<CTBookmark> list = new ArrayList<>();
List<CTBookmark> bookmarks = new ArrayList<>();
try {
try (XWPFDocument doc = new XWPFDocument(in)) {
for (XWPFParagraph paragraph : doc.getParagraphs()) {
list.addAll(paragraph.getCTP().getBookmarkStartList());
bookmarks.addAll(paragraph.getCTP().getBookmarkStartList());
}
for (XWPFTable table : doc.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph para : cell.getParagraphs()) {
bookmarks.addAll(para.getCTP().getBookmarkStartList());
}
}
}
}
for (XWPFHeader header : doc.getHeaderList()) {
for (XWPFParagraph para : header.getParagraphs()) {
bookmarks.addAll(para.getCTP().getBookmarkStartList());
}
for (XWPFTable table : header.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph para : cell.getParagraphs()) {
bookmarks.addAll(para.getCTP().getBookmarkStartList());
}
}
}
}
}
for (XWPFFooter footer : doc.getFooterList()) {
for (XWPFParagraph para : footer.getParagraphs()) {
bookmarks.addAll(para.getCTP().getBookmarkStartList());
}
for (XWPFTable table : footer.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
for (XWPFParagraph para : cell.getParagraphs()) {
bookmarks.addAll(para.getCTP().getBookmarkStartList());
}
}
}
}
}
} catch (IOException e) {
throw new RuntimeException(e);
@ -43,7 +91,7 @@ public class ContactSignUtils {
}catch (Exception e ){
throw new KDBizException("不支持doc格式的word文档请上传docx格式的word文档!!!");
}
return list;
return bookmarks;
}
/**
@ -61,7 +109,46 @@ public class ContactSignUtils {
byte[] imageBytes = readImageFile(imageFile);
try (XWPFDocument doc = new XWPFDocument(wordFile)) {
for (XWPFParagraph paragraph : doc.getParagraphs()) {
// 收集所有段落
// 1. 正文中的段落
List<XWPFParagraph> allParagraphs = new ArrayList<>(doc.getParagraphs());
// 2. 正文中表格内的段落
for (XWPFTable table : doc.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
allParagraphs.addAll(cell.getParagraphs());
}
}
}
// 3. 页眉中的段落及页眉内表格中的段落
for (XWPFHeader header : doc.getHeaderList()) {
allParagraphs.addAll(header.getParagraphs());
for (XWPFTable table : header.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
allParagraphs.addAll(cell.getParagraphs());
}
}
}
}
// 4. 页脚中的段落及页脚内表格中的段落
for (XWPFFooter footer : doc.getFooterList()) {
allParagraphs.addAll(footer.getParagraphs());
for (XWPFTable table : footer.getTables()) {
for (XWPFTableRow row : table.getRows()) {
for (XWPFTableCell cell : row.getTableCells()) {
allParagraphs.addAll(cell.getParagraphs());
}
}
}
}
// 遍历所有段落查找匹配书签并插入图片
for (XWPFParagraph paragraph : allParagraphs) {
List<CTBookmark> bookmarkStartList = paragraph.getCTP().getBookmarkStartList();
for (CTBookmark bookmark : bookmarkStartList) {
String name = bookmark.getName();
@ -69,26 +156,15 @@ public class ContactSignUtils {
List<XWPFRun> runs = paragraph.getRuns();
XWPFRun run = null;
int idx = 0;
// for (int i = 0; i < runs.size(); i++) {
// String nodeName = runs.get(i).getCTR().getDomNode().getPreviousSibling().getNodeName();
// if ("w:bookmarkEnd".equals(nodeName) && name.equals(runs.get(i).getCTR().getDomNode().getPreviousSibling().getPreviousSibling().getAttributes().getNamedItem("w:name").getNodeValue())) {
// idx = i - 1;
// break;
// }
// }
//当前分词的上一个分词是不是书签的结尾如果是就在上一个分词后面插入图片
// 寻找当前段落中书签结束标记所在的前一个分词
for (int i = 0; i < runs.size(); i++) {
Node previousSibling = runs.get(i).getCTR().getDomNode().getPreviousSibling();
if (previousSibling != null) {
String nodeName = previousSibling.getNodeName();
if ("w:bookmarkEnd".equals(nodeName)) {
Node bookmarkStart = previousSibling.getPreviousSibling();
if (bookmarkStart != null) {
Node nameAttribute = bookmarkStart.getAttributes().getNamedItem("w:name");
Node bookmarkStartNode = previousSibling.getPreviousSibling();
if (bookmarkStartNode != null) {
Node nameAttribute = bookmarkStartNode.getAttributes().getNamedItem("w:name");
if (nameAttribute != null && name.equals(nameAttribute.getNodeValue())) {
idx = i - 1;
break;
@ -102,17 +178,18 @@ public class ContactSignUtils {
} else {
run = paragraph.createRun();
}
// 设置图片大小 长宽比 1.8586387435
// 插入图片设置图片宽度和高度此处单位为EMU
run.addPicture(new ByteArrayInputStream(imageBytes), XWPFDocument.PICTURE_TYPE_PNG, "imageName.png", Units.toEMU(74), Units.toEMU(40));
}
}
}
// 保存文件
FileUtil fileUtil = new FileUtil("sales-order-sign-file");
File outFile = fileUtil.createNewFile(outfileName);
try (FileOutputStream out = new FileOutputStream(outFile)) {
doc.write(out);
}
return outFile;
} catch (InvalidFormatException e) {
throw new KDBizException("无法解析文件 " + outfileName + " 格式:" + e.getMessage());