Java-iText7-(2) 绘制文字段落(使用构建模块)
iText提供了两种位置文字的方式,一种是使用封装好的构建模块,相对简单方便;另一种是使用底层绘制接口,可以更加灵活地控制绘制过程。本文主要介绍使用构建模块绘制文字的方式。
0. 前置要求
- 掌握Java的基本语法
- 按照《iText7 Java环境配置》配置好了iText运行环境
- 了解iText创建文档的基本方法《Java-iText7-(1) 创建文档》
1. 使用Paragraph对象承接需要绘制的文本
最基本的的用法是这样
PdfWriter writer = new PdfWriter("/path/to/pdf.pdf");
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
document.add(new Paragraph("Hello World!"));
document.close();
第1、2、5行负责PDF文档的创建和关闭,它们都是底层接口的实现。第3行,创建了一个Document
对象,它是iText封装好的对象,可以使用非底层的构建模块进行文档创建。第4行,创建了一个Paragraph
段落,内容是Hello World,并且添加到创建的Document
文档中。以上程序将会生成如下的PDF文档。
对于很长的段落(超过一行),iText会自动进行换行,每一行的排版会按照水平对齐方式进行。这一点和Word的排版是相似的。水平对齐方式定义在TextAlignment
枚举类中,有LEFT
左对齐、CENTER
居中对齐、RIGHT
右对齐、JUSTIFY
两端对齐。
Paragraph para1 = new Paragraph("Alignment=JUSTIFIED: This is a long long long long long long long long sentence with so many words and characters in order to show auto line-break.");
para1.setTextAlignment(TextAlignment.JUSTIFIED);
document.add(para1);
Paragraph para2 = new Paragraph("Alignment=LEFT: This is a long long long long long long long long sentence with so many words and characters in order to show auto line-break.");
para2.setTextAlignment(TextAlignment.LEFT);
document.add(para2);
2. 字体与中文字符处理
iText默认的绘制字体是Helvetica。如果我们想使用Times New Roman(新罗马)字体绘制,就需要在创建Paragraph后,指定其绘制字体。iText的字体类是PdfFont
,通常使用工厂类PdfFontFactory
来创建。
Paragraph para3 = new Paragraph("This is a sentence using Times New Roman font.");
try {
document.add(para3.setFont(PdfFontFactory.createFont(StandardFonts.TIMES_ROMAN)));
} catch (IOException e) {
System.out.println("Font not found.");
}
Times New Roman字体是官方预设的字体之一,同样的预设字体有:
- StandardFonts.COURIER
- StandardFonts.COURIER_BOLD
- StandardFonts.COURIER_OBLIQUE
- StandardFonts.COURIER_BOLDOBLIQUE
- StandardFonts.HELVETICA
- StandardFonts.HELVETICA_BOLD
- StandardFonts.HELVETICA_OBLIQUE
- StandardFonts.HELVETICA_OBLIQUE
- StandardFonts.HELVETICA_BOLDOBLIQUE
- StandardFonts.SYMBOL
- StandardFonts.TIMES_ROMAN
- StandardFonts.TIMES_BOLD
- StandardFonts.TIMES_ITALIC
- StandardFonts.TIMES_BOLDITALIC
- StandardFonts.ZAPFDINGBATS
以上预设字体可以通过PdfFontFactory.createFont(String fontProgram)
创建。如果需要使用其他字体,我们可以通过字体文件来创建。创建方法为PdfFontFactory.createFont(String fontProgram, String encoding, boolean embedded)
。fontProgram为字体文件路径。encoding为字体对应的字符集,预设的字符集枚举类是PdfEncodings
。对于中文,encoding通常使用PdfEncodings.IDENTITY_H
,表示水平显示的Unicode字符集。embedded指定是否将字体嵌入PDF文档中。通常嵌入字体是一个比较好的选择,因为不嵌入字体的文档,在不具有此字体的计算机中将无法正常显示。
为Paragraph指定字体的方式很简单,只需调用Paragraph
对象的setFont(PdfFont font)
方法即可。CJK是中日韩语言的英文首字母。
PdfFont cjkFont = PdfFontFactory.createFont(
"path/to/cjkFont.otf", PdfEncodings.IDENTITY_H, true);
document.add(new Paragraph("使用合适的字体,除了英语,中文字符也可以使用;中国語に加えて、日本語も使用できます。").setFont(cjkFont));
这里可能有人会问,如果一篇文章都使用宋体,是不是每一个段落都需要setFont()
一下呢。答案肯定是否定的,我们可以为Document
对象设置一个默认字体,如果不在创建段落时显式地指定新字体,那么将会使用默认字体。上面的程序也等同于以下写法。
PdfFont cjkFont = PdfFontFactory.createFont(
"path/to/cjkFont.otf", PdfEncodings.IDENTITY_H, true);
document.setFont(cjkFont);
document.add(new Paragraph("使用合适的字体,除了英语,中文字符也可以使用;中国語に加えて、日本語も使用できます。"));
3. 字号
字号可以通过Paragraph
对象的setFontSize(Float fontSize)
方法设置。iText文字的默认字号是12.
Paragraph smallPara = new Paragraph("This is a small paragraph, font size is 8.").setFontSize(8.0F);
document.add(smallPara);
Paragraph largePara = new Paragraph("This is a large paragraph, font size is 18.").setFontSize(18.0F);
document.add(largePara);
同样地,我们可以通过document.setFontSize(Float fontSize)
设置文档的默认字体大小。
4. 粗体、斜体、下划线
粗体、斜体、下划线可以分别使用paragraph.setBold()
, paragraph.setItalic()
, paragraph.setUnderline()
来实现。
下划线除了基本下划线外,还可以指定下划线的厚度、颜色、位置等等。
Paragraph boldPara = new Paragraph("Bold paragraph 粗体").setBold().setFont(cjkFont);
document.add(boldPara);
Paragraph italicPara = new Paragraph("Italic paragraph 斜体").setItalic();
document.add(italicPara);
Paragraph underlinedPara = new Paragraph("Underlined paragraph 下划线").setUnderline();
document.add(underlinedPara);
Paragraph underlinedPara2 = new Paragraph("Underlined paragraph 自定义下划线").setUnderline(2.0F, -5.0F); // 指定下划线厚度为2,位置在基线下方5个单位
document.add(underlinedPara2);
粗体、斜体、粗斜体还可以通过使用只含粗体、斜体、粗斜体的字体文件实现。
5. 文字颜色
文字颜色可以通过paragraph.setFontColor(Color color)
进行设置。iText提供了一些预设基本颜色,定义在ColorConstants
枚举中,如下面的列表所示。
- BLACK = RGB(0, 0, 0)
- BLUE = RGB(0, 0, 255)
- CYAN = RGB(0, 255, 255)
- DARK_GRAY = RGB(64, 64, 64)
- GRAY = RGB(128, 128, 128)
- GREEN = RGB(0, 255, 0)
- LIGHT_GRAY = RGB(192, 192, 192)
- MAGENTA = RGB(255, 0, 255)
- ORANGE = RGB(255, 200, 0)
- PINK = RGB(255, 175, 175)
- RED = RGB(255, 0, 0)
- WHITE = RGB(255, 255, 255)
- YELLOW = RGB(255, 255, 0)
iText预设的颜色均是按照RGB颜色空间设置的,适合屏幕的显示。iText还支持如适合印刷的CMYK颜色以及灰度颜色Gray。这里使用RGB作为介绍。
我们可以通过new DeviceRgb(Integer red, Integer green, Integer blue)
的方式创建一个自定义颜色,并且通过setFontColor(color)
方法为段落设置文字颜色。
Paragraph redPara = new Paragraph("Paragraph in red color").setFontColor(ColorConstants.RED);
document.add(redPara);
Paragraph purplePara = new Paragraph("Paragraph in purple color(#6A0DAD)").setFontColor(new DeviceRgb(106, 13, 173));
document.add(purplePara);
6. 自由位置的文字(文本框)
段落既可以按照一段一段从上向下排布,也可以像Word中的文本框一样,自由出现在文档的各个位置。我们可以使用paragraph.setFixedPosition(float left, float bottom, float width)
来指定一个段落出现的横纵坐标以及文本宽度。需要注意,第一个参数left
是文本框左下角距离页面左边缘的距离,第二个参数bottom
是文本框左下角距离页面底部的距离。
Paragraph floatPara = new Paragraph("This is a floating paragraph which is not aligned as normal...")
.setFixedPosition(0, pdf.getDefaultPageSize().getHeight()-100, pdf.getDefaultPageSize().getWidth()/2);
document.add(floatPara);
7. 多个样式的组合方式
前面讲到的每个方法具有一个特点,它们的返回值都是Paragraph对象本身(也就是this)。因此,我们可以利用这个特点将多个样式的设置语句链接式地写出来。
下面的代码设置了一个段落的字体是前面定义的cjkFont,字号是20,颜色是绿色,加粗,加下划线,自由位置为(100, 100),宽度为页面宽度减掉文档的左右边距。
Paragraph combinedPara = new Paragraph("Combined paragraph.")
.setFont(cjkFont)
.setFontSize(20.0F)
.setFontColor(ColorConstants.GREEN)
.setBold()
.setUnderline()
.setFixedPosition(100, 100, pdf.getDefaultPageSize().getWidth()-document.getLeftMargin()-document.getRightMargin())
8. 行间距
在iText中,行间距(Leading)指的是本行基线(baseline)与上一行基线之间的距离。基线主要用于在西欧文字中。学习英语时,书写英语字母的四线三格纸的红色线(从上面数第3条),就是英文字母的基线。一些字母,如p、q的一部分是在基线的下方。
行间距可以使用paragraph.setFixedLeading(Float leading)
或paragraph.setMultipliedLeading(Float leading)
进行设置。它的默认值是1.5倍的字体大小;由于默认字体大小为12,默认的固定行间距就是18. 根据定义,行间距是两行基线的距离,因此它需要大于等于本行的字体大小。setFixedLeading()
使用绝对大小进行设置,不论使用的字体大小是多大;setMultipliedLeading()
使用相对大小进行设置,设置值为字体大小的倍数。
这两种方法在使用时不能混用; 并且只有第一次设置的行间距会生效(可能是bug?)。
Paragraph basePara = new Paragraph("This is a base line paragraph.");
document.add(basePara);
Paragraph smallLineSpacePara = new Paragraph("Line space = 3.0 * font size").setMultipliedLeading(3.0F);
document.add(smallLineSpacePara);
9. 其他样式
- paragraph.setFirstLineIndent(float indent): 首行缩进大小
- paragraph.setBackgroundColor(Color color): 设置背景颜色
- paragraph.setBorder(Border boder): 设置段落边框
- paragraph.setMargin系列(Margin, MarginTop, MarginLeft, MarginBottom, MarginRight, Margins): 设置段落外缩进
- paragraph.setMaxWidth(float width):设置段落最大宽度
- paragraph.setMahHeight(float height): 设置段落最大高度
- paragraph.setPadding系列:设置段落内缩进
- paragraph.setRotationAngle(float angleInRaduis):设置段落旋转角度,以弧度为单位
- 等等等等
10. 一个段落,多种样式的文本
前面我们是对段落Paragraph
设置样式,那么这个段落的全部文字都会应用设置的样式。如果一个段落中要有多种样式的文本,我们依然需要Paragraph
对象来承接一个段落中的文本。不同的是,我们不是直接为这个paragraph
来设置样式,而是创建Text
类的对象text,为这个text设置样式,最后将这些创建好样式的texts按顺序加入paragraph。用法参考下面的例子:
Paragraph combinedPara = new Paragraph();
Text boldText = new Text("I am bold. ").setBold();
combinedPara.add(boldText);
Text italicText = new Text("I am italic. ").setItalic();
combinedPara.add(italicText);
Text blueText = new Text("I am blue. ").setFontColor(ColorConstants.BLUE);
combinedPara.add(blueText);
Text largeText = new Text("I am large. ").setFontSize(20.0F);
combinedPara.add(largeText);
document.add(combinedPara);