要实现pdf的导出的话,首先需要有一个模板
1.制作pdf模板文件
用Word工具,如WPS或者Office新建一个空白Word文档,里面制作出自己想要的样式。
2、将Word转换成PDF形式
将设置好的Word文档转换成PDF形式,保存起来。
3.编辑PDF准备表单
使用pdfElement软件进行表单的编辑
注意,配置的数据源字段必须与Java中的实体类对象的字段名保持一致
4.代码
4.1导入相关的依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
4.2创建与模板表单相对应的实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PdfVo implements Serializable {
private String subject;
private String name;
private String studentId;
private String phone;
private String time;
}
4.3 controller层的代码
@Controller
@Api(tags = "测试pdf")
public class PdfController {
@Autowired
private PdfService pdfService;
@PostMapping("/pdf/export")
@ApiOperation(value = "pdf文件导出")
public void export(@RequestBody PdfVo pdfVo, HttpServletResponse httpServletResponse) throws UnsupportedEncodingException {
pdfService.export(pdfVo,httpServletResponse);
}
}
4.3service层的代码
@Service
public class PdfServiceImpl implements PdfService {
@Override
public void export(PdfVo pdfVo, HttpServletResponse httpServletResponse) throws UnsupportedEncodingException {
//模板的文件路径
String file="D:\\pdf\\准考证-Copy.pdf";
// 生成导出PDF的文件名称
String fileName =pdfVo.getName() + "-准考证.pdf";
fileName = URLEncoder.encode(fileName, "UTF-8");
// 设置响应头
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("Application/pdf");
//httpServletResponse.setContentType("application/force-download");
httpServletResponse.setHeader("Content-Disposition",
"attachment;fileName=" + fileName);
OutputStream out = null;
ByteArrayOutputStream bos = null;
PdfStamper stamper = null;
PdfReader reader = null;
try {
// 保存到本地
//out = new FileOutputStream(fileName);
// 输出到浏览器端
out = httpServletResponse.getOutputStream();
// 读取PDF模板表单
reader = new PdfReader(file);
// 字节数组流,用来缓存文件流
bos = new ByteArrayOutputStream();
// 根据模板表单生成一个新的PDF
stamper = new PdfStamper(reader, bos);
// 获取新生成的PDF表单
AcroFields form = stamper.getAcroFields();
// 给表单生成中文字体,这里采用系统字体,不设置的话,中文显示会有问题
BaseFont font = BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
form.addSubstitutionFont(font);
// 装配数据
Map<String, Object> data = new HashMap<>(5);
data.put("name", pdfVo.getName());
data.put("subject", pdfVo.getSubject());
data.put("phone", pdfVo.getPhone());
data.put("studentId", pdfVo.getStudentId());
data.put("time", LocalDateTime.now());
// 遍历data,给pdf表单赋值
for(String key : data.keySet()){
form.setField(key, data.get(key).toString());
}
// 表明该PDF不可修改
stamper.setFormFlattening(true);
// 关闭资源
stamper.close();
// 将ByteArray字节数组中的流输出到out中(即输出到浏览器)
Document doc = new Document();
PdfCopy copy = new PdfCopy(doc, out);
doc.open();
PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
//PdfImportedPage importedPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 2);
copy.addPage(importPage);
//copy.addPage(importedPage);
doc.close();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (out != null) {
out.flush();
out.close();
}
if (reader != null) {
reader.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
这时的代码只有装配文字的,如果要想填充图片的话,参考如下代码
for(String key : data.keySet()){
// 图片要单独处理
if("studentImg".equals(key)){
int pageNo = form.getFieldPositions(key).get(0).page;
Rectangle signRect = form.getFieldPositions(key).get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
String studentImage = data.get(key).toString();
//根据路径或Url读取图片
Image image = Image.getInstance(studentImage);
//获取图片页面
PdfContentByte under = stamper.getOverContent(pageNo);
//图片大小自适应
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
//添加图片
image.setAbsolutePosition(x, y);
under.addImage(image);
}
// 设置普通文本数据
else {
form.setField(key, data.get(key).toString());
}
}
如果pdf文档有多页的话,假设是2页,参考如下代码:
PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
PdfImportedPage importedPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 2);
copy.addPage(importPage);
copy.addPage(importedPage);