java导出pdf,前端下载
使用注意点
因为原来制作的pdf表单内容过于复杂,下面代码只包含前两行的操作。
本次操作需要前端向后端发起请求,后端返回数据给前端用于下载,所以没有在本地进行保存。
第 1 步制作pdf模板需要的pdf编辑软件基本上都需要钱,可以去买一个
第 2 步获取的pdf导出的中文需要的文件,如果pdf输出的内容有中文就需要去弄一下这个文件,在代码中用于读取设置中文字体
保函内容
1、导出pdf
2、设置斜体水印
1、制作pdf模板
先将需要的pdf模板通过word制作出来,然后导出为pdf
使用Adobe Acrobat DC 打开并制作模板(其他pdf编辑软件也可以)
选择打开前面导出的pdf模板
点击准备表单
点击之后,可以针对没一个位置进行编辑,选中双击就可以进行编辑了,要注意,每个位置的名字都需要是唯一的
全部赋值后保存即可
2、获取pdf导出中文需要的文件
获取中文字体需要的文件
在电脑这个路径下选择下载一个就行
3、实现
controller接口
java
@GetMapping("/exportPDF/{applyId}")
public ResponseEntity<byte[]> exportPDF(@PathVariable("applyId") String applyId, HttpServletResponse response) throws IOException,ParseException,Exception {
byte[] res = applyService.exportPDF(applyId);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=filled_form.pdf");
headers.add("Content-Type", "application/pdf");
return ResponseEntity.ok()
.headers(headers)
.body(res);
}
service具体实现
java
public static byte[] exportPDF1() throws Exception {
String inputTemplateName = "template";
try {
pdfBytes = null;
Map<String, String> map = new HashMap<>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
// map预填数据,用于后面读取输出到pdf文件上
map.put("department-1", "研发中心");
map.put("submitDate-1", sdf.format(new Date()));
map.put("submitPerson-1", "张三");
map.put("travelPerson-1", "李四");
map.put("receivePerson-1","王五");
// 设置中文字体
PdfFont chineseFont = PdfFontFactory.createFont("src/main/resources/file/simsun.ttc,0");
// 模板路径
String templatePath = "src\\main\\resources\\file\\" + inputTemplateName + ".pdf";
// 重点,这一个关联了reader 和 writer
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 读取文件
FileInputStream pdfInputStream = new FileInputStream(new File(templatePath));
// 定义 reader 和writer
PdfReader reader = new PdfReader(pdfInputStream);
PdfWriter writer = new PdfWriter(byteArrayOutputStream,new WriterProperties().setStandardEncryption(
null,
null,
EncryptionConstants.ALLOW_PRINTING, // 允许打印
EncryptionConstants.ENCRYPTION_AES_128 // 加密方式
));
// 根据 reader 和writer 创建 PdfDocument
PdfDocument pdfDocument = new PdfDocument(reader,writer);
// 下面是给文件添加水印,不需要的可以直接删掉
// 获取 pdf 模板页数
int numberOfPages = pdfDocument.getNumberOfPages();
// 遍历每一页并添加水印
for (int i = 1; i <= numberOfPages; i++) {
PdfPage page = pdfDocument.getPage(i);
// 获取页面尺寸(在这里我没有用)
int pageWidth = (int) Math.floor(page.getPageSize().getWidth());
int pageHeight = (int) Math.floor(page.getPageSize().getHeight());
// 创建一个 PdfCanvas 对象
PdfCanvas canvas = new PdfCanvas(page);
// 保存当前坐标系状态
canvas.saveState();
// 水印内容旋转
double angle = Math.toRadians(45);
double cos = Math.cos(angle);
double sin = Math.sin(angle);
canvas.concatMatrix(cos, sin, -sin, cos, 0, 0);
// 设置水印的字体和透明度
canvas.setFontAndSize(PdfFontFactory.createFont(), 20);
canvas.setFillColorRgb(0.75f, 0.75f, 0.75f); // 灰色
canvas.setLineWidth(2);
// 正常应该根据获取到的页面尺寸进行 x y 轴的遍历并
// 但是我这边没有铺满,就自己设置了遍历的范围
for (int x = -90; x < 2000; x += 300) {
for (int y = -190; y < 2000; y += 200) {
// 绘制水印文字
canvas.beginText();
canvas.setTextMatrix(x, y); // 设置水印位置
canvas.showText("Watermark Text this is just a test"); // 水印文字内容
canvas.endText();
}
}
// 恢复坐标系状态
canvas.restoreState();
}
// form 可以理解为把pdf文件看做一个form表单,以key value键值对保存
PdfAcroForm form = PdfAcroForm.getAcroForm(pdfDocument, true);
// 遍历上面预填的 map 并将值根据 key 赋值到form
for (Map.Entry<String, String> entry : map.entrySet()) {
form.getField(entry.getKey()).setValue(entry.getValue());
form.getField(entry.getKey()).setFont(chineseFont).setFontSize(8);
}
pdfDocument.close();
// 返回文件流
pdfBytes = byteArrayOutputStream.toByteArray();
return pdfBytes;
} catch (Exception e) {
e.printStackTrace();
}finally {
return pdfBytes;
}
}
4、前端发起请求并生成下载链接
js
exportPdf(applyId) {
exportPDF(applyId).then(res => {
// 创建一个 Blob 对象,指定类型为 PDF 文件
const blob = new Blob([res.data], { type: 'application/pdf' });
// 创建一个 URL 对象,指向 Blob 数据
const url = URL.createObjectURL(blob);
// 创建一个下载链接
const link = document.createElement('a');
link.href = url;
link.download = 'generated_with_form.pdf'; // 设置下载文件名
// 模拟点击下载链接
link.click();
// 下载完成后释放 URL 对象
URL.revokeObjectURL(url);
})
},