Apache PDFBox 2已于今年早些时候发布 , Apache PDFBox 2.0.1和Apache PDFBox 2.0.2已发布。 Apache PDFBox是开源的( Apache许可证版本2 )并且基于Java(因此易于使用,包括Java , Groovy , Scala , Clojure , Kotlin和Ceylon )。 这些或其他基于JVM的任何语言都可以使用Apache PDFBox来读取,编写和使用PDF文档 。
Apache PDFBox 2除了完成的任务和一些新功能以外,还引入了许多错误修复。 Apache PDFBox 2现在需要Java SE 6 ( Apache PDFBox 1.x的 J2SE 5最低要求)。 有一个迁移指南,“ 迁移到PDFBox 2.0.0” ,详细介绍了PDFBox 1.8和PDFBox 2.0之间的许多差异,包括更新后的依赖项( Bouncy Castle 1.53和Apache Commons Logging 1.2 )以及PDFBox 2中的“对库的重大更改”。
PDFBox可用于创建PDF。 下一个代码清单改编自文档创建 “ Cookbook”示例中的Apache PDFBox 1.8示例“ Create a blank PDF”。 引用的示例显式关闭了实例化的PDDocument ,可能这样做是为了对那些在JDK 7之前使用Java版本的用户有利。但是,对于Java 7的用户, try-with-resources是确保PDDocument
实例关闭的更好选择。并且受支持,因为PDDocument
实现了AutoCloseable 。
创建(空)PDF
- /**
- * Demonstrate creation of an empty PDF.
- */
- private void createEmptyDocument()
- {
- try (final PDDocument document = new PDDocument())
- {
- final PDPage emptyPage = new PDPage();
- document.addPage(emptyPage);
- document.save("EmptyPage.pdf");
- }
- catch (IOException ioEx)
- {
- err.println(
- "Exception while trying to create blank document - " + ioEx);
- }
- }
下一个代码清单改编自文档创建 “ Cookbook”示例中的Apache PDFBox 1.8示例“ Hello World使用PDF基本字体”。 从1.8 Cookbook示例中此清单中最重大的变化是分别将不赞成使用的方法PDPageContentStream.moveTextPositionByAmount(float,float)和PDPageContentStream.drawString(String)替换为PDPageContentStream.newLineAtOffset(float,float)和PDPageContentStream.showText(String) 。
用字体创建简单的PDF
- /**
- * Create simple, single-page PDF "Hello" document.
- */
- private void createHelloDocument()
- {
- final PDPage singlePage = new PDPage();
- final PDFont courierBoldFont = PDType1Font.COURIER_BOLD;
- final int fontSize = 12;
- try (final PDDocument document = new PDDocument())
- {
- document.addPage(singlePage);
- final PDPageContentStream contentStream = new PDPageContentStream(document, singlePage);
- contentStream.beginText();
- contentStream.setFont(courierBoldFont, fontSize);
- contentStream.newLineAtOffset(150, 750);
- contentStream.showText("Hello PDFBox");
- contentStream.endText();
- contentStream.close(); // Stream must be closed before saving document.
-
- document.save("HelloPDFBox.pdf");
- }
- catch (IOException ioEx)
- {
- err.println(
- "Exception while trying to create simple document - " + ioEx);
- }
- }
下一个代码清单演示了使用Apache PDFBox从PDF解析文本的方法。 这个极其简单的实现使用PDFTextStripper.getText(PDDocument)将所有文本解析为单个String
。 在最现实的情况下,我不希望PDF中的所有文本都在单个String中,并且可能会使用PDFTextStripper的功能来更狭窄地指定要分析的文本 。 还要注意的是,尽管此代码清单是从网上获取PDF的( Scala示例 PDF, 网址为http://www.scala-lang.org/docu/files/ScalaByExample.pdf ),但是PDDocument的构造函数很多 ,允许使用一个在文件系统上以及通过其他类型的流访问PDF。
从在线PDF解析文本
- /**
- * Parse text from an online PDF.
- */
- private void parseOnlinePdfText()
- {
- final String address = "http://www.scala-lang.org/docu/files/ScalaByExample.pdf";
- try
- {
- final URL scalaByExampleUrl = new URL(address);
- final PDDocument documentToBeParsed = PDDocument.load(scalaByExampleUrl.openStream());
- final PDFTextStripper stripper = new PDFTextStripper();
- final String pdfText = stripper.getText(documentToBeParsed);
- out.println("Parsed text size is " + pdfText.length() + " characters:");
- out.println(pdfText);
- }
- catch (IOException ioEx)
- {
- err.println("Exception while trying to parse text from PDF at " + address);
- }
- }
JDK 8问题
PDFBox 2暴露了JDK 8中的一个问题,该问题是在Bug JDK-8041125下提出的(“与JDK7相比,JDK 8中的ColorConvertOp过滤器要慢得多”)。 Apache PDFBox“ 入门 ”文档描述了以下问题:“由于将Java颜色管理模块更改为“ LittleCMS ”,因此用户在进行颜色操作时会遇到性能下降的问题。” 相同的“入门”部分提供了变通方法:“禁用LittleCMS以便使用旧的KCMS(柯达色彩管理系统)。”
该错误似乎已由IDR Solutions及其商业Java PDF库JPedal识别并提交。 他们的博客文章Java新版本中的Color性能的重大变化提供了与此问题相关的更多详细信息。
刚刚提到的文章和文档(包括Apache PDFBox 2的“入门”部分)通过明确指定使用KCMS( 可以随时删除 )而不是默认值来明确展示Java系统属性的使用,以解决该问题。 LittleCMS。 如这些来源所述,可以使用-D
选项[ -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider
]向Java启动器[ java ]提供系统属性 ,也可以在可执行代码中指定该属性。本身[ System.setProperty("sun.java2d.cmm", "sun.java2d.cmm.kcms.KcmsServiceProvider");
]。
听起来这个问题并不是Apache PDFBox版本2独有,但在Apache PDFBox 2中更常见,因为版本2更频繁地使用依赖结构,并且使用Java 8的人也有可能使用较新的PDFBox。
JDK 8中与属性sun.java2d.cmm
关联的默认实现的sun.java2d.cmm
说明了我在最近的博客文章《 Java向后不兼容的历史观察》中试图sun.java2d.cmm
的观点。 在那篇文章中,我总结道,“请小心并谨慎使用广告或实验性宣传的Java API,类和工具,这些Java,Java和Java在将来的Java发行版中可能会删除。” 事实证明Java 2D系统属性在此类中。 Java 2D Technology的系统属性页面提供了有关使用这些属性的背景信息和警告信息:
本文档介绍了一些不受支持的属性,可用于自定义2D绘画系统的运行方式。 您可能会使用这些属性来提高性能,修复错误的呈现或避免某些配置下的系统崩溃。 …
警告:使用这些属性时要小心。 由于非常实际的原因,其中一些不受支持。 …由于这些属性的唯一目的是启用或禁用特定于实现的行为,因此它们可能会更改或删除,恕不另行通知。 某些属性可能仅适用于所记录的确切产品版本。
结论
Apache PDFBox 2是在Java中操作PDF文档的相对简单的方法。 它具有开放的Apache 2许可证,非常适合广大读者,其开放源代码性质使开发人员可以了解如何使用其在幕后使用的库并根据需要进行调整。
其他资源
- Apache PDFBox – Java PDF库 (主项目页面)
- Apache PDFBox 2.0发布 (软件开发时间,2016年3月21日)
- 用于处理PDF文档的Apache PDFBox库 (2016年4月3日)
- 以编程方式用Java填写PDF (2013年1月11日– PDFBox 1.x)
翻译自: https://www.javacodegeeks.com/2016/07/apache-pdfbox-2.html