使用 itext 将 html 页面转 pdf(完美支持中文)

本贴最后更新于 2533 天前,其中的信息可能已经天翻地覆

最近有用到使用 itext 将 html 页面转 pdf 的操作,做个笔记

技术预研

受限于某些外部原因(该环境无法使用 java 执行 sh 脚本),wkhtmltopdf 被排除在外,最终选择了 itext 全家桶,itextpdf 作为 pdf 生成核心,xmlworker 用于 html 转 pdf,itext-asian 用于支持中文显示,视情况而定还可以引入 nekohtml 对非标准 html 页面进行标签补全.

引入 maven 依赖

<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.11</version> </dependency> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.11</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency>

核心功能代码

import com.itextpdf.text.Document; import com.itextpdf.text.Font; import com.itextpdf.text.PageSize; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.tool.xml.XMLWorkerFontProvider; import com.itextpdf.tool.xml.XMLWorkerHelper; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; public class PDFUtil { public static void writeStringToOutputStreamAsPDF(String html, OutputStream os) { writeToOutputStreamAsPDF(new ByteArrayInputStream(html.getBytes()), os); } public static void writeToOutputStreamAsPDF(InputStream html, OutputStream os) { try { Document document = new Document(PageSize.A4); PdfWriter pdfWriter = PdfWriter.getInstance(document, os); document.open(); XMLWorkerHelper worker = XMLWorkerHelper.getInstance(); worker.parseXHtml(pdfWriter, document, html, Charset.forName("UTF-8"), new AsianFontProvider()); document.close(); } catch (Exception e) { } } } /** * 用于中文显示的Provider */ class AsianFontProvider extends XMLWorkerFontProvider { @Override public Font getFont(final String fontname, String encoding, float size, final int style) { try { BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); return new Font(bfChinese, size, style); } catch (Exception e) { } return super.getFont(fontname, encoding, size, style); } }

其中 writeToOutputStreamAsPDF 方法接受输入流形式的 html 文件,然后将 pdf 写入到输出流中,而 writeStringToOutputStreamAsPDF 方法则接受文本形式的 html 文件,方便做一些模板替换的预处理工作,当然也可以结合 vm,fm 等模板引擎进行模板文件数据渲染,请自行了解,OutputStream 输出流可作为文件输出流写入到生成 PDF 文件,也可以作为 web 环境下的 response 提供 PDF 文档显示/下载功能

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3201 引用 • 8216 回帖
  • PDF
    30 引用 • 45 回帖 • 1 关注
  • Itext
    5 引用 • 3 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • lumang

    老哥我想问一下我使用的字体和您相同但是在浏览器预览的 PDF 和 pdf 转成的图片字体显示不同,老哥有遇到吗?

    QQ20180828155743png

    QQ20180828155910png

    1 回复
  • alanfans

    BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H"
    这个应该可以 改字体吧

    1 回复
  • lumang

    QQ20180828165317png
    我使用的也是这个,但是两次发现不一致,pdf 用别之前打开也是草体的