ItextPdf Layout 7.2.3 添加水印
背景介绍
- 使用
Itextpdf Layout 7.2.3
,需要在Pdf
上添加水印 Itext 5
添加水印已经在之前的文章中有讲过,可以看这片文章:Itext5 常用 API- 使用
PdfCanvas
相关方法
文章目录
ItextPdf Layout
-
ItextPdf Layout
是iTextPdf
的一个特定版本或子模块,用于处理PDF
布局相关的功能。 -
ItextPdf Layout
提供了一系列用于创建和控制PDF
布局的功能,如添加文本、图像、表格等元素到PDF
页面。 -
它允许您指定每个元素的位置、大小和样式,并可以应用字体类型、颜色、对齐方式和间距等格式选项。
水印相关属性
属性 |
---|
透明度(0.0f -1.0f) |
水印字体类型 |
水印字体大小 (12px 单位:像素) |
水印字体颜色 (#d9d9d9) |
水印多行文本行间距 (10 单位:毫米) |
水印角度(-30 单位:度) |
水印横向间距(50 单位:毫米 )纵向间距(50 单位:毫米) |
maven 依赖
- 添加中文支持、和
Itext layout
相关依赖
<!-- pdf 中文支持 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!--itext-->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>layout</artifactId>
<version>7.2.3</version>
</dependency>
代码示例
水印效果图
ItextPdf
以左下角为原点(0,0) 开始计算坐标
完整代码
ItextPdf 7.2.3
添加水印示例- 可以设置水印是否只打印一个,还是填充完整整个打印页
- 设置水印的角度
- 设置多行水印上下的行距、居左、居右、居中显示
- 设置水印字体、颜色、大小
- 水印横向间距、纵向间距
/**
* 打印页面设置水印
*/
@Test
public void addWaterMark() throws IOException {
PdfWriter writer = new PdfWriter(new File(UUID.randomUUID()+FILENAME));
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc, PageSize.A4);
IBlockElement paragraph = new Paragraph("Hello, world!");
document.add(paragraph);
String waterMarkContent = "测试水印\n你好";
int numberOfPages = pdfDoc.getNumberOfPages();
// 角度
float angle = 0;
// 横向间距
float xSpacing = 100;
// 纵向间距
float ySpacing = 100;
// 透明度
float opacity = 0.5f;
// 多行水印文本行距
float lineSpacing = 0;
// 是否重重
Boolean repeat = true;
// 多行水印文本对齐方式
String textAlign = "LEFT";
// 水印大小
float watermarkFontSize = 12;
PdfFont watermarkFont = PdfFontFactory.createFont("src/main/resources/fonts/STSong.ttf", PdfEncodings.IDENTITY_H);
float x = xSpacing;
float y = ySpacing;
// 将水印内容按换行符分割成多行
String[] lines = waterMarkContent.split("\n");
// 文本长度数组
float[] textLength = new float[lines.length];
// 最长文本的索引
int maxLengthIndex = 0;
for (int i = 0; i < lines.length; i++) {
textLength[i] = watermarkFont.getWidth(lines[i], watermarkFontSize);
if (i > 0 && textLength[i] > textLength[i - 1]) {
maxLengthIndex = i;
}
}
String tempStr = Arrays.stream(lines).max(Comparator.comparing(String::length)).get();
for (int i = 1; i <= numberOfPages; i++) {
PdfPage page = pdfDoc.getPage(i);
Rectangle pageSize = page.getPageSize();
float pageWidth = pageSize.getWidth();
float pageHeight = pageSize.getHeight();
float watermarkWidth = watermarkFont.getWidth(tempStr, watermarkFontSize);
float watermarkHeight = getFontHeight(watermarkFont, watermarkFontSize);
PdfPage firstPage = pdfDoc.getFirstPage();
PdfCanvas canvas1 = new PdfCanvas(firstPage)
.setFillColor(ColorConstants.RED)
.setColor(ColorConstants.RED, true)
.setExtGState(new PdfExtGState().setFillOpacity(opacity));
float tempX = (x + watermarkWidth) / 2;
int rowNum = 1;
while (y + watermarkHeight < pageHeight) {
// 偶数行错行展示
if (rowNum % 2 == 0) {
x = x - tempX;
}
while (x + watermarkWidth < pageWidth) {
float tempY = y;
for (int j = 0; j < lines.length; j++) {
float textAlignX = 0;
// 实现居中居左居右的效果
if (j != maxLengthIndex) {
float maxLength = textLength[maxLengthIndex];
float currentLength = textLength[j];
if ("RIGHT".equals(textAlign)) {
textAlignX = maxLength - currentLength;
} else if ("CENTER".equals(textAlign)) {
textAlignX = (maxLength - currentLength) / 2;
}
}
x = x + textAlignX;
String line = lines[j];
canvas1.saveState()
.concatMatrix(new AffineTransform());
canvas1.concatMatrix(
StrictMath.cos(Math.toRadians(angle)), StrictMath.sin(Math.toRadians(angle)),
-StrictMath.sin(Math.toRadians(angle)), StrictMath.cos(Math.toRadians(angle)),
x, tempY
);
canvas1.beginText()
.setFontAndSize(watermarkFont, watermarkFontSize)
.showText(line)
.endText();
canvas1.restoreState();
// 多行文本行间距
tempY -= watermarkHeight + lineSpacing;
}
x += watermarkWidth + xSpacing;
// 水印重复
if (!Boolean.TRUE.equals(repeat)) {
break;
}
}
// 水印重复
if (!Boolean.TRUE.equals(repeat)) {
break;
}
x = xSpacing;
y += watermarkHeight * lines.length + ySpacing;
rowNum++;
}
}
pdfDoc.close();
}
颜色转换
#D9D9D9
截取16
进制的字符串、获取16
进制的数
/**
* 获取颜色的16进制的值
*
* @param color #D9D9D9
* @return int
*/
public static int colorValue(String color) {
String tempColor = color;
String[] split = tempColor.split("#");
if (split.length > 1) {
tempColor = split[split.length - 1];
} else {
tempColor = split[0];
}
return Integer.valueOf(tempColor, 16);
}
获取字体高度
- 注意使用与
ItextPdf 7.2.3
/**
* 获取字体高度
*
* @param font 字体
* @param fontSize 字体大小
* @return float
*/
public float getFontHeight(PdfFont font, float fontSize) {
FontMetrics fontMetrics = font.getFontProgram().getFontMetrics();
// 获取字体上升高度
float ascent = fontMetrics.getTypoAscender() * fontSize / fontMetrics.getUnitsPerEm();
// 获取字体下降高度
float descent = fontMetrics.getTypoDescender() * fontSize / fontMetrics.getUnitsPerEm();
// 计算行距
float leading = fontMetrics.getTypoAscender() - fontMetrics.getTypoDescender() + fontMetrics.getLineGap();
// 将行距和字体大小转换为实际单位
leading *= fontSize / fontMetrics.getUnitsPerEm();
float lineHeight = ascent - descent + leading;
// 输出字体行高
System.out.println("line height: " + lineHeight);
return lineHeight;
}
方法说明
saveState()
-
saveState
方法是iText
中的一个方法,用于保存当前的绘图状态。它会将当前的绘图状态(如颜色、字体、线宽等)保存到一个堆栈中,以便稍后可以恢复到该状态。 -
通过使用
saveState
和restoreState
方法,你可以在需要的时候保存和恢复绘图状态,以确保绘制的内容符合预期。
concatMatrix()
concatMatrix
方法是iText PDF
中用于将一个变换矩阵与当前变换矩阵进行连接的方法。通过这个方法,你可以对PDF
文档中的内容应用各种变换,如平移、旋转、缩放和倾斜。
PdfCanvas
PdfCanvas
类用于在PDF
文档上绘制图形元素和内容。它提供了各种方法来绘制线条、形状、文本、图像,并应用变换。
绘制方法
moveTo(x, y)
:将当前绘图位置移动到指定的坐标。lineTo(x, y)
:从当前位置绘制一条线到指定的坐标。rectangle(x, y, width, height)
:在指定位置和大小绘制矩形。circle(x, y, radius)
:在指定位置绘制给定半径的圆形。arc(x, y, radius, startAngle, endAngle)
:在指定位置、半径和角度绘制弧形。text(x, y, text)
:在指定位置绘制文本。
路径构造方法
newPath()
:开始一个新路径。closePath()
:关闭当前子路径。stroke()
:使用当前描边颜色和线宽描边路径。fill()
:使用当前填充颜色填充路径。
图形状态方法
setLineWidth(width)
:设置后续绘制操作的线宽。setStrokeColor(color)
:设置后续绘制操作的描边颜色。setFillColor(color)
:设置后续绘制操作的填充颜色。concatMatrix(a, b, c, d, e, f)
:将一个变换矩阵连接到当前变换矩阵上。
图像方法
addImage(image, x, y, width, height)
:在指定位置和大小添加图像到画布上。
颜色填充路径。
图形状态方法
setLineWidth(width)
:设置后续绘制操作的线宽。setStrokeColor(color)
:设置后续绘制操作的描边颜色。setFillColor(color)
:设置后续绘制操作的填充颜色。concatMatrix(a, b, c, d, e, f)
:将一个变换矩阵连接到当前变换矩阵上。
图像方法
addImage(image, x, y, width, height)
:在指定位置和大小添加图像到画布上。