一、前端
// 预览 PDF 文件 export function viewPDF(Id, params = {}) { axios({ method: 'post', headers: { 'Content-Type': 'application/json' }, url: ****/viewPDF', data: {entityId: Id,entityType:entityType, paramsStr: JSON.stringify(params)}, responseType: 'blob', // 服务器返回的数据类型 }).then(res => { // 处理返回的文件流 const blob = new Blob([res.data], {type: "application/pdf"}) const href = window.URL.createObjectURL(blob); // 创建链接 window.open("../../../assets/plugins/showPdf/web/viewer.html?file=" + href); }) }
二、后端
/**
* 预览 PDF 文件
*
* @param response 响应流
* @param paramsMap 附带的参数
*/
@ApiOperation("预览 PDF 文件")
@PostMapping("/viewPDF")
public void viewPDF(@ApiParam(value = "响应流", required = true) HttpServletResponse response,
@ApiParam(value = "附带的参数", required = true)
@RequestBody Map<String, String> paramsMap) {
commonService.viewPDF(response, paramsMap);
}
public void viewPDF(HttpServletResponse response, Map<String, String> paramsMap) {
//获取当前用户
String currentUserId = ContextUtil.getCurrentUserId();
String currentUserName = ContextUtil.getCurrentUserName();
// 获取实体 id 和实体类型
String entityId = paramsMap.get("entityId");
String entityType = paramsMap.get("entityType");
String qrCodeUrl = "";
// 解析额外参数
JSONObject params = JSON.parseObject(paramsMap.get("paramsStr"));
// 设置响应头
response.reset();
response.addHeader("Access-Control-Allow-Origin", "*");
response.setContentType("application/octet-stream");
response.setCharacterEncoding("utf-8");
// 获取响应流
ServletOutputStream servletOutputStream;
try {
servletOutputStream = response.getOutputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
// 模板文件名称
String reportTemplateFileName = "";
// 模板参数 Map
Map<String, Object> templateMap = new HashMap<>();
// 总数据
List<Map<String, Object>> totalDataList = new ArrayList<>();
// 单页面数据
Map<String, Object> subPageMap;
// 单页面子表数据明细
List<Map<String, Object>> details;
// 获取文件路径
switch (entityType) {
// 直接根据路径输出pdf文件
case "aaa": {
// 构造 PDF 文件保存路径
String filePath = UploadUtils.UPLOAD_PATH + "reportFile" + File.separator + entityId + ".pdf";
FileUtil.writeToStream(filePath, servletOutputStream);
break;
}
}
// 根据对应的值给到word文档模板,然后转成PDF
case "bbb": {
Person person = personService.getById(entityId);
templateMap.putAll(MapUtils.objectToMap(person));
reportTemplateFileName = "word文件.docx";
break;
}
WordUtils.printSinglePagePDF(servletOutputStream, reportTemplateFileName, templateMap);
}
}
三、工具类
package com.*.common.utils;
import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import com.itextpdf.text.pdf.BarcodeQRCode;
import org.apache.pdfbox.util.PDFMergerUtility;
import javax.servlet.ServletOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* Word 操作工具类
* </p>
*/
public class WordUtils {
/**
* 打印包含循环表格的 PDF
*
* @param servletOutputStream Servlet 输出流
* @param reportTemplateFileName 报告模板文件名称
* @param totalDataList 所有数据列表
*/
public static void printContainsLoopTablePDF(ServletOutputStream servletOutputStream, String reportTemplateFileName, List<Map<String, Object>> totalDataList) {
String reportTemplateFilePath;
// 如果是 windows 开发环境就放到项目路径,否则放到启动文件同级目录
if (OSInfoUtils.isWindows()) {
reportTemplateFilePath = System.getProperty("user.dir") + "/project-spring-boot/src/main/resources/" + "otherWordTemplate" + File.separator + reportTemplateFileName;
} else {
reportTemplateFilePath = UploadUtils.UPLOAD_PATH + "otherWordTemplate" + File.separator + reportTemplateFileName;
}
try {
// 模板渲染策略
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
Configure config = Configure.builder()
.bind("details", policy).build();
// 编译模板文件
ByteArrayOutputStream os = new ByteArrayOutputStream();
XWPFTemplate
.compile(reportTemplateFilePath, config)
.render(new HashMap<String, Object>() {{
put("totalDataList", totalDataList);
}})
.writeAndClose(os);
Document doc = new Document(new ByteArrayInputStream(os.toByteArray()));
// 保存结果文档
doc.save(servletOutputStream, SaveFormat.PDF);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 单页面简单打印
*
* @param servletOutputStream Servlet 输出流
* @param reportTemplateFileName 报告模板文件名称
* @param templateMap 报告模板数据 map
*/
public static void printSinglePagePDF(ServletOutputStream servletOutputStream, String reportTemplateFileName, Map<String, Object> templateMap) {
String reportTemplateFilePath;
// 如果是 windows 开发环境就放到项目路径,否则放到启动文件同级目录
if (OSInfoUtils.isWindows()) {
reportTemplateFilePath = System.getProperty("user.dir") + "/project-spring-boot/src/main/resources/" + "otherWordTemplate" + File.separator + reportTemplateFileName;
} else {
reportTemplateFilePath = UploadUtils.UPLOAD_PATH + "otherWordTemplate" + File.separator + reportTemplateFileName;
}
try {
// 编译模板文件
ByteArrayOutputStream os = new ByteArrayOutputStream();
XWPFTemplate
.compile(reportTemplateFilePath)
.render(templateMap)
.writeAndClose(os);
Document doc = new Document(new ByteArrayInputStream(os.toByteArray()));
// 保存结果文档
doc.save(servletOutputStream, SaveFormat.PDF);
} catch (Exception e) {
e.printStackTrace();
}
}
}