欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > java实现根据Velocity批量生成pdf并合成zip压缩包

java实现根据Velocity批量生成pdf并合成zip压缩包

2025/5/20 18:59:22 来源:https://blog.csdn.net/weixin_43861630/article/details/147979447  浏览:    关键词:java实现根据Velocity批量生成pdf并合成zip压缩包

Velocity 模版操作

用的之前写好的: 传送门

其中需要新加一个转成输入流的方法

    public static InputStream convertToPdf(StringWriter stringWriter) throws IOException {//将 HTML 转为字节流byte[] htmlBytes = stringWriter.toString().getBytes(StandardCharsets.UTF_8);//创建 PDF 输出流ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();try (PdfWriter writer = new PdfWriter(pdfOutputStream);PdfDocument pdfDocument = new PdfDocument(writer)) {// 设置 A4 纸张和边距pdfDocument.setDefaultPageSize(PageSize.A4);pdfDocument.setTagged(); // 支持无障碍阅读//配置中文字体ConverterProperties properties = new ConverterProperties();FontProvider fontProvider = new FontProvider();fontProvider.addFont("STSongStd-Light", "UniGB-UCS2-H"); // 添加中文字体properties.setFontProvider(fontProvider);//转换 HTML 到 PDFtry (InputStream htmlStream = new ByteArrayInputStream(htmlBytes)) {HtmlConverter.convertToPdf(htmlStream, pdfDocument, properties);}}// 返回 PDF 的输入流return new ByteArrayInputStream(pdfOutputStream.toByteArray());}

具体使用

public void reportBatchDownload(ReportBatchDownload params, HttpServletResponse response) {List<SpeExamineInfo> infos = speExamineInfoMapper.selectListByReportBatchDownload(params);if (infos.isEmpty()) {throw new ServiceException("当前没有已完成的预约记录");}String filName = "体检报告.zip";// 设置请求流try {FileUtils.setAttachmentResponseHeader(response, filName);response.setContentType("application/zip");try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream(), StandardCharsets.UTF_8)) {for (SpeExamineInfo info : infos) {VelocityContext velocityContext = getVelocityContext(info.getId(), info, null);StringWriter stringWriter = VelocityUtils.genHtml(velocityContext, "vm/report.vm");try (InputStream inputStream = VelocityUtils.convertToPdf(stringWriter)) {// 添加ZIP条目zipOut.putNextEntry(new ZipEntry(buildFilePath(info)));// 写入文件内容byte[] cache = new byte[8192];int nRead;while ((nRead = inputStream.read(cache)) != -1) {zipOut.write(cache, 0, nRead);}zipOut.closeEntry();}zipOut.flush();}// 最后刷新缓冲区zipOut.finish();}} catch (IOException e) {throw new RuntimeException("生成压缩包失败", e);}}private String buildFilePath(SpeExamineInfo info){return "/" + info.getSchName() + "/" + info.getGradeName() + "/" + info.getClassName() + "/" + info.getStuName() + "_体检报告.pdf";}// 处理vm模版变量
private VelocityContext getVelocityContext(String infoId, SpeExamineInfo speExamineInfo, String imgPrefix) {SpeExamineResQuery speExamineResQuery = new SpeExamineResQuery();speExamineResQuery.setInfoId(infoId);List<SpeExamineResDto> speExamineResDtos = speExamineResMapper.selectList(speExamineResQuery);SpeExamineType speExamineType = new SpeExamineType();speExamineType.setInfoId(infoId);List<SpeExamineType> speExamineTypes = speExamineTypeMapper.selectList(speExamineType);Map<String, Object> res = new HashMap<>();speExamineResDtos.forEach(item -> {if (StringUtils.isNotBlank(item.getItemResLabel())) {res.put(item.getItemCode() + "_label", item.getItemResLabel());}res.put(item.getItemCode(), item.getItemRes());res.put(item.getItemCode() + "_conclusion", item.getConclusion());res.put(item.getItemCode() + "_hasException", item.getHasException());});Map<String, Object> type = new HashMap<>();speExamineTypes.forEach(item -> {type.put(item.getItemType() + "_advice", item.getDocAdvice());type.put(item.getItemType() + "_signature", (StringUtils.isNotBlank(imgPrefix) ? imgPrefix : "" ) + item.getDocSign());});Map<String, Object> param = new HashMap<>(3);param.put("info", speExamineInfo);param.put("res", res);param.put("type", type);VelocityContext velocityContext = new VelocityContext();velocityContext.put("pdf", param);return velocityContext;}

效果图

在这里插入图片描述
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词