【问题标题】:Defining Templates and Manipulating using Java使用 Java 定义模板和操作
【发布时间】:2017-11-29 19:07:25
【问题描述】:

作为我项目要求的一部分,我正在考虑创建预定义的模板,这些模板具有预定义的字体和缩进,并带有我想在运行时替换的固定可变部分并生成 PDF。这些可能是替换单个变量示例#Name 或插入重复组#List of Orders。

我正在考虑使用标签创建 PDF,然后通过 PDFBox 阅读并替换它们。然而,在不知道预定义位置的情况下,似乎无法使用 PDFBox 替换文本。

有什么我需要看的替代品吗?我需要能够在每个页面上有单独的标题,并且能够用变量替换标签。

谢谢 阿纳布

【问题讨论】:

  • PDF 不是文字处理格式,所以当您说“我有现有的 PDF 文档,我想用另一个单词替换其中的一个单词”时,一位 PDF 专家会听到:“我有洋葱汤,我想用西红柿代替洋葱。”我假设你不是在开玩笑,所以我会尽量不要对你的问题笑,但是你看过 PDF 表格吗?您是否可以选择使用 PDF AcroForm 技术?
  • 您有这些 PDF 的来源吗?也许那些具有 可读 格式。您需要知道,在转换为 PDF 时,您会丢失单词信息以及有关内容结构的许多其他信息。 PDF 只包含诸如在此坐标处放置一些笔划并在该坐标处放置另一个笔划 之类的内容。这也是处理 PDF 很困难以及优秀的编辑器成本高昂的原因。

标签: java pdf reporting


【解决方案1】:

为您的字体和布局创建模板是个好主意。除了使用 PDF 文档作为模板,您还可以使用文字处理器文档 (doc/docx/odt),填充它们然后转换为 PDF。

如果该方法适合您的目的,您可以使用 Libre Office Java API 来操作模板并保存为 PDF。这意味着您可以创建一个 DOC 或 ODT 文件作为您的模板(带有不同的标题)和数据的占位符,您的 Java 程序可以控制 Libre Office 加载文档、更新占位符并保存为 PDF。以下 Java 代码替换了模板中的 3 个占位符并保存了一个 pdf:

// Initialise
XComponentContext xContext = Bootstrap.bootstrap();

XMultiComponentFactory xMCF = xContext.getServiceManager();

Object oDesktop = xMCF.createInstanceWithContext(
     "com.sun.star.frame.Desktop", xContext);

XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(
     XDesktop.class, oDesktop);

// Load the Document
String workingDir = "C:/projects/";
String myTemplate = workingDir + "letterTemplate.doc";

if (!new File(myTemplate).canRead()) {
    throw new RuntimeException("Cannot load template:" + new File(myTemplate));
}

XComponentLoader xCompLoader = (XComponentLoader) UnoRuntime
    .queryInterface(com.sun.star.frame.XComponentLoader.class, xDesktop);

String sUrl = "file:///" + myTemplate;

PropertyValue[] propertyValues = new PropertyValue[0];

propertyValues = new PropertyValue[1];
propertyValues[0] = new PropertyValue();
propertyValues[0].Name = "Hidden";
propertyValues[0].Value = new Boolean(true);

XComponent xComp = xCompLoader.loadComponentFromURL(
    sUrl, "_blank", 0, propertyValues);

// Manipulate
XReplaceDescriptor xReplaceDescr = null;
XReplaceable xReplaceable = null;

XTextDocument xTextDocument = (XTextDocument) UnoRuntime
        .queryInterface(XTextDocument.class, xComp);

xReplaceable = (XReplaceable) UnoRuntime
        .queryInterface(XReplaceable.class,
                xTextDocument);

xReplaceDescr = (XReplaceDescriptor) xReplaceable
        .createReplaceDescriptor();

// mail merge the date
xReplaceDescr.setSearchString("<date>");
xReplaceDescr.setReplaceString(new Date().toString());
xReplaceable.replaceAll(xReplaceDescr);

// mail merge the addressee
xReplaceDescr.setSearchString("<addressee>");
xReplaceDescr.setReplaceString("Best Friend");
xReplaceable.replaceAll(xReplaceDescr);

// mail merge the signatory
xReplaceDescr.setSearchString("<signatory>");
xReplaceDescr.setReplaceString("John Steady");
xReplaceable.replaceAll(xReplaceDescr);

// save as a PDF
XStorable xStorable = (XStorable) UnoRuntime
        .queryInterface(XStorable.class, xComp);

propertyValues = new PropertyValue[2];
// Setting the flag for overwriting
propertyValues[0] = new PropertyValue();
propertyValues[0].Name = "Overwrite";
propertyValues[0].Value = new Boolean(true);
// Setting the filter name
propertyValues[1] = new PropertyValue();
propertyValues[1].Name = "FilterName";
propertyValues[1].Value = "writer_pdf_Export";

// Appending the favoured extension to the origin document name
String myResult = workingDir + "letter1.pdf";
xStorable.storeToURL("file:///" + myResult, propertyValues);

System.out.println("Saved " + myResult);

// shutdown
xDesktop.terminate();

您可以在此博客java-convert-word-to-pdf-part-1 中找到对代码的解释。请注意我为 Docmosis 工作。

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2014-06-11
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    相关资源
    最近更新 更多