背景
遇到个需求需要用Java导出PDF文件,权衡之下选择了iText,Java操作pdf的各个开源库之间的对比可以参考https://blog.csdn.net/u012397189/article/details/80196974
然后就是在pom文件中引包,网上很多都用iText5,这里我用新版的iText7
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.17</version>
</dependency>
这里附上iText7的官方文档中文翻译
https://github.com/iTextCN/itext7-in-mandarin
问题:
网上的教程大多采用这种写法,使用iText自带的中文jar包,但是结果是输出都是乱码。
PdfFont pdfFont = PdfFontFactory.createFont("STSongStd-Light", PdfEncodings.IDENTITY_H);
PdfWriter writer = new PdfWriter("./pdfTest.pdf");
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
Paragraph paragraph = new Paragraph();
paragraph.setFont(pdfFont).setFontSize(12);
paragraph.add("这是一段测试文字!");
document.add(paragraph);
document.close();
还有一个致命的问题是如果输出中文的省略号或者中文汉字“凉”,会直接报空指针。
解决:
我在网上尝试了很多解决方案,大多数是iText5的,有人说是iTextAsain包的版本要兼容,但是我尝试更改版本号后还是不行。某些方法能够输出中文,但是又会因为某些中文字符报空指针,始终不够完美,也不够简单。
这里提供一种最简单的方法解决问题,直接使用第三方的字体。
pom文件,只引入这个就够了
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.17</version>
</dependency>
Java文件
PdfFont pdfFont = PdfFontFactory.createFont("src/main/resources/fonts/Songti.ttc,1", PdfEncodings.IDENTITY_H);
//有问题
PdfFont pdfFont2 = PdfFontFactory.createFont("src/main/resources/fonts/simhei.ttf", PdfEncodings.UTF8);
//自带的全是乱码,而且中文省略号和中文"凉"字会直接报空指针
PdfFont pdfFont3 = PdfFontFactory.createFont("STSongStd-Light", PdfEncodings.IDENTITY_H);
PdfWriter writer = new PdfWriter("./SongtipdfTest.pdf");
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
Paragraph paragraph = new Paragraph();
paragraph.setFont(pdfFont).setFontSize(12);
paragraph.add(str);
document.add(paragraph);
document.close();
第一种用的是Mac系统自带的Songti字体文件,注意要有后面的,1。这个很坑,我也是看了源码才发现要加这个
第二种用的是windows系统自带的字体文件,但是还是有问题。
第三种用的是iText自带的,感觉完全不可用。