我是靠谱客的博主 无私芒果,这篇文章主要介绍Java生产Pdf文件,注意事项(坑),现在分享给大家,希望可以做个参考。

最近,在项目中遇到了这样的需求,将数据库中的数据导出为pdf文件。最初的路线是先使用Word生成表格模板,另存为pdf文件,再用Adobe Acrobat X Pro打开该pdf文件,添加Form域并保存生成pdf模板。使用iText向pdf模板写入数据,并生成最终的pdf文件。但遇到了以下问题:
1、向某text Form域写入多个汉字,但仅仅显示少数几个汉字,没有显示全,Form域的长度也修改了,没有效果;
2、明明设置了宋体,但就是不起作用,还显示为默认字体;

后改为直接使用iText生成pdf,单元测试很顺利,但集成到SpringMVC4中,启动Tomcat报错:

复制代码
1
Caused by: java.lang.IllegalStateException: Unable to complete the scan for annotations for web application [] due to a StackOverflowError. Possible root causes include a too low setting for -Xss and illegal cyclic inheritance dependencies. The class hierarchy being processed was [org.bouncycastle.asn1.ASN1Boolean->org.bouncycastle.asn1.DERBoolean->org.bouncycastle.asn1.ASN1Boolean]

在Idea中搜索类ASN1Boolean,发现itext-asian-5.2.0.jar里居然拷贝了bcprov-jdk15on相关的代码,太混乱了。排除其他bcprov-jdk15on,仅仅保留itext-asian-5.2.0.jar,业务关联的微信小程序里“微信授权登录”功能有异常。索性还原bcprov-jdk15on,删除itext-asian-5.2.0.jar,将操作系统下的字体文件拷贝到Web项目里,关键pom.xml如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13</version> </dependency> <!-- <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency> -->

