目錄
依賴
創建單元格
表格數據行輔助添加方法
創建表頭單元格
創建下劃線
創建帶下劃線的文字
創建PDF
依賴
<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.4.2</version>
</dependency>
<dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.13</version>
</dependency>
<dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version>
</dependency>
創建單元格
/*** 創建單元格** @param text 顯示值* @param font 字體* @param horizontalAlign 值水平顯示位置(例:Element.ALIGN_CENTER => 居中)* @param verticalAlign 值垂直顯示位置(例:Element.ALIGN_MIDDLE => 居中)* @param minHeight 最小行高* @return PdfPCell*/private static PdfPCell createCell(String text, Font font, int horizontalAlign, int verticalAlign, float minHeight) {Paragraph para = new Paragraph(text, font);para.setAlignment(horizontalAlign);para.setLeading(para.getLeading() * 1.2f);PdfPCell cell = new PdfPCell(para);cell.setHorizontalAlignment(horizontalAlign);// 水平居中cell.setVerticalAlignment(verticalAlign);// 垂直居中cell.setMinimumHeight(minHeight); // 設置最小高度
// cell.setPadding(0);// 內邊距cell.setBorderWidth(0.5f);// 單元格邊框寬度cell.setNoWrap(false);// 自動換行return cell;}
表格數據行輔助添加方法
/*** 輔助添加表格數據行* @param table 表格* @param col1 列1值* @param col2 列2值* @param col3 列3值* @param font 字體*/private static void addTableRow(PdfPTable table, String col1, String col2, String col3, Font font) {// 有幾列幾個 table.addCell 方法table.addCell(createCell(col1, font, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f));table.addCell(createCell(col2, font, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f));table.addCell(createCell(col3, font, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f));}
/*** 輔助添加表格行數據* @param table 表格* @param tableHeaderNumber 表格表頭列數* @param font 字體* @param horizontalAlign 值水平顯示位置(例:Element.ALIGN_CENTER => 居中)* @param verticalAlign 值垂直顯示位置(例:Element.ALIGN_MIDDLE => 居中)* @param minHeight 最小行高* @param column 單元格數據,x列傳入x個使用【,】隔開*/private static void addTableRow(PdfPTable table,int tableHeaderNumber, Font font, int horizontalAlign, int verticalAlign, float minHeight, String... column) {if (column.length == 1 && column[0].isEmpty()) {// 只傳入一個【""】值if (tableHeaderNumber > 0) {// 表頭列數 <= 0 時,不創建空行數據for (int i = 0; i < tableHeaderNumber; i++) {// 根據表頭列數生成對應的空行數據,值為【" "】(為""時不會創建空行數據)table.addCell(createCell(" ", font, horizontalAlign, verticalAlign, minHeight));}}}else {for (String s : column) {table.addCell(createCell(s, font, horizontalAlign, verticalAlign, minHeight));}}}
創建表格表頭
/*** 創建表頭單元格** @param table 表* @param text 顯示值* @param font 字體* @param bgColor 單元格背景色* @param horizontalAlign 值水平顯示位置(例:Element.ALIGN_CENTER => 居中)* @param verticalAlign 值垂直顯示位置(例:Element.ALIGN_MIDDLE => 居中)* @param height 行高*/private static void createTableHeader(PdfPTable table, String text, Font font, BaseColor bgColor, int horizontalAlign, int verticalAlign, float height) {Paragraph para = new Paragraph(text, font);para.setAlignment(horizontalAlign);PdfPCell cell = new PdfPCell(para);cell.setBackgroundColor(bgColor);cell.setHorizontalAlignment(horizontalAlign);// 水平居中cell.setVerticalAlignment(verticalAlign);// 垂直居中cell.setMinimumHeight(height); // 設置最小高度cell.setBorderWidth(0.5f);// 單元格邊框寬度
// cell.setFixedHeight(height); // 固定行高,文字超出高度不會顯示
// cell.setPadding(8);// 內邊距
// cell.setNoWrap(false);// 自動換行table.addCell(cell);}
創建下劃線
/*** 創建下劃線** @param width 寬* @param font 字體* @return Chunk*/private static Chunk createUnderlineChunk(float width, Font font) {Chunk underlineChunk = new Chunk(" ");underlineChunk.setHorizontalScaling(width); // 設置寬度underlineChunk.setUnderline(0.5f, -1f);// param-1:線寬 param-2:線位置,基于行底部,負數下調正數上調underlineChunk.setFont(font);// 設置字體return underlineChunk;}
/*** 使用PdfContentByte自定義繪制下劃線** @param writer PdfWriter* @param width 寬度* @return Chunk*/private static Chunk createCustomDrawnLine(PdfWriter writer, float width) {// 創建一個空白Chunk作為占位符Chunk placeholder = new Chunk(" ");// 添加自定義繪制功能placeholder.setGenericTag(" ");writer.setPageEvent(new PdfPageEventHelper() {@Overridepublic void onGenericTag(PdfWriter writer, Document document,Rectangle rect, String text) {// 獲取畫布PdfContentByte canvas = writer.getDirectContent();canvas.saveState();// 設置下劃線樣式canvas.setLineWidth(0.5f);canvas.setColorStroke(BaseColor.BLACK);// 計算下劃線位置float y = rect.getBottom() - 3; // 在文本下方3點處float x1 = rect.getLeft();float x2 = x1 + width;// 繪制下劃線canvas.moveTo(x1, y);canvas.lineTo(x2, y);canvas.stroke();canvas.restoreState();}});return placeholder;}
創建帶下劃線的文字
/*** 創建帶下劃線的文字塊* @param text 文字* @param font 字體* @return Chunk*/private static Chunk createUnderlinedText(String text, Font font){Chunk textChunk = new Chunk(text, font);textChunk.setUnderline(0.5f, -1f);// 設置下劃線:線寬0.5,位置在基線下方1點return textChunk;}
創建PDF
創建 Document 對象、pdf寫入器
Document document = new Document(PageSize.A4, 90, 90, 80, 50);// 創建文檔對象(A4紙大小,邊距:左, 右, 上, 下)PdfWriter writer = PdfWriter.getInstance(document, Files.newOutputStream(Paths.get(dest)));// 創建PDF寫入器
// PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));PageNumberEventHandler eventHandler = new PageNumberEventHandler();writer.setPageEvent(eventHandler);// 打開文檔document.open();
設置字體,避免中文不顯示問題
// 字體,中文字體,避免文字不顯示BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);Font titleFont = new Font(baseFont, 18, Font.BOLD);// 標題字體Font subtitleFont = new Font(baseFont, 12);// 副標題字體Font contentFont = new Font(baseFont, 12);// 正文字體Font headerFont = new Font(baseFont, 12);// 表頭字體Font footerFont = new Font(baseFont, 12);// 頁腳字體
標題、副標題定義?
// 標題Paragraph title = new Paragraph("Leslie Lee", titleFont);title.setAlignment(Element.ALIGN_CENTER);// 左右居中title.setSpacingAfter(5f); // 設置段后間距document.add(title);// 副標題Paragraph subtitle = new Paragraph("(風華絕代)", subtitleFont);subtitle.setAlignment(Element.ALIGN_CENTER);subtitle.setSpacingAfter(25f);document.add(subtitle);
?正文段落
// 添加內容段落Paragraph content = new Paragraph();content.setAlignment(Element.ALIGN_JUSTIFIED); // 段落兩端對齊content.add(new Chunk("風華絕代、風流倜儻、玉樹臨風", contentFont));content.add(Chunk.NEWLINE);// 換行,兩個效果為空一行content.add(Chunk.NEWLINE);
?正文中添加帶下劃線的文字
content.add(createUnderlinedText(text,contentFont));// 正文添加帶下劃線的文字,需這樣單獨添加
表格——創建表格
PdfPTable table = new PdfPTable(3);// 創建表格 x列table.setWidthPercentage(100); // 表格寬度占頁面百分比table.setSpacingBefore(5f); // 表格前間距table.setSpacingAfter(10f); // 表格后間距table.setSplitLate(false); // 防止單元格在分頁時被拆分table.setSplitRows(true); // 允許行拆分
// table.setHeaderRows(1); // 前 x 行作為表頭,跨頁時重復
表格——創建表頭-上面的方法
addTableHeader(table, "代表作", headerFont, null, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f);// 添加表頭單元格,幾列就幾個 addTableHeader 方法addTableHeader(table, "時間", headerFont, null, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f);// 添加表頭單元格,幾列就幾個 addTableHeader 方法addTableHeader(table, "角色", headerFont, null, Element.ALIGN_CENTER, Element.ALIGN_MIDDLE, 25f);// 添加表頭單元格,幾列就幾個 addTableHeader 方法
?表格——創建單元格-上面的方法
addTableRow(table, "絕代風華", "1956-09-12", "Cheung Kwok Wing", contentFont);// 添加表格數據,幾行就幾個 addTableRow 方法
?添加頁腳
// 添加頁腳Paragraph footer = new Paragraph("【風華絕代】", footerFont);footer.setAlignment(Element.ALIGN_CENTER);document.add(footer);
?添加圖片
// 添加圖片(可選)try {String imagePath = "img.jpg"; // 替換為實際圖片路徑Image img = Image.getInstance(imagePath);img.scaleToFit(100, 100); // 調整圖片大小img.setAbsolutePosition(36, 36); // 左下角位置document.add(img);} catch (Exception e) {System.err.println("圖片添加失敗: " + e.getMessage());}
?關閉文檔
document.close();// 關閉文檔
?頁碼處理類
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;import java.io.IOException;/** 頁碼處理* @author Leslie Lee* @version 2003/04/01* @date 1956/09/12*/
public class PageNumberEventHandler extends PdfPageEventHelper {private final Font footerFont;// 頁腳字體private PdfTemplate totalPagesTemplate;// 用于存儲總頁數的模板private final BaseFont baseFont;// 基礎字體public PageNumberEventHandler() throws DocumentException, IOException {super();baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);footerFont = new Font(baseFont, 10, Font.NORMAL, BaseColor.DARK_GRAY);}@Overridepublic void onOpenDocument(PdfWriter writer, Document document) {totalPagesTemplate = writer.getDirectContent().createTemplate(30, 17);// 創建用于總頁數的模板}@Overridepublic void onEndPage(PdfWriter writer, Document document) {PdfContentByte canvas = writer.getDirectContent();// 獲取PDF內容canvas.saveState();// 保存當前狀態// 創建頁碼文本String footerText = writer.getPageNumber() + " /";// 當前頁碼// 設置頁腳位置(居中底部)float x = (document.left() + document.right()) / 2;// 文檔中間位置float y = document.bottom() - 20;// 文檔底部上移 20 的位置ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, new Phrase(footerText, footerFont), x, y, 0);// 添加頁碼文本float pageTextWidth = baseFont.getWidthPoint(footerText, 9);// 計算頁碼文本寬度// 添加總頁數模板(占位符)canvas.addTemplate(totalPagesTemplate, x + pageTextWidth / 2 + 3, y); // 計算位置 x為左右位置(數大越右、數小越左) y為垂直位置(減數為下調、加數為上調)// 添加"頁"字
// canvas.beginText();
// canvas.setFontAndSize(baseFont, 9);
// canvas.setColorFill(BaseColor.DARK_GRAY);
// canvas.showTextAligned(Element.ALIGN_CENTER, "頁", x + pageTextWidth / 2 + 22, y, 0);
// canvas.endText();// 添加頁碼左標題
// String titleText = "";
// ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(titleText, footerFont), document.left(), y, 0);// 添加頁碼右標題
// String companyText = "";
// ColumnText.showTextAligned(canvas, Element.ALIGN_RIGHT, new Phrase(companyText, footerFont), document.right(), y, 0);// 添加頁腳分隔線
// canvas.setLineWidth(0.5f);// 分隔線粗細
// canvas.setColorStroke(BaseColor.LIGHT_GRAY);// 灰色
// canvas.moveTo(document.left(), y + 10);// 坐標起點 參數1:開始位置(左右) 參數2:高度(上下) 正數上調負數下調
// canvas.lineTo(document.right(), y + 10);// 坐標終點 參數1:結束位置(左右) 參數2:高度(上下) 正數上調負數下調
// canvas.stroke();// 恢復狀態canvas.restoreState();}/*** 文檔關閉時,寫入總頁數到模板*/@Overridepublic void onCloseDocument(PdfWriter writer, Document document) {totalPagesTemplate.beginText();totalPagesTemplate.setFontAndSize(baseFont, 10);totalPagesTemplate.setColorFill(BaseColor.DARK_GRAY);totalPagesTemplate.showText(String.valueOf(writer.getPageNumber())); // 有幾頁封面就減幾,沒有封面不減totalPagesTemplate.endText();}
}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Leslie Lee 隨筆