将HTML文件转换为PDF

141
我需要从现有的(X)HTML文档自动生成PDF文件。输入文件(报告)使用相当简单的基于表格的布局,因此可能不需要对非常复杂的JavaScript/CSS进行支持。由于我习惯于在Java中工作,因此最好能够在Java项目中轻松使用该解决方案。尽管如此,它只需要在Windows系统上运行即可。有一种可行的方法是使用CSS2XSLFO和Apache FOP来创建PDF文件,但它不能产生高质量的输出(至少默认情况下)。我遇到的问题是,虽然CSS属性被很好地转换了,但表格布局非常混乱,文字流出了表格单元格。我还快速查看了Jrex,这是一个用于使用Gecko呈现引擎的Java API。也许有一种方法可以从Internet Explorer呈现引擎中获取渲染的页面并自动将其发送到PDF打印机工具吗?我在Windows中没有OLE编程经验,所以我不知道什么是可能的,什么是不可能的。您有什么想法吗?

3
我最近创建了一个 Java 库 docbag,可以将 XHTML 转换为 PDF 文档。当前版本并不是特别高级,但如果您的 XHTML 模板比较简单,那么这个库可能会很实用。 - Jakub Torbicki
我在将包含西里尔字母的HTML转换为PDF时遇到了问题。除了被省略的西里尔字母外,一切都正常。有没有人遇到过这种问题? - Kristijan Iliev
@krisiliev:我曾经遇到过类似的问题,据我所记,使用的字体非常重要。大多数字体不支持完整的UTF8字符,但以下字体应该支持:'font-family: Arial Unicode MS;'(CSS)。还要确保使用正确的编码(我建议始终使用UTF-8)。 - panschk
2
这个链接帮助了我 http://hmkcode.com/itext-html-to-pdf-using-java/ - Mateen
该问题在SO上属于不适当话题,但在软件推荐SE上属于适当话题。请参见如何将带有CSS的HTML转换为PDF? - Martin Thoma
显示剩余3条评论
8个回答

80

26
飞碟的真正问题在于它使用iText来渲染PDF,而iText是一个AGPL v3许可的库。 - David Hofmann
14
Flying Saucer使用的itext版本是2.0.8,可在LGPL下使用。只有5及以上版本号的itext有更严格的许可证限制。http://stackoverflow.com/questions/2692000/can-i-use-a-previous-version-of-itextsharp-under-the-lgpl - Gary - Stand with Ukraine
9
我认为飞碟(Flying Saucer)的真正问题在于它需要一个格式良好且有效的XML文档。如果在您的HTML中包含类似“&”这样的字符,或者一些JavaScript代码使您呈现的HTML不是严格的XHTML,很容易无意中破坏PDF渲染。尽管可以通过自动化测试或涉及XML验证的某些流程来减轻这种情况。 - SteveT

54

你尝试过WKHTMLTOPDF吗?

它是一个简单的命令行实用程序,是WebKit的一个开源实现,两者都是免费的。

我们在这里设置了一个小教程(链接)

编辑(2017年):

如果今天要构建某些东西,我将不再走这条路线。
而会使用 http://pdfkit.org/
可能会剥离其所有的nodejs依赖项,以在浏览器中运行。


17
对于将HTML页面转换为PDF,这比我看到的任何免费或商业的工具都要好。 - MGOwen
1
@Eran,我们在Linux上使用它。我认为也有Windows版本。 - Mic
1
@Mic 是的,也有 Windows 版本。 - Viccari
@DavidHofmann,可能是因为这个问题追溯到2009年。从我几个月前进行的最后一次检查来看,JS仍然没有可比较的解决方案。 - Mic
我因为这个参考资料而爱你。非常实用。 - Jossef Harush Kadouri
显示剩余14条评论

48

请查看iText,它是一个纯Java的PDF工具包,支持从HTML读取数据。最近我在一个项目中使用了它,当我需要从我们的CMS中提取内容并将其导出为PDF文件时,一切都非常简单。它对CSS和样式标签的支持相当有限,但可以无问题地呈现表格(尽管我从未成功设置列宽)。

从HTML创建PDF大致如下:

