说明:很多时候我们会使用itext 来导出pdf。其实我们最关心的无非是两个问题。1.如何快速使用itext导出pdf。2.使用哪个版本以及能否支持中文。
第一点我将在下一篇文章中写自己开发了一套报表打印后的收获,以及代码。这里主要说第二点。下面我先贴一段代码(这个是我从网上搜来的)。
Document document = new Document(); File file = new File("chinese.pdf"); System.out.println(file.getAbsolutePath()); OutputStream os = new FileOutputStream(file); PdfWriter.getInstance(document,os); document.open(); //方法一:使用Windows系统字体(TrueType) //BaseFont baseFont = BaseFont.createFont("C:/Windows/Fonts/SIMYOU.TTF",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); //方法二:使用iTextAsian.jar中的字体 //BaseFont baseFont = BaseFont.createFont("STSong-Light",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); //方法三:使用资源字体(ClassPath) String resourcePath ="/Users/nsh/IdeaProjects/dingcw/dingfinance-app/src/main/resources/font/simhei.ttf"; String mainPath = "/Users/nsh/IdeaProjects/dingcw/dingfinance-app/src/main/java/com/raycloud/dingfinance/app/simhei.ttf"; String targetPath ="/Users/nsh/IdeaProjects/dingcw/dingfinance-app/target/classes/font/simhei.ttf"; String absPath = "font/simhei.ttf"; BaseFont baseFont = BaseFont.createFont(targetPath,BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); Font font = new Font(baseFont); document.add(new Paragraph("解决中文问题了!",font)); document.close();
我觉得这个就是最简单的也是最经典的导出pdf的实现方式。其中第一种我没有试,因为我是mac。后面两个都试过是可以的,但是这里有一些坑需要注意。
1.使用方法二导出时,你可能会报错,如果你起网上查,好多是告诉你 编译然后修改itext的文件名称。其实完全不需要,只要看看自己项目中现在用的是哪个版本,我用的这两个版本是可以的。
<!-- itextpdf 导出pdf --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.11</version> </dependency> <!-- pdf导出中文需要用到 --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency>
如果你也换成了这两个版本还是不支持中文(具体的异常信息就不贴了),请注意你的maven依赖中是否有其他组件也内含了itext相关的jar,这个我当时也遇到了,头疼的要死。为什么别人的可以我的不行呢,后来仔细找maven中的依赖发现了问题。
<dependency> <groupId>com.qumoon</groupId> <artifactId>qumoon-job-queue</artifactId> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> </exclusion> </exclusions> </dependency>
在我引用的 qumoon-job-queue中也有itext,而他里边的是比较旧的版本,这里我们需要配置一个 <exclusion></exclusion> 如上图,将itext相关的忽略掉。如果去除掉其他版本的干扰,这个时候你应该已经可以使用第二种方法导出中文的pdf了。但是还有个小问题,就是我们用的这个是iTextAsian.jar的中文字体。这个字体显示中文没问题,但是显示数字时数字之间的间距太小了,而且在部分xp系统中数字格式会完全乱掉(生产环境客户实际反馈的问题
所以我们需要使用其他字体去显示,所以有了第三种实现方式。
2.第三种方式是我们使用自己的字体(支持中文的)去显示,这里也有一些问题。
(1).不要把 字体文件放在resource目录下,因为经过maven打包到target后文件部分内容会被替换,这里我是用python对打包前后的文件做了对比,果然发生了变化
因为这个字体文件中可能有一些我们项目中其他配置文件的关键字,所以会被替换掉。这样就导致itext初始化字体失败。但是这个路径可以使用绝对路径,也可以使用相对路径,但是注意不要放在resource目录下。我是放在webapp目录下了。我项目中用的字体文件是黑体,比之前的数字显示会好很多。另外如果你使用第三种方式还报错,请仔细看下错误信息如果是报文件不存在还是资源解析失败。因为itext写死了是从字体文件中取"name"属性(打断点从源码中可以看到),所以确保你的字体文件是正确的而且没有放到resource目录下。
这是我导出pdf遇到的问题,希望对你有所帮助。