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;
            }
        }
    }
相关推荐
庖丁AI21 小时前
PDF 转 Markdown 工具怎么选?AI 知识库和 RAG 场景要注意什么
人工智能·pdf·文档解析
几层山下1 天前
WPS的word文档转pdf java实现不乱格式生成-已解决
java·pdf·word·wps
2601_962294051 天前
Python 操作 Word:如何查找、替换和批量修改文本
python·正则表达式·word·文档处理·查找替换
GHL2842710901 天前
codex操作excel学习
学习·ai·word·excel
Eiceblue1 天前
如何构建一个纯前端 Word 转 Markdown 转换器(React + WebAssembly)
前端·react.js·word
圣光SG2 天前
Word 综合实操项目:标准求职简历制作
word
DevOpenClub2 天前
PDF 多格式解析如何避免混用输出:TEXT、HTML、XML 与 TAG 数据契约
xml·前端·数据库·pdf·html
DevOpenClub2 天前
网页证据如何长期复核:快照、静态 HTML 与 PDF 归档链路
前端·pdf·html
RisunJan2 天前
项目经理面试知识点梳理
面试·职场和发展·word