Java实现PDF导出

iText 5(用于创建PDF):

1
2
3
4
5
6

<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.2</version> <!-- 或者其他版本 -->
</dependency>

具体代码:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// 导入必要的包
import com.itextpdf.text.Document; // iText核心类,表示PDF文档
import com.itextpdf.text.PageSize; // 页大小设置
import com.itextpdf.text.Paragraph; // 段落元素
import com.itextpdf.text.Element; // 元素属性
import com.itextpdf.text.Font; // 字体设置
import com.itextpdf.text.pdf.BaseFont; // 基础字体,用于支持非拉丁字符集
import com.itextpdf.text.pdf.PdfPTable; // 表格元素
import com.itextpdf.text.pdf.PdfPCell; // 表格单元格
import com.itextpdf.text.pdf.PdfWriter; // PDF写入器,用于将内容写入PDF文件
import com.itextpdf.text.DocumentException; // iText异常处理
import java.io.File; // 文件操作
import java.io.FileOutputStream; // 文件输出流
import java.io.IOException; // IO异常处理
import org.springframework.web.multipart.MultipartFile; // Spring框架中的多部分文件接口

// 定义PDF文件保存的本地路径,使用唯一ID防止文件名冲突
String dest = "D:/upload/" + IdUtils.simpleUUID() + ".pdf"; // 替换为你的实际路径

// 确保目录存在
File dir = new File(dest).getParentFile();
if (!dir.exists()) {
dir.mkdirs(); // 创建所有必要的父目录
}

// 创建一个新的A4尺寸的Document对象,并设置页边距(左右上下均为50)
Document document = new Document(PageSize.A4, 50, 50, 50, 50);

try {
// 创建PdfWriter实例,指定本地文件路径
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();

// 加载中文字体(注意:这里需要替换为实际的字体文件路径)
BaseFont bfChinese = BaseFont.createFont("字体路径", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

// 设置字体,适当增大字体大小以提高可读性
Font font = new Font(bfChinese, 10, Font.NORMAL); // 正常字体
Font boldFont = new Font(bfChinese, 10, Font.BOLD); // 加粗字体

// 创建段落作为页面标题(单个标题),并设置居中对齐
Paragraph title = new Paragraph("标题", boldFont);
title.setAlignment(Element.ALIGN_CENTER);
document.add(title);

// 创建无框表格,3列表格,宽度占满页面,前后间距20
PdfPTable titleTable = new PdfPTable(3);
titleTable.setWidthPercentage(100);
titleTable.setSpacingBefore(20f);
titleTable.setSpacingAfter(20f);

// 设置列宽比例,让各列适应内容
float[] columnWidths = {2f, 2f, 2f};
titleTable.setWidths(columnWidths);

// 创建表格单元格,添加到表格中
PdfPCell cellSchool = new PdfPCell(new Paragraph("名称", font));
cellSchool.setHorizontalAlignment(Element.ALIGN_LEFT); // 内容左对齐
cellSchool.setBorder(Rectangle.NO_BORDER); // 移除边框
cellSchool.setPaddingTop(10f); // 增加上方内边距
titleTable.addCell(cellSchool);
document.add(titleTable);

// 创建一个2列的表格,并设置列宽比例
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(100); // 表格宽度占满页面
table.setSpacingBefore(20f);
table.setWidths(new float[]{1.5f, 3.5f}); // 第一列宽1.5份,第二列宽3.5份

// 添加行到表格
addRowToTable(table, new ArrayList<>(), font);

// 将表格添加到文档
document.add(table);

// 添加新页
document.newPage();

System.out.println("PDF created and saved to: " + dest);
} catch (DocumentException | IOException e) {
e.printStackTrace();
System.err.println("Error creating or saving the PDF file.");
} finally {
// 关闭文档和流
document.close();
}

addRowToTable:

1
2
3
4
5
6
7
8
// 辅助方法:将一行的名字添加到表格中
private static void addRowToTable(PdfPTable table, List<String> cells, Font font) {
for (String cellContent : cells) {
PdfPCell cell = new PdfPCell(new Phrase(cellContent, font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 单元格内容居中
table.addCell(cell);
}
}

加水印

调用方法(按自己需求调整字体大小,也就是50这个参数)

1
2
3
4
5
6
7
8
9
10
BaseFont baseFont=BaseFont.createFont("字体路径", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

// 创建PdfWriter实例,指定本地文件路径
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
// 添加水印
PdfContentByte waterMarkContent = writer.getDirectContentUnder();

//在建立新页面后调用添加水印
addWatermark(waterMarkContent, "水印内容", baseFont, 50, 45);

部分水印

1
2
3
4
5
6
7
8
9
10
11
12
private static void addWatermark(PdfContentByte content, String text, BaseFont baseFont, float fontSize, float rotation) throws DocumentException, IOException {
content.beginText();
// 设置字体和大小
content.setFontAndSize(baseFont, fontSize);
// 设置旋转角度
content.setTextMatrix(0, -rotation);
// 设置透明度
content.setGrayFill(0.75f); // 灰色
// 设置水印位置
content.showTextAligned(Element.ALIGN_CENTER, text, 298, 421, 45); // 调整坐标以适应页面
content.endText();
}

铺满水印

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
29
30
31
private void addWatermark(PdfContentByte content, String text, BaseFont baseFont, float fontSize, float rotation) throws DocumentException {
content.beginText();
content.setFontAndSize(baseFont, fontSize);
content.setTextMatrix(0, -rotation);

// 设置透明度
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.3f); // 设置透明度为30%
content.setGState(gs);

// 获取页面大小
Rectangle pageSize = content.getPdfWriter().getPageSize();

// 计算水印的位置
float x = 50; // 起始X坐标
float y = 50; // 起始Y坐标
float stepX = 200; // X方向的步长
float stepY = 200; // Y方向的步长

while (y < pageSize.getHeight()) {
x = 50;
while (x < pageSize.getWidth()) {
content.showTextAligned(Element.ALIGN_CENTER, text, x, y, rotation);
x += stepX;
}
y += stepY;
}

content.endText();
}