itext 7 生成Pdf,提供给前端下载
开发环境下只需要能够生成Pdf文件就算实现了功能,但是部署之后,在生产环境中,我才发现情况是客户端需要拿到生成的Pdf,而不是仅仅在服务端生成一个Pdf文件就完了。根据我自己的解决方法,写个笔记。
·
开发环境下只需要能够生成Pdf文件就算实现了功能,但是部署之后,在生产环境中,我才发现情况是客户端需要拿到生成的Pdf,而不是仅仅在服务端生成一个Pdf文件就完了。
根据我自己的解决方法,写个笔记。
一、前端代码
// 导出PDF
exportPDF() {
//数据构建,后端用map<String, Object>接收
//准备参数
const ePatientInfo = this.ePatientInfo;
const results = this.results;
axios.post("/api/ePatientInfo/exportPDF", {'ePatientInfo': ePatientInfo, 'results': results},
//ArrayBuffer 是 JavaScript 中的一种数据类型,它表示一段固定长度的原始二进制数据缓冲区。
{responseType:"arraybuffer",}).then(resp => {
// 处理下载 PDF 的逻辑
// 创建一个Blob对象,将从网络请求响应中获取到的数据(resp.data)作为参数传递给Blob构造函数
// 同时指定该Blob对象的MIME类型为'application/octet-stream',表示它是一个字节流形式的数据,可用于传输各种二进制文件
const blob = new Blob([resp.data], { type: 'application/octet-stream' });
// 在文档对象模型(DOM)中创建一个<a>标签元素,通常用于创建超链接
const link = document.createElement('a');
// 设置<a>标签的'download'属性,属性值是由患者信息中的姓名(ePatientInfo.name)和就诊序列号(ePatientInfo.visitSerialNumber)拼接后再加上".pdf"组成的字符串
// 这样设置后,当用户点击这个链接进行下载时,下载的文件名将以此字符串命名
link.setAttribute('download', ePatientInfo.name + ePatientInfo.visitSerialNumber + ".pdf");
// 通过window.URL.createObjectURL方法为创建的Blob对象生成一个临时的可访问的URL地址,并将这个地址设置为<a>标签的'href'属性
// 使得该<a>标签指向这个由Blob对象生成的临时URL,以便后续能够通过点击这个链接来访问和下载Blob对象所代表的文件内容
link.href = window.URL.createObjectURL(blob);
// 将创建好的<a>标签元素添加到文档的<body>部分,使其成为页面DOM结构中的一部分
// 这样用户在浏览器页面中就能看到这个下载链接(虽然可能看不到具体的样式,具体样式可根据后续的CSS设置来展现)
document.body.appendChild(link);
// 模拟用户点击刚刚添加到页面中的<a>标签,触发下载操作
// 当点击这个链接时,浏览器会根据之前设置的'download'属性值来命名下载的文件,并从通过'href'属性指定的临时URL地址获取文件内容进行下载
link.click();
messageTip("导出PDF成功", "success");
}).catch(err=>{
messageTip(err,"error")
})
},
二、Controller代码
//导出PDF
@PostMapping(value = "/api/ePatientInfo/exportPDF")
public ResponseEntity<FileSystemResource> exportPDF(@RequestBody Map<String, Object> map) {
//调用service方法
String fileName =ePatientInfoService.exportPDF(map);
//硬编码,后期需要修改
String filePath="D:/pdf/"+fileName;
//以统一的方式访问不同类型的资源,如文件系统中的文件、类路径下的资源等
FileSystemResource file = new FileSystemResource(filePath);
//请求头
HttpHeaders headers = new HttpHeaders();
//Content-Disposition:attachment 浏览器将服务器返回的内容作为附件进行下载,而不是在浏览器内显示。
//filename=用于指定下载附件的文件名。
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
//"Content-Type":"application/octet-stream",内容类型标识:表示传输的内容是一个字节流,接收方并不知道这个字节流具体代表什么类型的文件或数据,它只是将其作为一系列连续的字节来处理。
//这种内容类型具有很强的通用性,因为它没有对所传输的字节流进行明确的类型定义。
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
return ResponseEntity.ok().headers(headers).body(file);
}
三、service方法
@Override
public String exportPDF(Map<String, Object> map){
//使用合适的 JSON 处理库(如 Jackson 或 Gson)来正确地将 JSON 数据反序列化为目标类型,而不是依赖于手动的类型转换。
Gson gson = new Gson();
EPatientInfo epi = gson.fromJson(gson.toJson(map.get("ePatientInfo")), EPatientInfo.class);
//TypeToken是 Google 的 Gson 库中的一个类,用于解决 Java 泛型类型擦除带来的问题,以便在运行时获取和处理具体的泛型类型信息。
List<EExamResults> list = gson.fromJson(gson.toJson(map.get("results")), new TypeToken<List<EExamResults>>() {
}.getType());
//调用本类的PDF处理方法
String fileName = null;
try {
fileName=pDfHandle(epi, list);
} catch (IOException e) {
throw new RuntimeException(e);
}
//返回一个文件名,供给controller下载用
return fileName;
}
四、生成Pdf的方法
生成PDF方法基本与之前的ITEXT7生成PDF文件一样(参见itext7使用),增加了把生成的文件名返回给调用者。
更多推荐
所有评论(0)