打开 HTML 转 PDF
概述
Open HTML to PDF 是一个纯 Java 库,用于使用 CSS 2.1(和更高版本的标准)进行布局和格式化,输出为 PDF 或图像,呈现格式良好的 XML/XHTML(甚至某些 HTML5)的合理子集。
使用这个库可以生成漂亮的 PDF 文档。但请注意,您不能将现代 HTML5+ 扔到这个引擎上并期望得到很好的结果。您必须为此库专门制作 HTML 文档,并使用它的扩展 CSS 功能(如 #31 或 #32)才能获得良好的结果。避免在分页符附近浮动并使用表格布局。
入门
- 集成指南 - 获取 Maven 工件和代码以开始使用。
- 1.0.10 在线沙箱 - 现在带有日志!
- Templates for Openhtmltopdf - 适用于该项目的 MIT 许可模板。更新于 2021 年 9 月 21 日。
- 展示文档 - PDF
- 文档维基
- 模板作者指南 - PDF - 已弃用 - 首选 wiki - 将信息移至 wiki
- 示例项目 - 漂亮的简历生成器
与飞碟的区别
- 使用维护良好的开源(兼容 LGPL)PDFBOX 作为 PDF 库,而不是 iText。
- 适当支持生成可访问的 PDF(第 508 条、PDF/UA、WCAG 2.0)。
- 正确支持生成符合 PDF/A 标准的 PDF。
- 新的、更快的渲染器意味着这个项目对于非常大的文档可以快几倍。
- 更好地支持 CSS3 转换。
- PDF 的自动视觉回归测试,包含许多端到端测试。
- 能够插入剪切内容的页面。
- SVG 和 MathML 的内置插件。
- 字体后备支持。
- 对 RTL 和双向文档的支持有限。
- 不利的一面是,不支持 OpenType 字体。
- 脚注支持。
- 更多。请参阅下面的变更日志。
执照
Open HTML to PDF 是在 LGPL 下分发的。 Open HTML to PDF 本身已获得 GNU Lesser General Public License 2.1 或更高版本的许可,可从 http://www.gnu.org/copyleft/lesser.html 获取。只要您遵守许可条款,您就可以以任何方式、出于任何目的使用 Open HTML to PDF。 LGPL 许可证的副本作为许可证-lgpl-2.1.txt 或许可证-lgpl-3.txt 包含在我们的发行版和源代码树中。
pdf-a 测试模块是一个例外,它是根据 GPL 授权的。该模块未分发到 Maven Central,仅用于测试。
Open HTML to PDF 使用几个 FOSS 软件包来完成工作。这些的列表可以在依赖图中找到。
学分
Open HTML to PDF 是基于 Flying-saucer 的。功劳归于该项目的贡献者。代码也将使用来自 neoFlyingSaucer
常问问题
- OPEN HTML TO PDF 已使用 OpenJDK 8、11 和 17(早期访问)进行测试。它至少需要 Java 8 才能运行。
- 不,您不能在 Android 上使用它。
- 您应该能够在 Google App Engine(Java 8 或更高环境)上使用它。让我们知道您的经历。
未实现流动列。在 RC12 中实现。- 不,它不是网络浏览器。具体来说,它不运行 javascript 或实现许多现代标准,例如 Flex 和网格布局。
测试用例
欢迎测试用例,失败或工作,请将它们放在/openhtmltopdf-examples/src/main/resources/testcases/
中并从/openhtmltopdf-examples/src/main/java/com/openhtmltopdf/testcases/TestcaseRunner.java
运行它们。
变更日志
头 - 1.0.11-SNAPSHOT
1.0.10(2021年9月13日)
注意:在此版本之后,旧的慢速渲染器将被删除。快速模式一直是默认模式(自 1.0.5 起),因此您只需在调用将被删除的useSlowMode
方法时检查代码。
- #551安全性修复带有
page-break-inside: avoid
约束。感谢您坚持@swillis12 并调试@syjer。 - #729安全升级 xmlgraphics-commons(用于 SVG 渲染)以避免 CVE。谢谢@electrofLy。
- #711 脚注支持(测试版)。请参阅 wiki 上的脚注文档。感谢您请求@a-leithner 和@slumki。
- #761 CSS 属性禁用边框上的斜角,以防止难看的抗锯齿效果,尤其是在表格单元格上。请参阅 wiki 上的 -fs-border-rendering 属性。感谢您提供样本@gandboy91。
- #103 对于具有关联异常的日志消息,默认输出异常类名称和消息。
- #711(混合)对
::before
和::after
内容进行更好的装箱。现在应该能够正确定义伪内容周围的边框。 - #738 支持 PDF/UA 中的其他元素,包括艺术、部分、节、部分、标题和块引用。谢谢@AndreasJacobsen。
- #736 使用 dom 突变器实现不支持的内容(例如字体标签属性)的新示例。感谢您请求@mgabhishek06kodur。
- #707 修复不兼容 PDF/A 的 PDF/UA 文档缺失都柏林核心元数据的回归问题。谢谢@mgm-rwagner,@syjer。
- #732 允许定位
table
元素。谢谢@fcorneli。 - #727 允许使用
page
和pages
计数器的初始页码。感谢@fanthos 的公关。
1.0.9(2021年6月18日)
安全版本:此版本是由于 PDFBOX 和 Batik 依赖项的安全版本而提前发布的。
- #722 升级 PDFBOX(至 2.0.24)- 避免早期版本和 PDFBoxGraphics2D 中的 CVE。非常感谢@rotator。
- #678 将 Batik 版本升级到 1.14 (CVE-2020-11987) - 再次强烈建议避免不受信任的 SVG 和 XML。谢谢@rotator。
- #716 用日志调用替换流氓
println
调用。感谢@syjer 的公关,@tfo 的报道。 - #708 允许
shape-rendering
SVG CSS 属性。感谢@syjer 的公关,@RAlfoeldi 的报道。 - #703 删除对 JRE 标准库中已弃用方法的调用。可能会更改 XML 阅读器类。由@danfickle 实现。
- #702 设置默认 HTTP/HTTPS 处理程序的超时。感谢您举报@gengzi。
- 162228 通过 URL 解析器放置指向 SVG 中光栅图像的链接。
- #694 修复不正确的 B3 纸张尺寸。感谢@lfintalan 报告行号!
- ab48fd 不要多次记录丢失的字体。
注意:PDFBOX CVE 与在 PDFBOX 中加载不受信任的 PDF 相关,因此该项目不会直接受到影响。但是,在类路径中包含 CVE 并不是一个好主意。
1.0.8(2021年3月22日)
安全发布
- #675 将 PDFBOX 更新到 2.0.23 以避免 CVE。感谢您举报@Samuel3。
注意:这些 CVE 与在 PDFBOX 中加载不受信任的 PDF 相关,因此该项目不会直接受到影响。但是,在类路径中包含 CVE 并不是一个好主意。
1.0.7(2021年3月19日)
- #650 支持一个元素上的多个背景图像。感谢您提出请求@baedorf。
- #669 支持后备字体。感谢您请求@asu2 并协助@draco1023。
- #640 通过链接上的下载属性实现文件嵌入。感谢@syjer 的原创公关以及@lindamarieb 和@vader 的请求。
- #666 API 用于获取渲染内容最底部的 y 位置,以便能够使用其他工具定位后续内容。感谢您对 PR @stechio 的广泛审查以及 @DSW-AK 的请求。
- #664 改进了对 PDF/A 和 PDF/UA 标准的支持。感谢 @qligier 的公关。
- #653 修复了具有 z 索引或变换的内联块元素被输出两次的问题。感谢您举报@hannes123bsi。
- #655 RTL 方向有序列表的正确布局。感谢 @johnnyaug 的公关。
- #658 实现
content
属性的target-text
功能。感谢@BenjaminVega 的公关。 - #647 修复在多线程环境中设置记录器时的竞争条件。感谢 @syjer 的公关。
- #638 能够根据资源类型和 url 插入外部资源控制。感谢@syjer 的原创公关。
- #628 使用 PDF-BOX 中的增强图像嵌入方法。感谢 PR @rototor 以及您在 PDF-BOX 中实现此功能的工作。
- #627 修复空字体样式导致 NPE 的回归。感谢公关@rototor。
- #338 实现只读单选按钮组。感谢 @ThoSchCon、@aleks-shbln、@dmitry-weirdo、@syjer 和 @paulito-bandito 的调查、报告和耐心。
1.0.6(2020年12月22日)
重要提示: #615 这是一个错误修复版本,用于解决在使用带有顶部/底部边距的浮动元素的断字时出现的无限循环问题。
- #624 将 PDFBOX 更新到 2.0.22,将 pdfbox-graphics2d 更新到 0.30。谢谢@rotator。
- #467 防止 CSS 导入循环的可能性。
- #621 数据 uri 中允许有空格。谢谢@syjer。
1.0.5(2020年11月30日)
安全: #609 将 Apache Batik SVG 渲染器更新到最新版本以避免安全问题。如果您使用此项目来渲染不受信任的 SVG(不建议),则应立即更新。非常感谢@halvorbmundal。
重要提示:快速渲染器现在是默认的,以准备删除旧的慢速渲染器。要暂时使用慢渲染器,您可以调用已弃用的方法builder.useSlowMode()
(仅限 PDF 输出)。
重要提示: #543 由于版本 2.0.21 中存在不间断空格的错误,该版本保留在 PDFBOX 版本 2.0.20 上。请确保 2.0.21 版本不在您的类路径中。该错误已在即将发布的 2.0.22 中修复。
- #544 用于为 thymeleaf 和原始 XHTML 格式的预装 PDF 模板创建网站的代码。查看模板网站以预览模板。
- #533 条形码插件。 @syjer 提供的非常有用的 PR。条形码插件文档。
- #521 将 Java2D 图像输出移至快速渲染器并进行一般改进。 Java2D 图像输出文档。
- 9ffd0e #568 过滤掉在某些字体中可见但不应该是软连字符的有问题的字符。谢谢@StephanSchrader。
- #587 修复空白:nowrap 切断而不是换行。感谢@vipcxj 最终通过 PR 修复了问题。
- #577 添加前景 PDF 抽屉插件(特别适用于水印)。感谢@rototor 的公关和@sillen102 的坚持。
- #566 将
baseUri
arg 重命名为baseDocumentUri
并改进 javadoc 以避免混淆。感谢您举报@NehalDamania。 - 801780 将 junit 测试依赖项更新为 4.13.1,以避免安全扫描器警告(特定安全问题不会影响此库)。
- #553 修复了使用负边距时 ContentLimitContainer 导致 NPE 的问题。感谢您举报@adilxoxo。
- #552 优化 jul 日志记录的日志格式化程序。感谢 @syjer 令人印象深刻的公关。
- #542 改进列表装饰放置。感谢 @syjer 的公关和 @mndzielski 的报道。
- #458 修复了在页边距区域中输出(剪切)列表装饰的问题。
- #525 删除未使用的架构/DTD。显着减小罐子的尺寸。感谢 @syjer 的公关。
- #592 允许在链接的 SVG 图像的宽度/高度属性中使用单位(px、cm、em 等)值。谢谢@DanielWulfert。
- #594 #458 修复更多重复内容和 PDF/UA 崩溃。谢谢@ThomHurks,@fungc。
- #599 修复 InlineText.setSubstring 上发生的 RuntimeException。谢谢@LAlves91。
- #605 修复以使代理对的合理性起作用。谢谢@EmanuelCozariz。
- #601 将 CI 移至 Github 操作。谢谢@syjer。
- #597 推广数据 uri 支持。谢谢@syjer,@Leostat86。
- #613 允许将 SVG、MathML 的字体添加为文件而不是输入流,以避免 JDK 错误。谢谢@syjer、@sureshkumar-ramalingam、@olayinkasf。
1.0.4(2020年7月25日)
- b88538 修复使用
word-wrap: break-word
时的无限循环。感谢您报告、测试和调查@swarl。感谢@rototor 和@syjer 的测试和调试。 - #492 对断行算法进行大量测试以避免未来的无限循环。作者:@danfickle。
- #515 将应用于 SVG 元素的文档 CSS 样式传递给 SVG 实现。感谢您的请求和贡献@amckain92。
- #514 修复:在对齐 rtl 线时正确定位框。感谢@lzhy1101 的报告和测试。
- #512 #507 #502 清理代码,包括删除未使用的代码、泛型等。感谢 PR @syjer。
- #489 日志记录的广泛检修,包括每次运行诊断消费者。非常感谢@syjer,在这个 PR 中做了很多工作。有关详细信息,请参阅 wiki 上的日志记录页面。
- #501 将 PDFBOX 升级到 2.0.20,将 PDFBox-Graphics2D 升级到 0.26。感谢@rotator 的公关。
- #490 修复了解码图像数据 url 失败时的 NPE。感谢 @syjer 的公关和 @AlexisCothenet 的报道。
- #516 将 OSGI 捆绑元数据添加到 MANIFEST.MF。感谢您提出请求并进行调查@zspitzer。
1.0.3(2020年5月25日)
- 重要提示:此版本包含两个错误的修复,这些错误可能会导致使用
word-wrap: break-word
时出现无限循环/拒绝服务。如果您正在使用该功能,请及时升级。 - #483 修复
word-wrap: break-word
和软连字符。感谢@rototor 的公关、@syjer 的分析和@swarl 的报告。 - #466 修复
word-wrap: break-word
和零宽度框。感谢@syjer 的分析和@AlexisCothenet 的报告。 - #486 SVG 插件现在可以提供外部资源允许的协议列表,并且将使用任何配置的 uri 解析器/流处理程序。感谢@syjer 的公关和@ieugen 的报道。
- #480 修复了从自定义对象抽屉返回的链接形状。感谢@rototor 的公关和@hbergmey 的报道。
- #485 实现对 SVG 数据 uri 的支持。感谢@syjer 的公关和@adrianrodfer 的报道。
- #470 允许
mailto:
链接或任何其他有效链接。感谢@syjer 的公关和@mndzielski 的报告。 - #464 尊重 CSS
direction
属性。感谢@AnanasPizza 的报告。 - #460 将抛出的异常类更改为更具体的
IOException
。感谢@leonorader 的公关。 - #459 实现
rem
CSS 单元。感谢@leonorader 的报告。 - #211 图像现在可以在 CSS
content
属性中使用。感谢您请求@Kuhlware。 - #445 修复了 Jsoup 转换文档中未拾取属性值的问题。感谢您报告@testinfected。
- #450 仅 Java2D 输出:能够通过代码添加字体。默认情况下也将不再使用环境字体。要使用环境字体:
builder.useEnvironmentFonts(true)
。
1.0.2(2020年2月25日)
- 安全性删除了 Log4J 1.x 适配器,因为它具有 CVE-2019-17571,且没有可用的更新版本。
- #448 实现对
background-image
属性的linear-gradient
支持。作者:@danfickle。由@rja907 请求。 - #429
word-wrap: break-word
。现在,一个单词不会被破坏,除非它对于一行来说太大了。作者:@danfickle。感谢您报告和测试@mndzielski。 - #433 不要对齐以
<br/>
标记结尾的行。感谢您举报@fcorneli。 - #440 删除右对齐文本的尾随空白,以避免出现锯齿状外观。感谢您举报@AnanasPizza。
- #446 使用
lang()
选择器时查找祖先元素上的 lang 属性。感谢@fungc 报告并追踪该错误。 - #430 在源 jar 中使用相对路径而不是绝对路径进行许可。感谢您报告 @gabro 并通过 PR @syjer 进行修复。
- #417 保持具有宽度/高度属性以及最小/最大宽度/高度属性的图像的纵横比。感谢您的报告和修复的基础@swarl。
- #423 允许使用
format
标签指定多个字体源。仅使用format(truetype)
。感谢@MichaelZaleskovsky 的请求和@syjer 的实施基础。 - #415 如果用户尝试浮动表格单元格,请避免类转换异常。感谢您举报@dmartineau99 和公关@syjer。
- #421 当合理的文本与不合理的内容混合时,避免 NPE。感谢您举报@Megingjard 和公关@syjer。
- 将 PDFBOX 2.0.17 更新至 2.0.19。
1.0.1(2019年11月18日)
- #413 处理表单问题,例如输入元素上没有名称,而不抛出 NPE。感谢@syjer 的公关和@mmatecki 的报道。
- #412 将 HTML 块级元素添加为默认 CSS
section
。谢谢@syjer。 - #339 删除 JSoup 到 DOM 转换器模块。谢谢@kewilson。
- 0cd098 修复了带有尾随空格的块最后一行的字母间距支持。还有性能改进和重构。作者:@danfickle。
- #410 修复了列表项计数器上错误的粗体设置。感谢@syjer 的公关修复(和测试!)和@acieplinski 的报告。
- Wiki 可配置的文本对齐设置作为对齐调整的一部分,当行上没有空格时,还允许在字符间使用更多空间。作者:@danfickle。 #403 中列出的提交。
- #403 软连字符支持。当用作行结束字符时,软连字符现在被替换为硬连字符。谢谢@sbrunecker。
- #408 修复了书签不适用于 HTML5 解析器(例如 JSoup)的问题。感谢@syjer 进行调查和修复,感谢@Milchreis 进行报告。
- #404 将 Batik 升级到 1.12,将 xmlgraphics-common 升级到 2.4(均在 SVG 模块中使用)以避免其中之一或两者出现 CVE。谢谢@avoiculet。
- #396 使用边框半径属性更快地渲染框。谢谢@mndzielski。
- #400 支持
lang
和title
属性以及abbr
标签,以实现可访问的 PDF。谢谢@Ignaciort91。 - #394、#395 将 PDFBOX 升级到 2.0.17,将 pdfbox-graphics2d 升级到 0.25。谢谢@cristan,@rototor。
- #384 允许用户提供 PDFont 供应商。谢谢@DSW-PS。
- #373 修复回归问题,其中为具有特定长宽比的图像提供最大宽度和最大高度。谢谢@rotator。
- #380 对流动列的更好支持,包括显式分栏符、浮动内容、块级嵌套内容。作者:@danfickle。
1.0.0(2019年7月23日)
- #372 大大改进了对
img
、 svg
和math
元素的大小调整支持。 - #344 在
img
标签中使用 PDF: <img src="some.pdf" page="1" alt="Some alt text" />
。
旧版本
查看 CHANGELOG.md。