1、目標
在pdf中產生一個可變表頭的表格,並向其中填充資料。通過泛型動態產生表頭,通過反射動態擷取實體類(我這裡是User)的get方法動態獲得資料,從而達到動態產生表格。
每天產生一個檔案夾儲存產生的pdf檔案(檔案夾的命名是年月日時間戳記),如:20151110
產生的檔案可能在毫秒層級,故檔案的命名規則是"到毫秒的時間戳記-uuid",如:20151110100245690-ece540e5-7737-4ab7-b2d6-87bc23917c8c.pdf
通過讀取properties檔案動態擷取檔案儲存體的跟目錄。
2、所需的jar
這裡通過itex外掛程式進行pdf的產生,需要的jar包括以下幾個
3、編碼實現
1)、實體類
package com.zcr.until;public class User { private String name; private int age ; private float height; private String adress; private String sex; private String jj; public String getJj() { return jj; } public void setJj(String jj) { this.jj = jj; } public User() { } public User(String name,int age,float height,String adress,String sex,String jj) { this.name = name; this.age = age; this.height = height; this.adress = adress; this.sex = sex; this.jj = jj; } public String getAdress() { return adress; } public void setAdress(String adress) { this.adress = adress; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public float getHeight() { return height; } public void setHeight(float height) { this.height = height; } }
2)、properties檔案
pdfPath=E\:/appDataPdf
3)、讀取properties檔案,擷取pdf儲存的路徑
package com.zcr.until;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.util.Properties;public class GetFilePlace { /** * 讀取檔案,擷取excel儲存的根目錄 * @return excel儲存的根目錄 */ public String getFilePath() { String dir = System.getProperty("user.dir"); //獲得tomcat所在的工作路徑 //擷取到儲存了檔案儲存體位置的filedir.properties 檔案路徑 --->java Project的檔案路徑 String realDir = dir + File.separator + "src" + File.separator +"META-INF" + File.separator + "filedir.properties"; //Web project儲存路徑 /*String realDir = dir.substring(0, dir.length()-4) + File.separator +"webapps" + File.separator + "generateExcels" + File.separator + "classes" + File.separator + "META-INF" + File.separator + "config" + File.separator + "filedir.properties"; */ return realDir; } /** * 擷取filePath路徑【properities檔案】中key對應的值, * @param filePath properities檔案路徑【包含properities檔案】 * @param key 要尋找的key值 * @return key對應的value */ public String GetValueByKey(String filePath, String key) { Properties pps = new Properties(); try { InputStream in = new BufferedInputStream (new FileInputStream(filePath)); pps.load(in); String value = pps.getProperty(key); in.close(); return value; }catch (IOException e) { e.printStackTrace(); return null; } } /** * 查詢properities檔案中可以對應的儲存地點 * @param key 查詢主鍵 * @return key對應的儲存地址 */ public String getFileDirFromProperties(String key) { return GetValueByKey(getFilePath(),key); }}
4)、擷取當天存在的檔案路徑,不存在則產生一個新的檔案夾
package com.zcr.service;import java.io.File;import java.text.SimpleDateFormat;import java.util.Calendar;public class GenerateFold{ /** * 查詢當前產生的excel需要存在在哪個路徑,如果存在則儲存在相應的位置,否則產生改目錄, 每天產生一個檔案夾,檔案夾的命名規則為 年月日的時間戳記 * @param foldName 產生excel儲存路徑 * @return 現在的excel需要儲存路徑 */ public String getFold(String foldName) { SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd"); String todayStr = format.format(Calendar.getInstance().getTime()); String foldPath = foldName + File.separator + todayStr; File file = new File(foldPath); if(!file.exists() && !file.isDirectory()) { System.out.println("不存在"); file.mkdirs(); } else { System.out.println("存在"); } return foldPath; }}
5)、組建檔案的名字
package com.zcr.until;import java.io.File;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.UUID;/** * 組建檔案名字 * @author zcr * */public class GenerateFileName{ /** * 根據檔案類別組建檔案的名字,檔案的命名規則是:檔案目錄/產生時間-uuid(全球唯一編碼).檔案類別 * @param fileDir 檔案的儲存路徑 * @param fileType 檔案的類別 * @return 檔案的名字 */ public String generateFileName(String fileDir,String fileType) { String saveFileName = ""; SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSS"); saveFileName += format.format(Calendar.getInstance().getTime()); UUID uuid = UUID.randomUUID(); //全球唯一編碼 saveFileName += "-" + uuid.toString(); saveFileName += "." + fileType; saveFileName = fileDir + File.separator + saveFileName; return saveFileName; }}
6)、產生pdf
package com.zcr.service;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;import com.lowagie.text.Document;import com.lowagie.text.DocumentException;import com.lowagie.text.Element;import com.lowagie.text.Font;import com.lowagie.text.PageSize;import com.lowagie.text.Phrase;import com.lowagie.text.pdf.BaseFont;import com.lowagie.text.pdf.PdfPCell;import com.lowagie.text.pdf.PdfPTable;import com.lowagie.text.pdf.PdfWriter;import com.zcr.until.GenerateFileName;import com.zcr.until.GetFilePlace;import com.zcr.until.User;/** * 產生pdf * @author zcr * */public class CreatePdf{ Document document = new Document();// 建立一個Document對象 private static Font headfont;// 設定字型大小 private static Font keyfont;// 設定字型大小 private static Font textfont;// 設定字型大小 static { //中文格式 BaseFont bfChinese; try { // 設定中文顯示 bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED); headfont = new Font(bfChinese, 10, Font.BOLD);// 設定字型大小 keyfont = new Font(bfChinese, 8, Font.BOLD);// 設定字型大小 textfont = new Font(bfChinese, 8, Font.NORMAL);// 設定字型大小 } catch (Exception e) { e.printStackTrace(); } } /** * 文成檔案 * @param file 待產生的檔案名稱 */ public CreatePdf(File file) { document.setPageSize(PageSize.A4);// 設定頁面大小 try { PdfWriter.getInstance(document, new FileOutputStream(file)); document.open(); } catch (Exception e) { e.printStackTrace(); } } public CreatePdf() { } public void initFile(File file) { document.setPageSize(PageSize.A4);// 設定頁面大小 try { PdfWriter.getInstance(document, new FileOutputStream(file)); document.open(); } catch (Exception e) { e.printStackTrace(); } } int maxWidth = 520; /** * 為表格添加一個內容 * @param value 值 * @param font 字型 * @param align 對齊 * @return 添加的文字框 */ public PdfPCell createCell(String value, Font font, int align) { PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setHorizontalAlignment(align); cell.setPhrase(new Phrase(value, font)); return cell; } /** * 為表格添加一個內容 * @param value 值 * @param font 字型 * @return 添加的文字框 */ public PdfPCell createCell(String value, Font font) { PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setPhrase(new Phrase(value, font)); return cell; } /** * 為表格添加一個內容 * @param value 值 * @param font 字型 * @param align 對齊 * @param colspan 佔多少列 * @return 添加的文字框 */ public PdfPCell createCell(String value, Font font, int align, int colspan) { PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setHorizontalAlignment(align); cell.setColspan(colspan); cell.setPhrase(new Phrase(value, font)); return cell; } /** * 為表格添加一個內容 * @param value 值 * @param font 字型 * @param align 對齊 * @param colspan 佔多少列 * @param boderFlag 是否有有邊框 * @return 添加的文字框 */ public PdfPCell createCell(String value, Font font, int align, int colspan, boolean boderFlag) { PdfPCell cell = new PdfPCell(); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setHorizontalAlignment(align); cell.setColspan(colspan); cell.setPhrase(new Phrase(value, font)); cell.setPadding(3.0f); if (!boderFlag) { cell.setBorder(0); cell.setPaddingTop(15.0f); cell.setPaddingBottom(8.0f); } return cell; } /** * 建立一個表格對象 * @param colNumber 表格的列數 * @return 產生的表格對象 */ public PdfPTable createTable(int colNumber) { PdfPTable table = new PdfPTable(colNumber); try { table.setTotalWidth(maxWidth); table.setLockedWidth(true); table.setHorizontalAlignment(Element.ALIGN_CENTER); table.getDefaultCell().setBorder(1); } catch (Exception e) { e.printStackTrace(); } return table; } public PdfPTable createTable(float[] widths) { PdfPTable table = new PdfPTable(widths); try { table.setTotalWidth(maxWidth); table.setLockedWidth(true); table.setHorizontalAlignment(Element.ALIGN_CENTER); table.getDefaultCell().setBorder(1); } catch (Exception e) { e.printStackTrace(); } return table; } public PdfPTable createBlankTable() { PdfPTable table = new PdfPTable(1); table.getDefaultCell().setBorder(0); table.addCell(createCell("", keyfont)); table.setSpacingAfter(20.0f); table.setSpacingBefore(20.0f); return table; } public <T> void generatePDF(String [] head,List<T> list,int colNum) { Class classType = list.get(0).getClass(); // 建立一個只有5列的表格 PdfPTable table = createTable(colNum); // 添加備忘,靠左,不顯示邊框 table.addCell(createCell("APP資訊列表:", keyfont, Element.ALIGN_LEFT, colNum,false)); //設定表頭 for(int i = 0 ; i < colNum ; i++) { table.addCell(createCell(head[i], keyfont, Element.ALIGN_CENTER)); } if(null != list && list.size() > 0) { int size = list.size(); for(int i = 0 ; i < size ; i++) { T t = list.get(i); for(int j = 0 ; j < colNum ; j ++) { //獲得首字母 String firstLetter = head[j].substring(0,1).toUpperCase(); //獲得get方法,getName,getAge等 String getMethodName = "get" + firstLetter + head[j].substring(1); Method method; try { //通過反射獲得相應的get方法,用於獲得相應的屬性值 method = classType.getMethod(getMethodName, new Class[]{}); try { System.out.print(getMethodName +":" + method.invoke(t, new Class[]{}) +","); //添加資料 table.addCell(createCell(method.invoke(t, new Class[]{}).toString(), textfont)); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } System.out.println(""); } } try { //將表格添加到文檔中 document.add(table); } catch (DocumentException e) { e.printStackTrace(); } //關閉流 document.close(); } /** * 提供外界調用的介面,產生以head為表頭,list為資料的pdf * @param head //資料表頭 * @param list //資料 * @return //excel所在的路徑 */ public <T> String generatePDFs(String [] head,List<T> list) { final String FilePath = "pdfPath"; String saveFilePathAndName = ""; //獲得儲存的根目錄 String savePath = new GetFilePlace().getFileDirFromProperties(FilePath); //獲得當天儲存的路徑,不存在則產生當天的檔案夾 String realSavePath = new GenerateFold().getFold(savePath); saveFilePathAndName = new GenerateFileName().generateFileName(realSavePath,"pdf"); File file = new File(saveFilePathAndName); try { file.createNewFile(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } initFile(file); try { file.createNewFile(); //產生一個pdf檔案 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } new CreatePdf(file).generatePDF(head,list,head.length); return saveFilePathAndName; }}
7)、測評函數
public static void main(String[] args) { System.out.println("begin"); String [] head = {"name","sex","adress","height","age","jj"}; List<User> list = new ArrayList<User>(); User user1 = new User("zhangsan",1,1.1f,"北京","男","AA"); User user2 = new User("lisi",22222,3.2f,"上海","女","BB"); list.add(user1); list.add(user2); String filePath = new CreatePdf().generatePDFs(head,list); System.out.println(filePath); System.out.println("end"); }
8)、測試結果
9)、檔案內容如下
java如何在pdf中產生表格,我相信通過這個簡單一實例示範有了大概的認識,大家可以動手去實驗一下,看看會不會達到預想的效果。