Document doc = new Document(PageSize.A4);
PdfWriter.getInstance(doc, out);
doc.open();
HTMLWorker hw = new HTMLWorker(doc);
hw.parse(new StringReader(html));
doc.close();

9
这是AGPL许可证,似乎比GPL还要严格,即使您只是提供PDF服务,并且iText是服务器端,您也需要开源。 - Eran Medan
10
@Eran,请使用最新的非AGPL版本(在Maven中为com.lowagie:itext:2.1.7)。 - Nowaker
1
HTMLWorker在新版本的iText中已被弃用,XMLWorker是替代方案;但是两者在CSS支持方面都较为薄弱(请参见http://demo.itextsupport.com/xmlworker/itextdoc/CSS-conformance-list.htm),并不能满足我的需求。相反,Flying Saucer则非常完美。 - Pino
您可以使用LGPL版本,该版本可在https://github.com/albfernandez/itext2上找到。 - Vova Rozhkov
HTMLWorker支持非常简单的HTML文档,具有基本元素和没有CSS。它太过于有限,无法发挥作用。但是更近期的iText html2pdf效果非常好 https://kb.itextpdf.com/home/it7kb/ebooks/itext-7-converting-html-to-pdf-with-pdfhtml/chapter-1-hello-html-to-pdf - Emmanuel Bourg

4

1
如果你正在寻找Prince的更便宜替代品,可以尝试使用DocRaptor.com。它使用Prince作为引擎。 - Julie
如果您想要更便宜但选项更多,请尝试http://www.htm2pdf.co.uk - 它使用webkit并提供真正的所见即所得。 - user1914292

4

也许有一种方法可以从Internet Explorer渲染引擎中获取已呈现的页面,并自动将其发送到PDF打印机工具吗?

这就是ActivePDF的工作方式,这意味着您知道会得到什么,而且它实际上具有合理的样式支持。

在我几年前查找时,它也是我发现的为数不多支持各种分页CSS命令的软件包之一。


不幸的是,ActivePDF软件非常令人沮丧-由于必须在后台启动IE浏览器进行转换,因此可能会很慢,而且也不太稳定。

目前正在测试的新版本应该要好得多,但我实际上还没有试过,所以不知道它有多大的改进。


1
感谢您提供的有用答案。我认为ActivePDF并不是很适合,因为价格较高,但知道这样的东西存在还是很好的。 - panschk
GrabzIt的HTML转PDF API:https://grabz.it/html-to-pdf-image-api.aspx。它的工作方式与浏览器中呈现HTML的方式相同,然后创建PDF,这确保了更准确的PDF转换。 - user1474090

2
您可以使用带有扩展的无头火狐浏览器。虽然启动比较麻烦,但它确实能够产生良好的结果。
请查看此答案以获取更多信息。

如果需要并行地将页面即时转换为PDF,则听起来不是一个非常可扩展的解决方案。如果有一些请求通过使用FF进行转换,那么您的服务器将损失几个GIG的内存,仅仅为了提供一些转换后的页面。这将使您的服务器开放到DOS攻击的风险中。 - mP.
更好但类似的:https://github.com/ariya/phantomjs/wiki/Screen-Capture(根据http://we-love-php.blogspot.com/2012/12/create-pdf-invoices-with-html5-and-phantomjs.html,PDF具有真实文本,而不是光栅化)。 - nafg

0

如果您查看问题的侧边栏,您会看到许多相关的问题...

在您的情况下,更简单的方法可能是安装一个PDF打印驱动程序,例如PDFCreator,然后将页面打印到此输出。


这怎么是一个Java解决方案?这是一个Windows打印驱动程序。 - Gray
OP明确提到了Windows。我想其他系统也有类似的驱动程序。OP只提到Java作为可能的解决方案... - PhiLho

0

Amyuni WebkitPDF 可以与 JNI 一起用于仅限 Windows 的解决方案。这是一个 HTML 到 PDF/XAML 转换库,可供商业和非商业使用。

如果不需要立即输出文件,则为了更好的可扩展性,最好设置一个队列和几个后台进程从中获取项目,将其转换并将其存储在数据库或文件系统中。

通常的免责声明适用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接