【问题标题】:Creating complex pdf using java使用java创建复杂的pdf
【发布时间】:2012-12-18 13:10:16
【问题描述】:

我有一个基于 Java/Java EE 的应用程序,其中我需要为将提供给用户的各种服务创建 PDF 证书。我正在寻找一种创建 PDF 的方法(目前不需要数字证书)。

最简单方便的方法是什么?我试过了

  1. XSL 到 pdf 的转换
  2. 使用 itext 将 HTML 转换为 PDF。
  3. 粗暴的java方式(使用PDFWriter、PdfPCell等)

最好的方法是什么,或者有没有其他更简单方便的方法?

【问题讨论】:

  • 对于 HTML 到 PDF,您应该尝试飞碟:code.google.com/p/flying-saucer
  • 最简单方便的方式取决于您想要的灵活性。如果应该允许这些“证书”包含 PDF 中可用的任何内容,那么您将不得不采用 原始 Java 方式,无论是使用您引用的类名所暗示的 iText 还是使用另一个体面的 PDF图书馆。如果“证书”是带有少量花里胡哨的简单文本,则脚本解决方案可能更合适。 XSL 或 JasperReport 都有其优点。 HTML->PDF 在我看来只有当你不得不获取 HTMLn 格式的证书模板时才有意义。

标签: java pdf-generation itext


【解决方案1】:

当您谈论证书时,我会想到对于每个证书接收者来说看起来都相同的标准表,除了:

  • 收件人姓名
  • 接收者遵循的课程
  • 日期

如果是这种情况,我会使用任何允许您创建精美证书的工具(Acrobat、Open Office、Adobe InDesign 等)并创建一个静态表单(有时称为 AcroForm),其中包含三个字段:名称、课程、日期。

然后我会使用 iText 填写如下字段:

PdfReader reader = new PdfReader(pathToCertificateTemplate);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(pathToCertificate));
AcroFields form = stamper.getAcroFields();
form.setField("name", name);
form.setField("course", course);
form.setField("date", date);
stamper.setFormFlattening(true);
stamper.close();
reader.close();

从代码创建这样的证书是“艰难的方式”;从 XML 创建这样的证书是“痛苦的”(因为 XML 不太适合定义布局),使用 iText 的 XML Worker 可以从(HTML + CSS)创建证书,但所有这些解决方案都有缺点很难正确定位每个项目,以确保所有内容都适合同一页面等等......

使用固定字段维护模板要容易得多。这样,您只需编写一次代码。如果由于某种原因您想将字段移动到另一个地方,您只需更改模板,您不必担心代码、XML、HTML 或 CSS 乱七八糟。

有关更多信息,请参阅http://www.manning.com/lowagie2/samplechapter6.pdf(第 6.3.5 节)。

