先上個效果圖
因為做的項目涉及到數據預測,其中有大量打印業務來支撐實體店的運營,因為注重的是數據,要求簡潔,清晰,所以寫了個很簡單也很實用的工具類。
如果需要編寫樣式或者插入背景,都可以查閱itex官方文檔,進行擴展。
這個工具是基於 itext 寫的,主要作用是生成最簡潔的表格,選用的jar包版本是:
<dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>2.1.7</version> </dependency>
廢話就不多說了,直接貼代碼 PDFConstants.class
import java.awt.Color; import java.util.List; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPTable; public class PDFConstants { /** * PDF大標題字體 */ public static Font PDFTITLEFONT = new Font(null, 16, Font.BOLD); /** * PDF小標題字體 */ public static Font PDFTITLEFONT1 = new Font(null, 13, Font.NORMAL); /** * 表格寬度百分比 */ public static Integer WIDTHPERCENTAGE = 98; /** * 表格標題字體 */ public static Font TITLEFONT = new Font(null, 12, Font.COURIER); /** * 翻頁加載表頭 */ public static Integer HEADERROWS = 1; /** * 翻頁不加載表頭 */ public static Integer NOHEADERROWS = 0; /** * 表格內容字體 */ public static Font CONTENTFONT = new Font(null, 9, Font.NORMAL); /** * PDF表格樣式 */ private static PdfPCell cell = new PdfPCell(); /** * 獲取表格 */ public static PdfPCell getCell() { // 水平居中 cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 垂直居中 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 邊距 cell.setPadding(1); // 行高 cell.setMinimumHeight(22); // 不換行 // cell.setNoWrap(true); // 顏色淡化 cell.setBorderColor(Color.decode("#EBEEF5")); return cell; } /** * 獲取表格並賦值 */ public static PdfPCell getCell(Paragraph content) { cell = getCell(); // 設置內容 cell.setPhrase(content); return cell; } /** * @Description 生成PDF表格 * @param titleNum * 列數 * @param tableWidth * 列寬 * @param titles * 標題集合 * @param contents * 內容集合 * @param headerRows * 是否再次加載表頭 * @return * @throws Exception */ public static PdfPTable getPDFTable(int titleNum, int[] tableWidth, String[] titles, List<String> contents, int headerRows) throws Exception { // 創建表格對象 // 列數 PdfPTable table = new PdfPTable(titleNum); //表格寬度百分比 table.setWidthPercentage(WIDTHPERCENTAGE); // 列寬百分比 if (tableWidth != null) table.setWidths(tableWidth); // 翻頁加載表頭 if (headerRows == HEADERROWS) table.setHeaderRows(HEADERROWS); // 標題集合 String[] pdfTitles = titles; if (pdfTitles != null && pdfTitles.length > 0) { // 標題 for (String pdfTitle : pdfTitles) { PdfPCell title = getCell(new Paragraph(pdfTitle, TITLEFONT)); table.addCell(title); } } // 內容集合 List<String> pdfContents = contents; if (pdfContents != null && pdfContents.size() > 0) { // 內容 for (String pdfContent : pdfContents) { PdfPCell content = getCell(new Paragraph(pdfContent, CONTENTFONT)); table.addCell(content); } }
// 撐行數,否則最后一行會消失
table.addCell("");
table.completeRow();
return table; } }
分頁工具類 PDFMaker.class
import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfContentByte; import com.lowagie.text.pdf.PdfPageEventHelper; import com.lowagie.text.pdf.PdfTemplate; import com.lowagie.text.pdf.PdfWriter; /** * @Description 分頁工具 * @author ry * @date 2019年7月12日 */ public class PDFMaker extends PdfPageEventHelper { /** 這個PdfTemplate實例用於保存總頁數 */ public PdfTemplate tpl; /** 頁碼字體 */ public BaseFont helv; @Override public void onCloseDocument(PdfWriter writer, com.lowagie.text.Document arg1) { tpl.beginText(); tpl.setFontAndSize(helv, 12); tpl.setTextMatrix(0, 0); tpl.showText("" + (writer.getPageNumber() - 1)); tpl.endText(); } /* * (non-Javadoc) * * @see * com.lowagie.text.pdf.PdfPageEventHelper#onEndPage(com.lowagie.text.pdf * .PdfWriter, com.lowagie.text.Document) */ @Override public void onEndPage(PdfWriter writer, com.lowagie.text.Document document) { PdfContentByte cb = writer.getDirectContent(); cb.saveState(); String text = " Page " + writer.getPageNumber() + " of "; float textSize = helv.getWidthPoint(text, 9); float textBase = document.bottom(); cb.beginText(); cb.setFontAndSize(helv, 9); // for odd pagenumbers, show t cb.setTextMatrix(document.left(), textBase); cb.showText(text); cb.endText(); cb.addTemplate(tpl, document.left() + textSize, textBase); cb.restoreState(); } /* * (non-Javadoc) * * @see * com.lowagie.text.pdf.PdfPageEventHelper#onOpenDocument(com.lowagie.text * .pdf.PdfWriter, com.lowagie.text.Document) */ @Override public void onOpenDocument(PdfWriter writer, com.lowagie.text.Document arg1) { try { // initialization of the template tpl = writer.getDirectContent().createTemplate(100, 100); // tpl.setBoundingBox(new Rectangle(0, 0, 10, 10)); // initialization of the font helv = BaseFont.createFont("Helvetica", BaseFont.WINANSI, false); } catch (Exception e) { } } }
注意:網上大部分此工具類都會報錯,生成PDF失敗 Unbalanced save/restore state operators,這是因為調用了saveState()但是沒調用restoreState(),這里我已經修正了
拿出部分業務代碼做例子,使用這個工具是很簡單的
首先打開一個文檔
// 定義文件路徑 你可以完成過程后刪掉這個臨時文件 或者存在tmp里
File f = new File("xxxx/xxx.pdf"); FileOutputStream output = new FileOutputStream(f); // 實例化文檔對象 Document document = new Document(PageSize.A4, 0, 0, 0, 0); // 創建 PdfWriter 對象 文件的輸出路徑+文件的實際名稱 PdfWriter writer = PdfWriter.getInstance(document, output);
// 設置分頁
writer.setPageEvent(new PDFMaker()); document.open();// 打開文檔
Document有橫向屬性 使用方法是 PageSize.A4.rotate()這個rotate方法是個神奇的方法
后面四個數字對應的是邊距 分別是 左,右,上,下
生成table幾個傳參的例子
// 標題 String[] title = { "Min.", "SUN", "MON", "TUE", "WED", "THUR", "FRI", "SAT" }; // 列數 Integer titleNum = 8; // 列寬 int tableWidth[] = { 15, 15, 15, 10, 10, 12, 12, 11 };
//內容 List<String> contents = new ArrayList<String>(); //TODO 業務代碼填充contens // 獲取PDFTable PdfPTable table = PDFConstants.getPDFTable(titleNum, tableWidth, title, contents, 0);
//表格上間距 table.setSpacingBefore(0); //添加進文檔
document.add(table);
//關閉文檔
document.close();
如果大家有什么不解,或意見,歡迎在下方留言,樓主看到就會回復的,謝謝。