文章目录
-
-
- 一、环境准备与Maven依赖说明
- 二、核心代码解析
-
- [1. 基础文档创建](#1. 基础文档创建)
- [2. 中文字体处理](#2. 中文字体处理)
- [3. 复杂表格创建](#3. 复杂表格创建)
- [4. 图片插入](#4. 图片插入)
- 三、完整代码示例
- 四、最终效果
-
这篇主要说一下如何使用Java生成pdf,包括标题,文字,图片,表格的插入和调整等相关内容。
一、环境准备与Maven依赖说明
这里我使用的是iTextPDF,依次添加下面的依赖
核心依赖说明:
xml
<!-- pdf:start -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
<!-- 支持中文 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!-- 支持css样式渲染 -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.1.16</version>
</dependency>
<!-- 转换html为标准xhtml包 -->
<dependency>
<groupId>net.sf.jtidy</groupId>
<artifactId>jtidy</artifactId>
<version>r938</version>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.3</version>
</dependency>
<!-- Jetty WebSocket支持 -->
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
<version>9.4.44.v20210927</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>9.4.44.v20210927</version>
</dependency>
<!-- Apache HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
二、核心代码解析
1. 基础文档创建
文档的创建:
java
// 创建A4文档,设置页边距(左、右、上、下)
Document document = new Document(PageSize.A4, 40, 40, 40, 40);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
// 必须显式打开文档
document.open();
2. 中文字体处理
字体调整:
java
// 使用内置STSong-Light字体
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font bodyFont = new Font(bf, 12);
// 推荐做法:使用外部字体文件
BaseFont externalFont = BaseFont.createFont("fonts/SourceHanSansCN-Regular.ttf",
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED);
3. 复杂表格创建
表格创建:
java
// 创建5列表格,设置列宽比例
float[] colWidths = {2f, 1.5f, 1.5f, 1.5f, 1.5f};
PdfPTable table = new PdfPTable(colWidths);
// 设置表格占页面宽度的100%
table.setWidthPercentage(100);
// 添加表头
addTableHeader(table, new String[]{"指标", "Q1", "Q2", "Q3", "Q4"}, headerFont);
// 添加数据行
addTableRow(table, new String[]{"响应时间(ms)", "230", "180", "150", "120"}, bodyFont);
4. 图片插入
插入本地图片:
java
// 推荐使用相对路径
String imagePath = "src/main/resources/charts/tech_trend.png";
// 自动缩放适应宽度
Image image = Image.getInstance(imagePath);
image.scaleToFit(document.getPageSize().getWidth() - 80, Float.MAX_VALUE);
image.setAlignment(Image.ALIGN_CENTER);
// 添加图片描述
Paragraph caption = new Paragraph("图1 2023年季度性能趋势对比", captionFont);
caption.setAlignment(Element.ALIGN_CENTER);
document.add(caption);
document.add(image);
三、完整代码示例
下面是完整的代码示例,可以直接调整使用
java
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.LineSeparator;
import com.ruoyi.RuoYiApplication;
import com.ruoyi.common.utils.http.HttpUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.*;
import java.text.ParseException;
@RunWith(SpringRunner.class)
@SpringBootTest(classes= RuoYiApplication.class)
public class pdfDemoTest5 {
/**
* PDF生成- 公司年度技术报告
*/
@Test
public void generateDemoPdf() throws Exception {
// 文档设置(调整页边距)
Document document = new Document(PageSize.A4, 40, 40, 40, 40);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("tech_report_demo.pdf"));
// 创建中文字体
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
// 定义字体样式
Font redTitleFont = new Font(bf, 20, Font.BOLD, BaseColor.RED);
Font programFont = new Font(bf, 16, Font.BOLD);
Font sectionFont = new Font(bf, 14, Font.BOLD);
Font bodyFont = new Font(bf, 12);
Font tableHeaderFont = new Font(bf, 12, Font.BOLD);
Font contactFont = new Font(bf, 11, Font.BOLD);
document.open();
// ========== 标题区块 ==========
Paragraph program = new Paragraph();
program.add(new Chunk("2023年度技术发展报告\n", programFont));
program.add(new Chunk("科技创新与数字化转型", programFont));
program.setAlignment(Element.ALIGN_CENTER);
program.setSpacingAfter(15f);
document.add(program);
// 红色主标题(带下划线)
Paragraph mainTitle = new Paragraph("技术研发中心年度报告", redTitleFont);
mainTitle.setAlignment(Element.ALIGN_CENTER);
mainTitle.setSpacingAfter(10f);
document.add(mainTitle);
// ========== 期号信息 ==========
Paragraph issue = new Paragraph();
issue.add(new Chunk("[2023]年度报告", bodyFont));
issue.add(new Chunk(" ", bodyFont)); // 空格占位
issue.add(new Chunk("发布日期:[2024]年[1]月[15]日", bodyFont));
issue.setAlignment(Element.ALIGN_RIGHT);
document.add(issue);
// 添加下划线效果
Chunk underline = new Chunk(new LineSeparator(1.5f, 100f, BaseColor.RED, Element.ALIGN_CENTER, -1));
document.add(underline);
// ========== 报告标题 ==========
Paragraph reportTitle = new Paragraph(
"2023年度技术研发成果与2024年展望",
sectionFont);
reportTitle.setAlignment(Element.ALIGN_CENTER);
reportTitle.setSpacingBefore(15f);
reportTitle.setSpacingAfter(20f);
document.add(reportTitle);
// ========== 正文内容 ==========
// 年度总结部分
addSection(document, "1. 年度技术成果总结", sectionFont,
"2023年,我司在人工智能、大数据分析和云计算领域取得了显著进展。主要成果包括完成了新一代智能分析平台的开发,实现了数据处理效率提升300%;发布了基于机器学习的预测模型,准确率达到行业领先水平;完成了核心系统的云原生改造,系统稳定性提升至99.99%。", bodyFont);
// 技术指标部分
addSection(document, "2. 关键技术指标", sectionFont, "", bodyFont);
// 表格样式优化
float[] colWidths = {2f, 1.5f, 1.5f, 1.5f, 1.5f};
// 创建表格标题
Paragraph tableCaption = new Paragraph("表1 2023年关键技术指标对比", bodyFont);
tableCaption.setAlignment(Element.ALIGN_CENTER);
tableCaption.setSpacingBefore(10f);
tableCaption.setSpacingAfter(5f);
document.add(tableCaption);
// 创建表格
createComparisonTable(document,
new String[]{"系统响应时间(ms)", "230", "180", "150", "120"},
new String[]{"数据处理量(TB/天)", "5.2", "8.7", "12.4", "15.8"},
colWidths, tableHeaderFont, bodyFont);
// ========== 技术趋势图 ==========
Paragraph imageParagraph = new Paragraph();
imageParagraph.setSpacingBefore(20f);
imageParagraph.add(new Chunk("图1 2023年技术发展趋势", bodyFont));
imageParagraph.setAlignment(Element.ALIGN_CENTER);
document.add(imageParagraph);
// 插入本地图片(示例)
String localImagePath = "D:\\test.jpg";
Image localImage = Image.getInstance(localImagePath);
localImage.scaleToFit(400, 250);
localImage.setAlignment(Image.ALIGN_CENTER);
document.add(localImage);
// ========== 未来展望 ==========
addSection(document, "3. 2024年技术发展规划", sectionFont,
"2024年,我们将重点布局以下领域:\n\n" +
"• 人工智能:深化自然语言处理技术应用\n" +
"• 边缘计算:构建分布式计算网络\n" +
"• 数据安全:实施零信任安全架构\n" +
"• 云原生:全面容器化改造\n\n" +
"预计2024年研发投入将增长30%,重点培养高端技术人才50名。", bodyFont);
// ========== 联系方式 ==========
Paragraph contacts = new Paragraph();
contacts.add(new Chunk("技术咨询:", contactFont));
contacts.add(new Chunk(" 400-123-4567 ", bodyFont));
contacts.add(new Chunk("电子邮箱:", contactFont));
contacts.add(new Chunk("[email protected]\n", bodyFont));
contacts.add(new Chunk("公司地址:", contactFont));
contacts.add(new Chunk("北京市海淀区科技园区88号 创新大厦B座", bodyFont));
contacts.setSpacingBefore(20f);
document.add(contacts);
document.close();
}
// 辅助方法:添加章节
private void addSection(Document doc, String title, Font titleFont, String content, Font bodyFont) {
try {
Paragraph section = new Paragraph(title, titleFont);
section.setSpacingBefore(15f);
doc.add(section);
if(!content.isEmpty()) {
Paragraph text = new Paragraph(content, bodyFont);
text.setSpacingAfter(15f);
doc.add(text);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
// 辅助方法:创建对比表格
private void createComparisonTable(Document doc,
String[] row1, String[] row2,
float[] colWidths, Font headerFont, Font bodyFont) {
try {
PdfPTable table = new PdfPTable(colWidths);
table.setWidthPercentage(100);
table.setSpacingBefore(0f); // 标题与表格的间距由外部控制
table.setSpacingAfter(15f);
// 表头
addTableHeader(table, new String[]{"省份", "河南省", "河北省", "山东省", "江苏省", "安徽省"}, headerFont);
// 数据行
addTableRow(table, row1, bodyFont);
addTableRow(table, row2, bodyFont);
doc.add(table);
} catch (DocumentException e) {
e.printStackTrace();
}
}
// 辅助方法:添加表头
private void addTableHeader(PdfPTable table, String[] headers, Font font) {
for (String header : headers) {
PdfPCell cell = new PdfPCell(new Paragraph(header, font));
cell.setBackgroundColor(new BaseColor(240, 240, 240));
cell.setPadding(5);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);
}
}
// 辅助方法:添加表格行
private void addTableRow(PdfPTable table, String[] data, Font font) {
for (String item : data) {
PdfPCell cell = new PdfPCell(new Paragraph(item, font));
cell.setPadding(5);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);
}
}
}
四、最终效果
这个就是上面代码生成的最终的pdf的效果图