大致的业务描述:将用户在Web页面输入的简历信息(包括个人基本信息、求职期望、工作经历、教育经历、技能标签、公司的Logo和Slogan)生成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
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
import com.itextpdf.text.*; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; import java.io.*; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.util.List; @Service public class ZuiResume2PdfServiceImpl { private static final Logger LOG = LoggerFactory.getLogger(ZuiResume2PdfServiceImpl.class); private BaseFont bfChinese = null; { try { // 因为jar包冲突,不再使用itext-asian-5.2.0.jar //bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); String webInfPath = Thread.currentThread().getContextClassLoader().getResource("").getPath(); LOG.debug("###### WEB-INF absolutePath=" + webInfPath); webInfPath = webInfPath.replace("WEB-INF/classes/", "WEB-INF/"); LOG.debug("###### WEB-INF absolutePath02=" + webInfPath); // simfang.ttf拷贝自win10系统 bfChinese = BaseFont.createFont(webInfPath + "simfang.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private int MINI_CELL_HEIGHT = 10; private Font titleChinese = new Font(bfChinese, 20, Font.BOLD); private Font secondtitleChinese = new Font(bfChinese, 12, Font.BOLD); private Font fontChinese = new Font(bfChinese, 8, Font.NORMAL); /** * 业务入口 */ public void generatePdf(BaseInfoVO baseInfo, ExpectVO expect, List<WokExperienceVO> workExperienceList, List<TEducation> eduExperienceList, List<String> specList, File localTempFile) throws Throwable { LOG.debug("###### baseInfo=" + ToStringBuilder.reflectionToString(baseInfo, ToStringStyle.MULTI_LINE_STYLE)); LOG.debug("###### expect=" + ToStringBuilder.reflectionToString(expect, ToStringStyle.MULTI_LINE_STYLE)); for (WokExperienceVO workExp : workExperienceList) { LOG.debug("###### workExpList[i]=" + ToStringBuilder.reflectionToString(workExp, ToStringStyle.MULTI_LINE_STYLE)); } for (TEducation edu : eduExperienceList) { LOG.debug("###### eduExpList[i]=" + ToStringBuilder.reflectionToString(edu, ToStringStyle.MULTI_LINE_STYLE)); } for (String tag : specList) { LOG.debug("###### specList[i]=" + tag); } Assert.notNull(bfChinese, "字体为空"); //A4横向 Document document = new Document(PageSize.A4); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfWriter writer = PdfWriter.getInstance(document, baos); document.open(); // 文档标题 Paragraph title = new Paragraph("文档标题", titleChinese); title.setAlignment(Element.ALIGN_CENTER); document.add(title); buildBaseInfoTable(baseInfo, document); buildExpectTable(expect, document); buildWorkExperience(workExperienceList, document); buildEduExperience(eduExperienceList, document); buildSpecialityTags(specList, document); buildLogoSlogan(document); document.close(); baos.writeTo(new FileOutputStream(localTempFile)); } private void buildLogoSlogan(Document document) throws IOException, DocumentException { // 应用的Logo和标语 float[] widths04 = {2f, 2f, 2f, 2f, 2f, 2f, 2f, 24f}; PdfPTable table06 = new PdfPTable(widths04); table06.setSpacingBefore(5f); table06.setWidthPercentage(90); //不显示边框 table06.getDefaultCell().setBorderWidth(0); //垂直居中 table06.setHorizontalAlignment(Element.ALIGN_CENTER); PdfPCell nullCell = new PdfPCell(new Paragraph("")); nullCell.setBorderWidth(0); table06.addCell(nullCell); table06.addCell(nullCell); table06.addCell(nullCell); table06.addCell(nullCell); table06.addCell(nullCell); table06.addCell(nullCell); String webInfPath = Thread.currentThread().getContextClassLoader().getResource("").getPath(); LOG.debug("###### 2WEB-INF absolutePath=" + webInfPath); webInfPath = webInfPath.replace("WEB-INF/classes/", "WEB-INF/"); LOG.debug("###### 2WEB-INF absolutePath02=" + webInfPath); Image logo = Image.getInstance(webInfPath + "favicon.png"); //logo.setAbsolutePosition(200, 0); logo.setAlignment(Element.ALIGN_CENTER); logo.scaleAbsolute(30, 30); //logo.scalePercent(50, 50); logo.setRotation(0); table06.addCell(logo); PdfPCell slogan = new PdfPCell(new Paragraph("华为手机:手机中的战斗机,欧耶!", fontChinese)); slogan.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); slogan.setBorderWidth(0); table06.addCell(slogan); document.add(table06); } private void buildSpecialityTags(List<String> specList, Document document) throws DocumentException { PdfPCell cell;// 最多5个Cell。注意:即使没有,也要输出空字符串!!!!!!!!!!! Paragraph tableName05 = new Paragraph("技能标签", secondtitleChinese); tableName05.setAlignment(Element.ALIGN_CENTER); tableName05.setSpacingBefore(10f); document.add(tableName05); float[] widths02 = {24f, 24f, 24f, 24f, 24f}; PdfPTable table05 = new PdfPTable(widths02); table05.setSpacingBefore(5f); table05.setWidthPercentage(90); for (String tag : specList) { cell = new PdfPCell(new Paragraph(tag, fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table05.addCell(cell); } document.add(table05); } private void buildEduExperience(List<TEducation> eduExperienceList, Document document) throws DocumentException { PdfPCell cell;// 表名4,教育经历,一个表格,可能有0-5行 Paragraph tableName04 = new Paragraph("教育经历", secondtitleChinese); tableName04.setAlignment(Element.ALIGN_CENTER); tableName04.setSpacingBefore(10f); document.add(tableName04); float[] widths02 = {24f, 24f, 24f, 24f, 24f}; PdfPTable table04 = new PdfPTable(widths02); table04.setSpacingBefore(5f); table04.setWidthPercentage(90); // 第一行,表头 cell = new PdfPCell(new Paragraph("学校名称", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table04.addCell(cell); cell = new PdfPCell(new Paragraph("所学专业", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table04.addCell(cell); cell = new PdfPCell(new Paragraph("学历", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table04.addCell(cell); cell = new PdfPCell(new Paragraph("开始时间", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table04.addCell(cell); cell = new PdfPCell(new Paragraph("结束时间", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table04.addCell(cell); for (TEducation edu : eduExperienceList) { cell = new PdfPCell(new Paragraph(edu.getCollegeName(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table04.addCell(cell); cell = new PdfPCell(new Paragraph(edu.getMajor(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table04.addCell(cell); cell = new PdfPCell(new Paragraph(edu.getEduBackground(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table04.addCell(cell); cell = new PdfPCell(new Paragraph(edu.getStartDate(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table04.addCell(cell); cell = new PdfPCell(new Paragraph(edu.getEndDate(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table04.addCell(cell); } document.add(table04); } private void buildWorkExperience(List<WokExperienceVO> workExperienceList, Document document) throws DocumentException { PdfPCell cell;// 表名3,工作经历可能有0-5个表格 float[] widths = {20f, 40f, 20f, 40f}; Paragraph tableName03 = new Paragraph("工作经历", secondtitleChinese); tableName03.setAlignment(Element.ALIGN_CENTER); tableName03.setSpacingBefore(10f); document.add(tableName03); for (WokExperienceVO workExp : workExperienceList) { PdfPTable table03i = new PdfPTable(widths); table03i.setSpacingBefore(5f); table03i.setWidthPercentage(90); // 第一行 cell = new PdfPCell(new Paragraph("公司名称", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table03i.addCell(cell); cell = new PdfPCell(new Paragraph(workExp.getCompName(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table03i.addCell(cell); cell = new PdfPCell(new Paragraph("职位", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table03i.addCell(cell); cell = new PdfPCell(new Paragraph(workExp.getMyPosition(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table03i.addCell(cell); // 第二行 cell = new PdfPCell(new Paragraph("开始时间", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table03i.addCell(cell); cell = new PdfPCell(new Paragraph(workExp.getEntryDate(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table03i.addCell(cell); cell = new PdfPCell(new Paragraph("结束时间", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table03i.addCell(cell); cell = new PdfPCell(new Paragraph(workExp.getLeaveDate(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table03i.addCell(cell); // 第三行 cell = new PdfPCell(new Paragraph("工作内容", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table03i.addCell(cell); cell = new PdfPCell(new Paragraph(workExp.getWorkContent(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setColspan(3); table03i.addCell(cell); document.add(table03i); } } private void buildExpectTable(ExpectVO expect, Document document) throws DocumentException { PdfPCell cell; float[] widths = {20f, 40f, 20f, 40f}; // 建立一个pdf表格 PdfPTable table02 = new PdfPTable(widths); table02.setSpacingBefore(5f); // 设置表格宽度为100% table02.setWidthPercentage(90); // 表名2 Paragraph tableName02 = new Paragraph("求职意向", secondtitleChinese); tableName02.setAlignment(Element.ALIGN_CENTER); tableName02.setSpacingBefore(10f); document.add(tableName02); //表名2第一行 cell = new PdfPCell(new Paragraph("期望城市", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table02.addCell(cell); cell = new PdfPCell(new Paragraph(expect.getExCityName(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table02.addCell(cell); cell = new PdfPCell(new Paragraph("期望职位", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table02.addCell(cell); cell = new PdfPCell(new Paragraph(expect.getExPosition(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table02.addCell(cell); //表名2第二行 cell = new PdfPCell(new Paragraph("职位类型", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table02.addCell(cell); cell = new PdfPCell(new Paragraph(expect.getWorkStyleStr(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table02.addCell(cell); cell = new PdfPCell(new Paragraph("期望月薪", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table02.addCell(cell); cell = new PdfPCell(new Paragraph(expect.getExMonthMoneyStr(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table02.addCell(cell); document.add(table02); } private void buildBaseInfoTable(BaseInfoVO baseInfo, Document document) throws DocumentException { // 表名1 Paragraph tableName01 = new Paragraph("基本信息", secondtitleChinese); tableName01.setAlignment(Element.ALIGN_CENTER); tableName01.setSpacingBefore(10f); document.add(tableName01); // 设置表格的列宽和列数 float[] widths = {20f, 40f, 20f, 40f}; // 建立一个pdf表格 PdfPTable table01 = new PdfPTable(widths); table01.setSpacingBefore(5f); // 设置表格宽度为100% table01.setWidthPercentage(90); PdfPCell cell = null; //表名1第一行 cell = new PdfPCell(new Paragraph("姓名", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph(baseInfo.getRealName(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph("性别", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph(baseInfo.getSexStr(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); //表名1第二行 cell = new PdfPCell(new Paragraph("出生年月", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph(baseInfo.getBirthDate(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph("最高学历", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph(baseInfo.getHighestTechStr(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); //表名1第三行 cell = new PdfPCell(new Paragraph("工作年限", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph(baseInfo.getWorkYearStr(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph("当前状态", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph(baseInfo.getMyStateStr(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); //表名1第四行 cell = new PdfPCell(new Paragraph("手机号码", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph(baseInfo.getPhoneNum(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph("个人邮箱", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph(baseInfo.getEmail(), fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); //表名1第五行 cell = new PdfPCell(new Paragraph("介绍自己", fontChinese)); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); cell = new PdfPCell(new Paragraph(baseInfo.getMyDesc(), fontChinese)); cell.setColspan(3); cell.setMinimumHeight(MINI_CELL_HEIGHT); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table01.addCell(cell); document.add(table01); } }

 

最后

以上就是无私芒果最近收集整理的关于Java生产Pdf文件,注意事项(坑)的全部内容,更多相关Java生产Pdf文件内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(72)

评论列表共有 0 条评论

立即
投稿
返回
顶部