spire.doc.free将word中占位符替换为pdf文件,以及合并PDF
package org.apache.pdfbox.io;
e-iceblue
spire.doc.free
5.3.2
</dependen
java
/**
* 合并多个 PDF 字节数组为一个 PDF
*
* @param pdfBytesList PDF 文件的字节数组列表
* @return 合并后的 PDF 字节数组
* @throws IOException 如果读取或写入 PDF 失败
*/
public static byte[] mergePdfBytes(List<byte[]> pdfBytesList) throws IOException {
PDFMergerUtility merger = new PDFMergerUtility();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 1. 将所有 byte[] 作为输入源添加到合并器中[reference:3]
for (byte[] pdfByte : pdfBytesList) {
merger.addSource(new ByteArrayInputStream(pdfByte));
}
// 2. 设置合并后的输出流
merger.setDestinationStream(outputStream);
// 3. 执行合并操作
// 使用 setupMainMemoryOnly() 可以避免使用临时文件,适合处理中等大小的文件[reference:7]
merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
// 4. 返回合并后的字节数组
return outputStream.toByteArray();
}
/**
* 替换 Word 模板中的占位符(支持普通文本和 PDF 嵌入)
*
* @param templateBytes 模板文档的字节数组
* @param pdfReplacements PDF 占位符替换映射,key 为占位符(如 "{{pdfReport}}"),value 为 PDF 文件的字节数组
* @param fileFormat 文档格式(如 FileFormat.Docx 或 FileFormat.Doc)
* @return 替换完成后的文档字节数组
* @throws Exception 加载、处理或保存文档时可能抛出的异常
*/
public byte[] replacePlaceholders(byte[] templateBytes,
Map<String, byte[]> pdfReplacements,
FileFormat fileFormat) throws Exception {
// 1. 加载模板文档
com.spire.doc.Document document = new com.spire.doc.Document();
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(templateBytes)) {
document.loadFromStream(inputStream, fileFormat);
}
// 2. 如果存在替换内容,遍历所有段落(包括表格内的)
if (pdfReplacements != null && !pdfReplacements.isEmpty()) {
// 遍历所有节
for (Object sectionObj : document.getSections()) {
Section section = (Section) sectionObj;
// 2.1 处理普通段落
for (Object paraObj : section.getParagraphs()) {
processParagraph((Paragraph) paraObj, pdfReplacements, document);
}
// 2.2 处理表格中的段落(包括嵌套表格)
for (Object tableObj : section.getTables()) {
processTable((Table) tableObj, pdfReplacements, document);
}
}
}
// 3. 保存结果
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
document.saveToStream(outputStream, fileFormat);
byte[] resultBytes = outputStream.toByteArray();
document.dispose();
return resultBytes;
}
/**
* 递归处理表格中的所有段落(包括嵌套表格)
*/
private void processTable(Table table, Map<String, byte[]> pdfReplacements, com.spire.doc.Document document) {
for (Object rowObj : table.getRows()) {
TableRow row = (TableRow) rowObj;
for (Object cellObj : row.getCells()) {
TableCell cell = (TableCell ) cellObj;
// 处理单元格内的普通段落
for (Object paraObj : cell.getParagraphs()) {
processParagraph((Paragraph) paraObj, pdfReplacements, document);
}
// 递归处理单元格内的嵌套表格
for (Object nestedTableObj : cell.getTables()) {
processTable((Table) nestedTableObj, pdfReplacements, document);
}
}
}
}
/**
* 处理单个段落:替换占位符为 PDF OLE 对象
*/
private void processParagraph(Paragraph paragraph,
Map<String, byte[]> pdfReplacements,
com.spire.doc.Document document) {
String paraText = paragraph.getText();
for (Map.Entry<String, byte[]> entry : pdfReplacements.entrySet()) {
String placeholder = entry.getKey();
if (paraText.contains(placeholder)) {
// 清除该段落所有内容(移除占位符)
paragraph.getChildObjects().clear();
// 加载图标
DocPicture pdfIcon = new DocPicture(document);
// 注意:getResourceAsStream 需要确保 /1.jpeg 存在于 classpath 中
pdfIcon.loadImage(getClass().getResourceAsStream("/1.jpeg"));
pdfIcon.setWidth(60);
pdfIcon.setHeight(60);
byte[] pdfBytes = entry.getValue();
try (ByteArrayInputStream pdfStream = new ByteArrayInputStream(pdfBytes)) {
DocOleObject oleObj = paragraph.appendOleObject(pdfStream, pdfIcon, "pdf");
oleObj.setDisplayAsIcon(true);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
}