最近在做一个项目,项目的需求主要是根据不同的考试系统得出一份考生的综合性报告,并且后期希望易于下载、打印,那么容易打印的格式,最好的肯定是Word和PDF。word在java中不是很好实现,而且word下载后也容易被修改(有利有弊),JAVA中实现pdf用的最多的是itext,目前最新的版本是7.1.14,以前使用的是5.2.X的版本,升级到7以后有不少的改变,而且以前使用的时候,主要是修改别人现成的代码,从来没有整体的去了解itext,这次因为是全新的项目,并且是专门用于生成报告的,所以打算做一个PDF的框架,以后有PDF生成的需求,使用这个框架就可以把一些基础信息自动生成,例如目录、页眉页脚等,故最近系统的去学习了下ITEXT7。在学习的过程中,发现新版本还是有不少变化的,也有一些需要注意的事项,现记录下来,以备后期查阅。
一、itext7 jar引用
<properties>
<itext.version>7.1.14</itext.version>
</properties>
<dependencies>
<!-- itext7 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>kernel</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>io</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>forms</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>pdfa</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>pdftest</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>font-asian</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.18</version>
</dependency>
<!--itext7 html转pdf用到的包-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
下面介绍每一个jar文件:
kernel 和 io: 包含低层次常用的基础的函数
layout: 包含高层次的函数
forms: 有关AcorForms操作需要的函数库
pdfa: 有关PDF/A(电子文档标准)的相关操作
pdftest: test例子中所引用的库
除了这些常用的架包意外,还有一些其他可能的包:
barcodes: 当你想要创建bar code(条代码?)时使用
hyph: 当你想要文字有连字符时使用
font-asian: 当你想要用CJK字符时 (Chinese / Japanese / Korean)
sign: 当你想要使用电子签名是使用
ITEXT基础的使用方法就不多说了,可以去官网查看。
官网API: https://api.itextpdf.com/iText7/java/7.1.14/
二、中文字体显示
itext 默认是不显示中文的,要显示中文,需要嵌入中文字体。
PdfFontFactory.createFont("D:/itextpdf/SONGTI.TTF", PdfEncodings.IDENTITY_H, false)
参数:
fontProgram :要嵌入的字体路径位置
encoding :编码
embedded :是否将字体嵌入到文件中
注:当encoding是PdfEncodings.IDENTITY_H或PdfEncodings.IDENTITY_Y 时,embedded就不起作用了,字体始终会被嵌入
adobe默认包含几个非英文字体,如下图所示:
例如要使用默认的宋体,代码如下,并且要包含font-asian jar包
PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", false)
三、加入中文字体文件过大问题
一个PDF文档使用中文的地方肯定很多,如果在每次使用的时候,都调用createFont方法,那么会导致字体被嵌入多次,文件也会非常大。解决办法就是只要在最开始创建文档的时候,定义一个字体变量,后面每次用到此字体时都调用这个变量,那么字体就只会嵌入一次,那么文件就不会太大了。
四、右对齐
在5.X版本中,右对齐都是使用setHorizontalAlignment(Alignment.RIGHT) 方式,但是在7.X版本,此方法不成功,改用:add(new Tab()).addTabStops(new TabStop(1000, TabAlignment.RIGHT))
Paragraph nameParagraph = new Paragraph();
nameParagraph.add(new Tab()).addTabStops(new TabStop(1000, TabAlignment.RIGHT));
nameParagraph.add("右对齐");
五、空格的输入
在写入文字或有上下级层级模块时,下一级左侧需要留白处理,这种情况下一般通过类似上面的右对齐方式即可,如下代码
Paragraph p = new Paragraph();
p.add(new Tab());
p.addTabStops(new TabStop(12, TabAlignment.LEFT));
p.add("左侧留白文字")
这种写法在一种情况下有问题,即在写有层级的目录,并且目录多余1页,而第二层级的目录刚好在新的页面的第一个时,则不起作用,这种情况就要使用输入空白字符的方式,而itext 7输入中英文空格、 均无效,
可以通过输入“\u00a0” 字符达到这种效果。下面2张图,分别使用的是这2种方式,就可以看出目录里的第二层在翻页时显示是不一样的。
未完待续。。。。。。