集团 SaaS 平台目前需要实现导出 PDF 格式的电子委托协议功能。业务方已经提供了一个现成的 PDF 文件作为参考。针对这一需求,我们有两个可行的方案:
- 完全代码生成:根据 PDF 文件的外观,完全通过代码动态生成 PDF 文件。
- 模板填充:将现有的 PDF 文件作为模板,仅需在代码中填充真实数据即可生成最终的 PDF 文件。
从实现效率和开发速度的角度来看,方案二(模板填充)无疑是更优的选择。它不仅能够大幅减少开发工作量,还能确保生成的 PDF 文件与业务方提供的模板完全一致,避免样式偏差。接下来,我们将重点探讨如何通过模板填充的方式实现这一功能。
一、PDF 模板制作
首先通过 PDF 编辑器制作 PDF 模板,这里我选用 Adobe Acrobat Pro 编辑表单来实现,这里我主要用到了表单的文本域和复选框。
工具我放云盘,需要的自取:https://caiyun.139.com/m/i?105CqcMLSgEyR 提取码:6ais

文本域的 name 对应 Java 中 model 类的属性。
二、前端编码
// html
<a-button v-has="'dec:down'" type="primary" icon="printer" :loading="printBatchLoading" @click="handlePrintBatch">批量打印</a-button>
// JavaScript
/**
* 批量打印
*/
handlePrintBatch(){
if (this.selectedRowKeys.length == 0) {
this.$message.error('请选择至少一票数据!')
return
}
let params = {}
params.ids = this.selectedRowKeys.join(',')
this.printBatchLoading = true
let fileName = ''
if (this.selectedRowKeys.length > 1) {
fileName = '电子委托协议批量导出.zip'
} else {
fileName = '电子委托协议导出' + (this.selectionRows[0].consignNo ? this.selectionRows[0].consignNo :
this.selectionRows[0].id) + '.pdf'
}
downloadFile(this.url.exportElecProtocolBatch, fileName,
params).then((res) => {
if (res.success) {
} else {
this.$message.warn(`导出失败!${res.message}`)
}
}).finally(() => {
this.printBatchLoading = false
})
}
/**
* 下载文件
* @param url 文件路径
* @param fileName 文件名
* @param parameter
* @returns {*}
*/
export function downloadFile(url, fileName, parameter) {
return downFile(url, parameter).then((data) => {
if (!data || data.size === 0) {
Vue.prototype['$message'].warning('文件下载失败')
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), fileName)
} else {
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link) //下载完成移除元素
window.URL.revokeObjectURL(url) //释放掉blob对象
}
})
}
三、后端编码
/**
* 批量打印电子委托协议
*
* @param ids
* @return org.jeecg.common.api.vo.Result<?>
* @author ZHANGCHAO
* @date 2025/1/16 08:54
*/
@Override
public void exportElecProtocolBatch(String ids, HttpServletResponse response) {
try {
// 获取协议列表
List<ElecProtocol> elecProtocolList = fetchProtocolsByIds(ids);
if (isEmpty(elecProtocolList)) {
throw new RuntimeException("未获取到电子委托协议数据");
}
if (elecProtocolList.size() == 1) {
// 单个文件导出
ElecProtocol protocol = elecProtocolList.get(0);
Map<String, Object> data = prepareDataMap(protocol);
byte[] pdfBytes = generatePdf(data);
// 设置响应头
String pdfFileName = URLEncoder.encode(
"电子委托协议_" + (isNotBlank(protocol.getConsignNo()) ? protocol.getConsignNo() : protocol.getId()) + ".pdf",
"UTF-8");
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=" + pdfFileName);
try (ServletOutputStream outputStream = response.getOutputStream()) {
outputStream.write(pdfBytes);
outputStream.flush();
}
} else {
// 多个文件压缩成 ZIP 导出
response.setContentType("application/zip");
String zipFileName = URLEncoder.encode("电子委托协议导出.zip", "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);
try (<


7210

被折叠的 条评论
为什么被折叠?



