spire.doc.free将word中占位符替换为pdf文件,以及合并PDF

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;
            }
        }
    }
相关推荐
FinelyYang1 天前
uniapp使用kkfileview在线预览ppt,excel,word,pdf类型文件
pdf·uni-app·powerpoint
yivifu1 天前
使用lxml操作 Word 的 OpenXML 底层
word·openxml·lxml
WORLDPO92262 天前
QTE-020-01-L/F/C-D-A-K-TR_实物_数据手册PDF_国产替代
pdf
asdzx672 天前
C# 操作 PDF 元数据:从属性写入到字段提取的完整流程
前端·pdf·c#
WORLDPO92262 天前
SFSDT-10/15/20/25/35-28-G-19.69-SR_实物图_数据手册PDF_国产替代
pdf·pcb工艺·pcb
梦想出海-Phoebe2 天前
Gemini新增文件编辑功能:PDF、Word、Excel处理体验分享
pdf·word·excel
开开心心就好2 天前
网页图片批量下载工具,输入链接就保存
服务器·算法·leetcode·支持向量机·pdf·ocr·1024程序员节
汤姆宝库3 天前
法考历年真题及答案解析合集pdf版(2002-2025年)
pdf·法考
优化控制仿真模型3 天前
2026【英一】考研英语一历年真题及答案解析PDF电子版(1980-2025年)
考研·pdf
开开心心_Every4 天前
快速隐藏程序工具自定义快捷键一键切换
java·开发语言·前端·spring·智能手机·word·intellij-idea