java整合itext?pdf實(shí)現(xiàn)自定義PDF文件格式導(dǎo)出方式
背景需求
使用PDF導(dǎo)出指定人員對(duì)應(yīng)周次的打卡記錄,每周對(duì)應(yīng)星期幾打卡過(guò)就打“√”。
如下圖:

1、導(dǎo)入依賴
導(dǎo)入itextpdf依賴
<!-- itex PDF --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.3</version> </dependency>
2、使用代碼自定義導(dǎo)出
2.1 定義pdf數(shù)據(jù)vo對(duì)象
// vo對(duì)象
@Data
class DataVo {
/**
* 周次
*/
private String week;
/**
* 打卡次數(shù)
*/
private int count;
/**
* 周幾
*/
private List<Integer> days;
}2.2 itextpdf相關(guān)代碼
定義表格的列數(shù),同時(shí)定義每列的大小或者格式,然后再依次填充每個(gè)單元格數(shù)據(jù)
注意:需要保證填充每個(gè)單元格,即使沒(méi)數(shù)據(jù)也要填充空的數(shù)據(jù),否則出現(xiàn)文件格式不對(duì)
// itext pdf文件構(gòu)建
@PostMapping("/pdfExport")
public void exportPdf(HttpServletResponse response, MyAttendanceStatisticsDto dto) {
// 封裝好的業(yè)務(wù)數(shù)據(jù)
List<DataVo> vos = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
DataVo vo = new DataVo();
vo.setWeek("第"+i+"周");
vo.setCount(3);
vo.setDays(CollUtil.newArrayList(i,6,7));
vos.add(vo);
}
if(CollUtil.isNotEmpty(vos)) {
Rectangle pageSize = PageSize.A4.rotate();
Document document = new Document(pageSize);
try {
String title = "文件名"+ RandomUtil.randomString(5);
String fileName = URLEncoder.encode("文件名"+ RandomUtil.randomString(5), "UTF-8");
// 設(shè)置響應(yīng)文件類型PDF
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".pdf");
// 創(chuàng)建 PdfWriter 實(shí)例,將 PDF 內(nèi)容寫入 HTTP 響應(yīng)流,1.7版本
PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
writer.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
document.open();
// 中文字體
BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
Font font = new Font(baseFont, 12);
// 添加文檔標(biāo)題,居中,間距20,添加到文檔中
Paragraph pdfTitle = new Paragraph(title, font);
pdfTitle.setAlignment(Element.ALIGN_CENTER);
pdfTitle.setSpacingAfter(20f);
document.add(pdfTitle);
// 9 列的表格,寬度占滿整個(gè)頁(yè)面
PdfPTable table = new PdfPTable(9);
table.setWidthPercentage(100);
// 單獨(dú)設(shè)置前兩2寬度
float[] columnWidths = new float[9];
columnWidths[0] = 3f;
columnWidths[1] = 2f;
for (int i = 2; i < 9; i++) {
columnWidths[i] = 1f;
}
table.setTotalWidth(columnWidths);
// 添加帶斜線的單元格
PdfPCell splitCell = new PdfPCell();
// 綁定斜線事件
splitCell.setCellEvent(new DiagonalLineEvent());
// 設(shè)置單元格高度
splitCell.setFixedHeight(30f);
Paragraph day = new Paragraph("日", font);
day.setAlignment(Element.ALIGN_RIGHT);
splitCell.addElement(day);
Paragraph month = new Paragraph("周", font);
month.setAlignment(Element.ALIGN_LEFT);
month.setSpacingBefore(-15f);
splitCell.addElement(month);
table.addCell(splitCell);
// 添加第二列表頭“周打卡數(shù)”
PdfPCell cell2 = new PdfPCell(new Phrase("周打卡數(shù)", font));
cell2.setHorizontalAlignment(Element.ALIGN_CENTER);
cell2.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell(cell2);
for (int i = 1; i <= 7; i++) {
PdfPCell cell = new PdfPCell(new Phrase(String.valueOf(i), font));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell(cell);
}
for (DataVo vo : vos) {
PdfPCell monthCell = new PdfPCell(new Phrase(vo.getWeek(), font));
monthCell.setFixedHeight(20f);
monthCell.setHorizontalAlignment(Element.ALIGN_CENTER);
monthCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell(monthCell);
PdfPCell totalCell = new PdfPCell(new Phrase(String.valueOf(vo.getCount()), font));
totalCell.setHorizontalAlignment(Element.ALIGN_CENTER);
totalCell.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell(totalCell);
List<Integer> days = vo.getDays();
for (int i = 1; i <= 7; i++) {
PdfPCell cell = null;
if (days.contains(i)) {
cell = new PdfPCell(new Phrase("√", font));
} else {
cell = new PdfPCell(new Phrase("", font));
}
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
table.addCell(cell);
}
}
document.add(table);
} catch (Exception e) {
log.error("導(dǎo)出pdf文件"+e);
} finally {
if (document.isOpen()) {
document.close();
}
}
}
}3、測(cè)試結(jié)果
調(diào)用接口測(cè)試,響應(yīng)pdf文件打開(kāi)如下:

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java導(dǎo)出csv方法實(shí)現(xiàn)講解
這篇文章主要介紹了java導(dǎo)出csv的方法,客戶要求在項(xiàng)目中有導(dǎo)出CSV文件的功能,并且給出了如何在不知道如何在不知道對(duì)象類型(沒(méi)有應(yīng)用泛型)的List中如何得到對(duì)象的屬性值,下面就詳細(xì)說(shuō)下這個(gè)功能是如何實(shí)現(xiàn)的2013-12-12
Java基礎(chǔ)之?dāng)?shù)組的初始化過(guò)程
Java數(shù)組分為靜態(tài)和動(dòng)態(tài)初始化,靜態(tài)初始化中,程序員設(shè)定元素初始值,系統(tǒng)決定長(zhǎng)度;動(dòng)態(tài)初始化中,程序員設(shè)定長(zhǎng)度,系統(tǒng)提供初始值,數(shù)組初始化后長(zhǎng)度固定,存儲(chǔ)在堆內(nèi)存中,數(shù)組變量在棧內(nèi)存指向堆內(nèi)存數(shù)組對(duì)象,基本類型數(shù)組存儲(chǔ)數(shù)據(jù)值,引用類型數(shù)組存儲(chǔ)對(duì)象引用2024-10-10
Java中static與instance的區(qū)別及作用詳解
這篇文章主要為大家介紹了Java中static與instance的區(qū)別及作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
使用Zxing實(shí)現(xiàn)二維碼生成器內(nèi)嵌圖片
二維碼在現(xiàn)實(shí)中的應(yīng)用已經(jīng)很廣泛了,本文介紹了使用Zxing實(shí)現(xiàn)二維碼生成器內(nèi)嵌圖片,有需要的可以了解一下。2016-10-10
注意Java中?new?BigDecimal(double?val)?的使用
這篇文章主要介紹了注意Java中?new?BigDecimal(double?val)?的使用,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-07-07
Spring?Boot?lombok在高版本idea中注解不生效的解決辦法
這篇文章主要介紹了Spring?Boot?lombok在高版本idea中注解不生效的解決辦法,文中介紹了三種解決方案,分別是使用ptg插件生成方法、添加Lombok依賴或指定1.18.30版本并清除構(gòu)建配置,需要的朋友可以參考下2025-05-05

