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
package com.yiboshi.science.utils;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.properties.*;
import com.itextpdf.text.DocumentException;
import com.yiboshi.science.param.dto.ComProjectCooperativeUnitsDTO;
import com.yiboshi.science.param.dto.ComProjectTaskDTO;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static com.yiboshi.science.utils.PdfUtil.*;
import static com.yiboshi.science.utils.PdfUtil.addCell;
import static com.yiboshi.science.utils.ProjectInfoToPDF.getCurrentOperatingSystem;
public class TalentToPDF {
static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
static SimpleDateFormat sdfM = new SimpleDateFormat("yyyy年MM月");
static float borderWidth = 1f;
static Border unitedBorder = new SolidBorder(new DeviceRgb(0, 0, 0), borderWidth);
private static PdfFont createFont(String fontName) {
try {
if ("linux".equals(getCurrentOperatingSystem())) {
if (fontName.toLowerCase().endsWith(".ttc"))
return PdfFontFactory.createFont("/usr/share/fonts/" + fontName + ",0", PdfEncodings.IDENTITY_H);
else
return PdfFontFactory.createFont("/usr/share/fonts/" + fontName, PdfEncodings.IDENTITY_H);
} else {
if (fontName.toLowerCase().endsWith(".ttc"))
return PdfFontFactory.createFont("c:/Windows/Fonts/" + fontName + ",0", PdfEncodings.IDENTITY_H);
else
return PdfFontFactory.createFont("c:/Windows/Fonts/" + fontName, PdfEncodings.IDENTITY_H);
}
} catch (Exception e) {
throw new RuntimeException("加载字体文件失败,请确保系统中存在字体文件 " + fontName + ":" + e.getMessage(), e);
}
}
/**
* 生成项目合同书PDF
*
* @param dto 项目任务信息
* @return PDF文件字节数组
*/
public static byte[] createContractPdf(ComProjectTaskDTO dto) throws DocumentException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(baos));
Document document = new Document(pdfDoc);
try {
// 设置页边距 (左, 右, 上, 下)
document.setMargins(72f, 54f, 72f, 54f);
// 宋体
PdfFont sfChinese = createFont("simsun.ttc");
// 仿宋
PdfFont fsChinese = createFont("simfang.ttf");
// 首页
firstPageInfo(document, dto, sfChinese, fsChinese);
// 填表说明
tableDescription(document, dto, sfChinese, fsChinese);
// 申报人基本情况
basicInformation(document, dto, sfChinese, fsChinese);
// 申报人学习、研修与工作简历
basicInformation1(document, dto, sfChinese, fsChinese);
// 关闭文档
document.close();
return baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static void firstPageInfo(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 附件编号
Paragraph paragraph = new Paragraph("附件3").setFont(bfChinese).setFontSize(16).setBold();
paragraph.setTextAlignment(TextAlignment.LEFT);
document.add(paragraph);
document.add(new Paragraph("\n\n"));
// 添加标题
Paragraph title = new Paragraph("云南省医学高端人才申报表").setFont(bfChinese).setFontSize(22);
title.setTextAlignment(TextAlignment.CENTER);
document.add(title);
document.add(new Paragraph("\n\n\n\n\n\n"));
float[] columnWidths = {65f, 15f, 200f};
Table table = new Table(columnWidths);
// 设置表格水平居中
table.setHorizontalAlignment(HorizontalAlignment.CENTER);
table.setWidth(UnitValue.createPointValue(400f));
// table.setBorder(unitedBorder);
// 添加表格内容
addTablePageCell(table, "申报人姓名:", dto.getProjName(), 2, null, bfChinese);
addTablePageCell(table, "从事专业:", dto.getAppUnitName(), null, 2, bfChinese);
addTablePageCell(table, "单位名称:", dto.getAppUnitName(), null, 2, bfChinese);
addTablePageCell(table, "单位公章:", dto.getAppPersonName(), null, 2, bfChinese);
document.add(table);
}
private static void tableDescription(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加标题
Paragraph title = new Paragraph("填 表 说 明").setFont(bfChinese).setFontSize(16);
title.setTextAlignment(TextAlignment.CENTER);
document.add(title);
document.add(new Paragraph("\n"));
// 添加填表说明内容
List<String> descriptions = new ArrayList<>();
descriptions.add("一、填写本表前请认真阅读《云南省卫生健康委 云南省财政厅关于印发云南省高层次卫生健康技术人才培养等 4 个项目实施方案的通知》(云卫科教发〔2024〕1号)的《云南省高层次卫生健康技术人才培养项目实施办法(试行)》。");
descriptions.add("二、申报表内各项内容应实事求是,认真填写。");
descriptions.add("三、单位名称必须与单位公章上的名称相一致,不能用简称。");
descriptions.add("四、省级或省级以上人才指“国家杰出青年基金“获得者,“国务院政府特殊津贴“获得者,国家卫生健康委“有突出贡献的中青年专家“获得者,教育部“长江学者“获得者,人力资源和社会保障部“百千万“人才工程获得者,云南省中青年学术和技术带头人获得者,省科技领军人才,省创新团队带头人,省科技创新人才获得者。");
descriptions.add("五、表格四中“申报人特研学术成绩“填报时限为2019年1月1日至2024年1月1日。");
descriptions.add("六、申报表用A4纸打印,并在左侧装订成册,一式十份,每份均须加盖单位公章。");
descriptions.add("七、所附材料包括学位证书、荣誉证书、获奖证书复印件、社会团体聘书复印件、论文、专著和教材的封面、目录、版权页复印件。在加上封面和材料目录后按此次序在左侧装订成册,一式一份。");
// 添加填表说明内容
for (String desc : descriptions) {
Paragraph p = new Paragraph(desc).setFont(fsChinese).setFontSize(12);
p.setFirstLineIndent(24f); // 设置首行缩进
p.setMultipliedLeading(1.5f); // 设置行间距
document.add(p);
}
}
private static void basicInformation(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
// 创建表格
float[] column = {10f, 20f, 10f, 10f, 10f, 10f, 10f, 20f, 6.5f, 6.5f, 6.5f, 20f};
Table table = new Table(column);
table.setWidth(UnitValue.createPercentValue(100));
table.setBorder(unitedBorder);
addCell(table, "个人\n" + "情况\n", null, 11, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
// 基本信息行
addValueCell(table, "姓名", 1, "", 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "性别", 2, "", 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "民族", 3, "", 1, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
// 出生年月等信息行
addValueCell(table, "出生年月", 1, "", 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "最高学位", 2, "", 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "最高学位\n授予时间", 3, "", 1, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
// 最高学位等信息行
addValueCell(table, "最高学位\n授予单位", 1, "", 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "目前从事\n专业", 2, "", 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addCell(table, "是否为研究\n生导师", 3, null, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addCell(table, "博导□\n硕导□\n否□", 1, null, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
// 专业技术职称等信息行
addValueCell(table, "专业技术\n职称", 1, "", 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "职派", 2, "", 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "行政职务", 3, "", 1, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
// 是否是省级人才
String talentText = "国家杰出青年基金□,国务院政府特殊津贴□,国家卫健委有突出贡献的中青年专家□,教育部长江学者□,人力资源和社会保障部“百千万”人才工程□,云南省中青年学术和技术带头人□,省科技领军人才□,省创新团队带头人□,省科技创新人才获得者□。";
addValueCell(table, "是否是省级或\n以上人才", 1, talentText, 10, 50f, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
// 个人情况相关行
addValueCell(table, "省级及以上专\n家称号、先进\n工作者等荣誉\n称号", 1, "", 10, 50f, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "在国家、省级\n学术团体中任\n职情况(包括\n任职时间和职\n务)", 1, "", 10, 50f, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "担任国内统计\n源期刊编委情\n况(包括任职\n时间和职务)", 1, "", 10, 50f, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "担任国家或省\n级重点学科/\n专科、重点实\n验室、内设研\n究机构负责人\n情况(包括任\n职时间和职\n务)", 1, "", 10, 50f, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
// 联系方式行
addCell(table, "联系方式", 1, 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
addValueCell(table, "电话", 1, "", 4, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
addValueCell(table, "传真:", 1, "", 4, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
addValueCell(table, "Email:", 1, "", 9, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.RIGHT);
// 申报单位信息
addCell(table, "所在\n单位\n情况", 1, 4, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
// 单位名称
addValueCell(table, "单位名称", 1, "", 10, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
// 支撑条件
String supportText = "1.所在学科的优势(包括综合实力、学术水平);2.学术梯队;3.理实条件;4. :";
addValueCell(table, "支撑条件:", 1, supportText, 10, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
// 主管部门等信息行
addValueCell(table, "主管部门", 1, "", 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
addValueCell(table, "电话", 1, "", 3, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
addValueCell(table, "邮编", 1, "", 3, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
// 通讯地址
addValueCell(table, "通讯地址", 1, "", 10, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
addCell(table, "自评\n研究\n内容", 1, 4, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
// 研究方向
addValueCell(table, "研究方向", 1, "", 10, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
// 研究类别
addValueCell(table, "研究类别:", 1, "A.基础研究□ B.应用研究□ C.开发研究□", 10, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
// 研究基础与进展
addValueCell(table, "研究起止年月", 1, "", 2, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
// 研究基础与进展
addValueCell(table, "研究基础与进展:\n研究基础(包括已取得的主要研究成果):", 4, "", 4, null, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.LEFT);
// 研究目的等
addCell(table, "研究目的、意义、关键技术的主要内容及预期效果(限100字)", 11, 1, 80f, bfChinese, null, VerticalAlignment.MIDDLE, HorizontalAlignment.CENTER);
// 添加表格到文档
document.add(table);
}
private static void basicInformation1(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
}
private static void basicInformation2(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
}
private static void basicInformation3(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
}
private static void basicInformation4(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
}
private static void basicInformation5(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
}
private static void basicInformation6(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
}
private static void basicInformation7(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
}
private static void basicInformation8(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
}
private static void basicInformation9(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
}
private static void basicInformation10(Document document, ComProjectTaskDTO dto, PdfFont bfChinese, PdfFont fsChinese) throws DocumentException {
// 添加新页面
document.add(new AreaBreak());
// 添加段落标题
setParagraph(document, "申报人基本情况", bfChinese, 12f, true);
}
}