【讨论】:

  • 这是一个不错的选择。非常感谢!
  • 您建议的选项很好,但我无法找到创建 PDF 的开源方式 :(。我正在尝试转换 html -> PDF,但是存在一些问题。 HTML页面中的图片在pdf中显示不正确。图片尺寸在pdf中发生了变化,有什么办法可以纠正吗?
  • 为什么使用 HTML 转 PDF?为什么不在 Open Office / Libre Office 中打开 HTML 并按照您想要创建 PDF 的方式对其进行调整? HTML 不太适合作为创建设计的格式。
  • html 到 pdf 因为这个 html 是动态的(来自 jsp 页面的 html)。
  • 在那种情况下,我不明白这个问题:要么你使用 AcroForms,要么你使用动态的东西。
【解决方案2】:

尝试使用 Jasper Reports mate。查看http://community.jaspersoft.com/

【讨论】:

  • 同意,Jasper 可能最适合这里。免费版已经够用了。
【解决方案3】:

我推荐第一种方法:XSL到pdf的转换,这是最强大的。我有使用Apache FOP优雅地生成大量PDF报告(每个都有数千页)的经验,我认为它已经足够好并且相当容易(但它需要一些xsl-FO的知识)。

【讨论】:

  • 我还发现将 XSL 转换为 pdf 很顺利,但我发现创建 XSL 是一项繁琐的任务,是否有更简单的方法来创建 xsl 或者只能手动创建?
  • XSL 有点麻烦,但是一旦你完成了,你就可以一遍又一遍地重复使用它。此外,您可以选择一些好的编辑器(例如 XMLSpy)来编辑 XSL/XML 文件,这可能会消除大量的手动输入。
【解决方案4】:

尽管这是个老问题,但我认为应该回答。

创建非常复杂的 pdf,例如证书、报告或付款单等。 您绝对可以使用动态报告库。这个库依赖于 jasper 报告(这也是非常流行的老库)。动态报告将为您提供使用 java 代码设计文档的功能,以便您可以轻松地根据需要进行操作或更改。

他们的网站上有很多示例,从这些示例中学习非常容易。

下面是它的链接:

http://www.dynamicreports.org/

【讨论】:

【解决方案5】:

Bruno Lowagie 指出了一种生成模板的好方法,该模板对于所有数据基本上都相同并且需要填充。但是,Bruno Lowagie 建议使用 iText 作为库来填充字段。对我来说,就像 Ankit 一样,这个许可证是我不得不选择另一个库的一个问题。在下文中,我将逐步指导如何使用 Apaches PdfBox 创建模板并使用数据填充它

    <dependency>
        <groupId>org.apache.pdfbox</groupId>
        <artifactId>pdfbox</artifactId>
        <version>2.0.16</version>
    </dependency>
  1. 使用 LibreOffice Writer 创建模板。对于占位符使用 文本框(查看 >> 工具栏 >> 表单控件)。这将按照 Bruno Lowagie 的建议使用 AcroForms 创建 PDF

  2. 为每个文本框设置一个名称。将只读设置为 true。

  3. 将文档另存为 PDF。

  4. 使用 PdfBox 读取 PDF 模板并设置 文本框。

    InputStream is = getClass().getClassLoader().getResourceAsStream("Template.pdf");
    
    try {
        PDDocument pDDocument = PDDocument.load(is);
        PDAcroForm pDAcroForm = pDDocument.getDocumentCatalog().getAcroForm();
    
        PDField fieldName = pDAcroForm.getField("name");
        fieldName.setValue("FirstName Surname"); // <-- Replacement
    
        pDDocument.save(outStream);
        pDDocument.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    

【讨论】:

  • 当前版本为2.0.21
【解决方案6】:

使用 iText pdf 库创建 pdf 您可以轻松地从该 api 生成 pdf。这是链接

http://itextpdf.com/

Text ® 是一个允许您创建和操作 PDF 文档的库。它使希望通过动态 PDF 文档生成和/或操作来增强 Web 和其他应用程序的开发人员。

开发者可以使用 iText 来:

将 PDF 提供给浏览器

从 XML 文件或数据库生成动态文档

使用 PDF 的许多交互功能

添加书签、页码、水印等

拆分、连接和操作 PDF 页面

自动填写 PDF 表单

为 PDF 文件添加数字签名

【讨论】:

  • 我认为这就是@Ankit 所说的粗制Java 方式(使用PDFWriter、PdfPCell 等)。 ;)
【解决方案7】:

您提到 PDF 可能很复杂。如果这与可变性或布局有关,提供相当复杂的基于模板的布局和控件的一个选项是Docmosis。您为 Docmosis 提供 doc 或 odt 文件作为模板,因此它们很容易更改,并且调用 Docmosis 到邮件合并以创建 pdf 或其他格式。请不要让我为创建 Docmosis 的公司工作。

希望对您有所帮助。

【讨论】:

  • 感谢您的推荐。 Docmosis 有一个简单的接口,带有 doc 模板和 java。
猜你喜欢
  • 2011-11-13
  • 1970-01-01
  • 2013-11-07
  • 2016-04-04
  • 2012-10-28
  • 2015-01-03
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多