备案 控制台
学习
实践
活动
专区
工具
TVP
写文章
专栏首页 JAVA乐园 HTML转PDF字体的坑,搞了半天
1 0

海报分享

HTML转PDF字体的坑,搞了半天

阅读文本大概需要3分钟。

itext提供可HTML转PDF的工具包,但是在中文字体时也许会遇到意想不到的问题。特别宋体对应的粗体。

0x01:引入itext包

<dependency>
       <groupId>com.itextpdf</groupId>
       <artifactId>itext7-core</artifactId>
       <version>7.1.11</version>
       <type>pom</type>
 </dependency>
<dependency>
       <groupId>com.itextpdf</groupId>
        <artifactId>html2pdf</artifactId>
        <version>2.0.2</version>
</dependency>

0x02:要转换的HTML文件 </head> <p>iText</p> <div><b>大发发发萨法发发呆发呆东方大厦发</b></div> <div style="font-family:SimSun;weight:normal">Your developer here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的journey with iText begins here法大大是地方大发顺丰萨法发顺丰的</div> <div style="font-family:SimSun;font-weight:bold">Your developer here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的journey with iText begins here法大大是地方大发顺丰萨法发顺丰的</div> <p>iText</p> <div><b>大发发发萨法发发呆发呆东方大厦发</b></div> <div style="font-family:宋体;weight:normal">Your developer here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的journey with iText begins here法大大是地方大发顺丰萨法发顺丰的</div> <div style="font-family:宋体;font-weight:bold">Your developer here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的here法大大是地方大发顺丰萨法发顺丰的journey with iText begins here法大大是地方大发顺丰萨法发顺丰的</div> </body>

0x03:编写代码

  • itext默认字体
public static void defaultFont() throws Exception{
        try {
            String pdfPath = "C:\\Users\\2230\\Desktop\\a\\defaultFont.pdf";
            PdfWriter pdfWriter = new PdfWriter(new File(pdfPath));
            PdfDocument pdfDocument = new PdfDocument(pdfWriter) ;
            Document doc = new Document(pdfDocument);
            pdfDocument.setDefaultPageSize(PageSize.A4);
            pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new TextFooterEventHandler(doc));
            ConverterProperties pro =  new ConverterProperties();
            FontProvider fontProvider = new DefaultFontProvider();
            fontProvider.addSystemFonts();
            pro.setFontProvider(fontProvider);
            HtmlConverter.convertToPdf(new FileInputStream("C:\\Users\\2230\\Desktop\\a\\d.html"), pdfDocument, pro);
        } catch (Exception e) {
            e.printStackTrace();

默认转换结果

  • 加载宋体

这里只加载了宋体,没有加载宋粗体

public static void songTiDefaultFont() throws Exception{
            String pdfPath = "C:\\Users\\2230\\Desktop\\a\\songTiDefaultFont.pdf";
            PdfWriter pdfWriter = new PdfWriter(new File(pdfPath));
            PdfDocument pdfDocument = new PdfDocument(pdfWriter) ;
            Document doc = new Document(pdfDocument);
            pdfDocument.setDefaultPageSize(PageSize.A4);
            pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new TextFooterEventHandler(doc));
            ConverterProperties pro =  new ConverterProperties();
            FontProvider fontProvider = new DefaultFontProvider();
            FontProgram fontProgram1 = FontProgramFactory.createFont("C:\\Users\\2230\\Desktop\\a\\simsun.ttc,1");
            fontProvider.addFont(fontProgram1);
            pro.setFontProvider(fontProvider);
            HtmlConverter.convertToPdf(new FileInputStream("C:\\Users\\2230\\Desktop\\a\\d.html"), pdfDocument, pro);
        } catch (Exception e) {
            e.printStackTrace();

发现转换出来的PDF,丢失了字体样式

分析原因发现 C:\Windows\Fonts 默认没有 宋体粗字体 ,默认只有 宋体常规

网上下载宋体粗字体 宋体-粗体.ttf, 下载的都是ttf格式;代码加载 宋体粗字体

public static void songTiDefaultFont() throws Exception{
            String pdfPath = "C:\\Users\\2230\\Desktop\\a\\songTiDefaultFont.pdf";
            PdfWriter pdfWriter = new PdfWriter(new File(pdfPath));
            PdfDocument pdfDocument = new PdfDocument(pdfWriter) ;
            Document doc = new Document(pdfDocument);
            pdfDocument.setDefaultPageSize(PageSize.A4);
            pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new TextFooterEventHandler(doc));
            ConverterProperties pro =  new ConverterProperties();
            FontProvider fontProvider = new DefaultFontProvider();
            FontProgram fontProgram1 = FontProgramFactory.createFont("C:\\Users\\2230\\Desktop\\a\\simsun.ttc,1");
            fontProvider.addFont(fontProgram1);
            //宋体粗体
            FontProgram fontProgram2 = FontProgramFactory.createFont("C:\\Users\\2230\\Desktop\\a\\宋体-粗体.ttf");
            fontProvider.addFont(fontProgram2);
            pro.setFontProvider(fontProvider);
            HtmlConverter.convertToPdf(new FileInputStream("C:\\Users\\2230\\Desktop\\a\\d.html"), pdfDocument, pro);
        } catch (Exception e) {
            e.printStackTrace();

多加了如下代码:

执行直接报错,字体无法加载

  • 把ttf转换成otf格式字体

在线转换工具: https://www.fontke.com/tool/convfont

public static void songConvertTiFont() throws Exception{
            String pdfPath = "C:\\Users\\2230\\Desktop\\a\\songTiFont.pdf";
            PdfWriter pdfWriter = new PdfWriter(new File(pdfPath));
            PdfDocument pdfDocument = new PdfDocument(pdfWriter) ;
            Document doc = new Document(pdfDocument);
            pdfDocument.setDefaultPageSize(PageSize.A4);
            pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new TextFooterEventHandler(doc));
            ConverterProperties pro =  new ConverterProperties();
            FontProvider fontProvider = new DefaultFontProvider();
            fontProvider.addSystemFonts();
            FontProgram fontProgram1 = FontProgramFactory.createFont("C:\\Users\\2230\\Desktop\\a\\simsun.ttc,0");
            fontProvider.addFont(fontProgram1);
            //宋体粗体
            FontProgram fontProgram2 = FontProgramFactory.createFont("C:\\Users\\2230\\Desktop\\a\\宋体-粗体.otf");
            fontProvider.addFont(fontProgram2);
            pro.setFontProvider(fontProvider);
            HtmlConverter.convertToPdf(new FileInputStream("C:\\Users\\2230\\Desktop\\a\\d.html"), pdfDocument, pro);
        } catch (Exception e) {
            e.printStackTrace();

转换结果

文章分享自微信公众号:
BUG弄潮儿

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

作者: java乐园
原始发表时间: 2020-06-12
如有侵权,请联系 cloudcommunity@tencent.com 删除。