2

我有一个文档模板,其中一些字段是静态的,而其他字段是动态的。我需要替换一些数据(姓名、姓氏、薪水)并生成新文件。您建议使用哪个库来执行此操作?POI合适吗?我正在使用 Spring、Java EE6 和 Oracle。

4

2 回答 2

3

您可以尝试使用 Apache POI,但是操作 word 文件所需的 POI 的 HWPF 和 XWPF 部分使用起来非常复杂 - 您至少需要很好地了解 word 文件的结构!

使用 iText 和 PDF 的解决方案

我对 PDF 做了类似的事情(这可能是你的一个选择)

1) 您可以使用 LibreOffice 在文档中创建字段(如在 Acrobat Pro 中)

  • 创建一个 .odt 文件并为其设置样式
  • 或使用 MS Word 或 LibreOffice Writer 将您的模板转换为它
  • 然后转到查看->工具栏->表单设计并设置“设计模式开/关”
  • 现在您可以将字段添加到文件中(双击它将打开字段的属性)
  • 完成后:“文件 -> 导出为 PDF”

2) 现在您可以使用 iText 来填写创建的字段

以下只是示例代码:

    public byte[] getDocumentAsByteArray(Object dataBean, String pdfTemplateName) throws KkmsException {

    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    PdfStamper stamp = null;
    InputStream templateInputStream = null;

    Locale local = new Locale(language);

    try {
        templateInputStream = // get the file input stream of the pdf
        PdfReader reader = new PdfReader(templateInputStream);

        // Create a stamper that will copy the document to a new file
        stamp = new PdfStamper(reader, outputStream);

        AcroFields form = stamp.getAcroFields();

        // form fields are normal text in the end
        stamp.setFormFlattening(true);
        Map<String, AcroFields.Item> map = (Map<String, AcroFields.Item>)form.getFields();
        if (map != null) {
            if (map.size() == 0) {
                logger.debug("There are no fields in this PDF layout");
            }
            for (Entry<String, AcroFields.Item> e : map.entrySet()) {
                logger.debug("PDF fieldname = " + e.getKey());

                // at the moment we only handle text fields
                if (AcroFields.FIELD_TYPE_TEXT == form.getFieldType(e.getKey())) {
                    fillForm(dataBean, form, e.getKey(), local);
                } else {
                    logger.warn("Field type is not supported: "+form.getFieldType(e.getKey()));
                }
            }
        }

        stamp.close();
    } catch (Exception e) {
        logger.warn("Failed to create PDF document", e);
        throw new KkmsException("Failed to create PDF document: "+e.getMessage());
    } finally {
        if (templateInputStream != null) {
            try {
                templateInputStream.close();
            } catch (IOException e) {
                throw new KkmsException("Failed to close InputStream of PDF document", e);
            }
        }
    }
    return outputStream.toByteArray();
}

最后你会得到一个 PDF -> 希望这至少对你有一点帮助!

另一个快速而肮脏的解决方案

可能是使用 odt 或 docx 的强大功能 -> 将您的 doc 转换为 docx 或 odt -> 它只是一个 zip 文件 -> 所以解压缩它 -> 你会在 zip 的根目录中看到一个 content.xml 文件 -> 那里是那里的所有文档内容现在您可以在此处添加一些魔术标签(例如 $$$),以后可以由您的程序替换

<text:p text:style-name="P3">SAP Customer Number:</text:p>

<text:p text:style-name="P3">SAP Customer Number: $$$sapCustomerNumber$$$</text:p>

现在创建一个解压缩 odt/docx 文件的程序 -> 替换标签 -> 再次压缩文件

于 2013-02-19T02:43:08.373 回答
2

这些幻灯片来自我在 OSDC 2012 上的演示文稿,概述了一些主要方法。

这些天来,我可能会添加“生成您想要的 XHTML,然后将其导出到 docx”。自从我们引入了支持将 CSS @class 值转换为 Word 样式的 docx4j-ImportXHTML 以来,我们已经越来越多地看到这种方法。

于 2014-11-20T00:29:19.043 回答