持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
哈喽,大家好,我是一条。
之前写过如何导入导出 excel ,在实际开发中,还会出现导出为 pdf 的需求,实现起来也很简单,今天就和大家聊一下实现步骤。
基于 spring boot 工程,过于基础的部分不做讲解,只说和导出 pdf 相关的部分。
pom
<!-- 核心导出类 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<!-- 去掉会无法加载中文字体 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
代码
接口
@GetMapping("/export/pdf")
public void exportPdf(HttpServletResponse response) {
// 持久层查询全量数据
List<Article> articleList = articleService.getAllArticle();
OutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(response.getOutputStream());
// 生成pdf文件核心方法
articleService.generatePdf(articleList, outputStream);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
核心方法
其原理大概是和制作表格一样,一行一行的去渲染,并不是限制做好模板在替换的方式。
从表头到表格,每行每个部分所占的列数,都规定好,程序按照我们设定好的步骤将表格画出来。
public void generatePdf(List<Article> articles, OutputStream outputStream) {
Document document = new Document();
try {
PdfWriter instance = PdfWriter.getInstance(document, outputStream);
document.open();
// 文字水印
// document.newPage();
// instance.setPageEvent(new TextWaterMark("一条coding"));
// 图片水印
// Resource resource = new ClassPathResource(pdfConfigProperties.getImage().getFile());
// instance.setPageEvent(new ImageWaterMark(resource.getURL().getPath()));
// 解决中文不显示问题
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
// 标题加粗
Font fontChina18 = new Font(bfChinese, 18, Font.BOLD);
Font fontChina15 = new Font(bfChinese, 15);
Font fontChina10 = new Font(bfChinese, 10);
// 获取pdf头文件信息
Map<String, String> headInfo = new HashMap<>();
headInfo.put("firstHeadInfo", "文章列表");
// 空格
Paragraph blank1 = new Paragraph(" ", new Font(bfChinese, 5));
Paragraph firstTitle = new Paragraph(headInfo.get("firstHeadInfo"), fontChina18);
firstTitle.setAlignment(Element.ALIGN_CENTER);// 居中
document.add(firstTitle);
// 添加空格
document.add(blank1);
// 3 创建表格
PdfPTable table = new PdfPTable(7);// 表格总共几列
table.setWidthPercentage(100);// 表格宽度为100%
PdfUtil.addTableCell(table, "名称", fontChina15, false, false, 0, 0);
PdfUtil.addTableCell(table, "目录", fontChina15, false, false, 0, 0);
PdfUtil.addTableCell(table, "观看", fontChina15, false, false, 0, 0);
PdfUtil.addTableCell(table, "喜欢", fontChina15, false, false, 0, 0);
PdfUtil.addTableCell(table, "标签", fontChina15, false, false, 0, 0);
// 这里跨两列,需要先把第一个 false 改成 true ,再设置具体跨几列
PdfUtil.addTableCell(table, "摘要", fontChina15, true, false, 2, 0);
articles.forEach(article -> {
PdfUtil.addTableCell(table, article.getName(), fontChina10, true, false, 0, 0);
PdfUtil.addTableCell(table, article.getCategoryId().toString(), fontChina10, true, false, 0, 0);
PdfUtil.addTableCell(table, article.getViewCount().toString(), fontChina10, true, false, 0, 0);
PdfUtil.addTableCell(table, article.getLikeCount().toString(), fontChina10, true, false, 0, 0);
PdfUtil.addTableCell(table, article.getLabel(), fontChina10, true, false, 0, 0);
PdfUtil.addTableCell(table, article.getDescription(), fontChina10, true, false, 2, 0);
});
document.add(table);
} catch (DocumentException | IOException e) {
e.printStackTrace();
} finally {
document.close();
}
}
效果图
文字水印
相当于一个工具类,传入水印的具体的文字即可。
也可以在配置文件设定好是否开启水印和水印文字,达到动态配置。
package com.yitiao.util;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import lombok.RequiredArgsConstructor;
import java.io.IOException;
@RequiredArgsConstructor
public class TextWaterMark extends PdfPageEventHelper {
private final String waterMarkText;
public void onEndPage(PdfWriter writer, Document document) {
try {
float pageWidth = document.right() + document.left();//获取pdf内容正文页面宽度
float pageHeight = document.top() + document.bottom();//获取pdf内容正文页面高度
//设置水印字体格式
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font waterMarkFont = new Font(base, 20, Font.BOLD, BaseColor.LIGHT_GRAY);
PdfContentByte waterMarkPdfContent = writer.getDirectContentUnder();
Phrase phrase = new Phrase(waterMarkText, waterMarkFont);
//两行三列
ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
pageWidth * 0.25f, pageHeight * 0.2f, 45);
ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
pageWidth * 0.25f, pageHeight * 0.5f, 45);
ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
pageWidth * 0.25f, pageHeight * 0.8f, 45);
ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
pageWidth * 0.65f, pageHeight * 0.2f, 45);
ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
pageWidth * 0.65f, pageHeight * 0.5f, 45);
ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
pageWidth * 0.65f, pageHeight * 0.8f, 45);
} catch (DocumentException | IOException de) {
de.printStackTrace();
}
}
}