itext之html2pdf

数坑:

  1. itext本身不支持中文
    1. 字体文件格式的不同ttc\ttf,造成加载方式差异
  2. itext7之前,官方jar不支持中文自动换行
    1. 排版调整,极其艰难
  3. itext不支持字体加粗
    1. 解决方式:导入加粗、非加粗两种字体
    2. 字体选择
  4. 严格要求html标签开闭
  5. itext7默认的透明度,拿粉色遮罩
  6. itext下划线问题

从html转pdf,难点主要在两种文件格式语法不一样。需要把html语法转换成pdf,那么html对于排版的规范、优化也必然要被支持。

由此造成工作的繁琐复杂。

1. 引入jar

1
2
3
# 包含itext7大多基本包

compile group: 'com.itextpdf', name: 'html2pdf', version: '2.1.1'

2. 中文字体支持

1
2
3
4
5
6
7
8
9
10
11
12
ConverterProperties properties = new ConverterProperties();
FontProvider font = new FontProvider();

// fontPath = "xxxxxxx/xxx/xxxx.ttf"
// fontPath = "xxxx/xxx/xxx.tcc,1" tcc是个字体合集,取其索引为1的
PdfFont pdfFont = PdfFontFactory.createTtcFont(fontPath, 1, PdfEncodings.IDENTITY_H,false, true);

font.addFont(pdfFont.getFontProgram());
// font.addSystemFonts();
properties.setFontProvider(font);

Optional<FontInfo> fontinfo = font.getFontSet().getFonts().stream().findFirst();

3. html2pdf

1
HtmlConverter.convertToPdf(htmlFile,outputPdf,properties);

4. 水印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
PdfDocument pdfDocument = new PdfDocument(new PdfReader(srcFile), new PdfWriter(targetFile));
doc = new Document(pdfDocument);

// 添加图层的属性配置
PdfExtGState gs1 = new PdfExtGState();
// 透明度设置
gs1.setFillOpacity(1f);

for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
// 条形码水印到pdf
ImageData imageData = ImageDataFactory.create(barCodePath);// 插入水印

// 相对定位使用
Rectangle pageSize = pdfDocument.getPage(i).getPageSize();
float x, y;
x = signConfig.getSignX() > 0 ? signConfig.getSignX().floatValue() :
pageSize.getWidth() + signConfig.getSignX().floatValue() - signConfig.getSignWidth().floatValue();
y = signConfig.getSignY() > 0 ? signConfig.getSignY().floatValue() :
pageSize.getHeight() + signConfig.getSignY().floatValue() - signConfig.getSignHeight().floatValue();

PdfCanvas pdfCanvas = new PdfCanvas(pdfDocument.getPage(i));
pdfCanvas.saveState();
pdfCanvas.setExtGState(gs1);
pdfCanvas.addImage(imageData, x, y, signConfig.getSignWidth().floatValue(), false);
pdfCanvas.restoreState();
}

doc.close();

5. 下划线

实现1

1
<u></u>
1
text-decoration: underline

效果如下(支持换行):

image-20181225165825747

实现2

1
border-bottom: 1px solid #949494;

效果如下(不支持换行,这里是手动分行):