1、目標
在pdf中生成一個可變表頭的表格,并向其中填充數據。通過泛型動態的生成表頭,通過反射動態獲取實體類(我這里是User)的get方法動態獲得數據,從而達到動態生成表格。
每天生成一個文件夾存儲生成的pdf文件(文件夾的命名是年月日時間戳),如:20151110
生成的文件可能在毫秒級別,故文件的命名規則是"到毫秒的時間戳-uuid",如:20151110100245690-ece540e5-7737-4ab7-b2d6-87bc23917c8c.pdf
通過讀取properties文件動態獲取文件存儲的跟目錄。
2、所需的jar
這里通過itex插件進行pdf的生成,需要的jar包括以下幾個
3、編碼實現
1)、實體類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
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存儲的路徑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
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)、獲取當天存在的文件路徑,不存在則生成一個新的文件夾
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
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)、生成文件的名字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
|
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)、測評函數
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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)、文件內容如下
4、其他相關鏈接
生成可變表頭excel:http://www.cnblogs.com/0201zcr/p/4950619.html
java如何在pdf中生成表格,我相信通過這個簡單實例演示有了大概的認識,大家可以動手去試驗一下,看看會不會達到預想的效果。