使用poi-tl填充word模板,并转化为pdf输出
后端
依赖
<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.0</version>
</dependency>
Word版本
Word版本填充代码
// 培训详情HashMap<String, Object> textMap = new HashMap<>();textMap.put("projectNo", projectInitiation.getProjectNo());textMap.put("projectName", projectInitiation.getProjectName());textMap.put("organization1", organization.getName());textMap.put("email", Objects.isNull(user.getEmail()) ? "" : user.getEmail());textMap.put("headPhone", Objects.isNull(deviceManage.getHeadPhone()) ? "" : deviceManage.getHeadPhone());// 查看培训人员(扫码查看)QrConfig config = new QrConfig(300, 300);// 设置边距,既二维码和背景之间的边距config.setMargin(3);HashMap<String, String> qrMap = new HashMap<>();qrMap.put("type", RandomUtil.randomString(5));qrMap.put("data", AESUtils.encodeBase64(String.valueOf(visitationTask.getId())));String qr = QrCodeUtil.generateAsBase64(JsonUtils.objectToJsonString(qrMap), config, ImgUtil.IMAGE_TYPE_JPG);textMap.put("detailPages", Pictures.ofBase64(qr, PictureType.JPEG).size(100, 100).create());// 选中textMap.put("redio", "\u2611");textMap.put("customerSignature", Objects.isNull(cultivateDetail.getCustomerSignature()) ? "" : Pictures.ofUrl(cultivateDetail.getCustomerSignature(), PictureType.JPEG).size(100, 50).create());textMap.put("engineerSignature", Objects.isNull(cultivateDetail.getEngineerSignature()) ? "" : Pictures.ofUrl(cultivateDetail.getEngineerSignature(), PictureType.JPEG).size(100, 50).create());// 获取文件流try {InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/培训服务报告.docx");XWPFTemplate template = XWPFTemplate.compile(inputStream).render(textMap);Map<String, Object> map = new HashMap<>();ByteArrayOutputStream fos = new ByteArrayOutputStream();template.write(fos);byte[] bytes = fos.toByteArray();byte[] convertToPdf = Doc2PdfUtil.doc2Pdf(bytes);String bytesRes = StringUtils.bytesToHexString2(convertToPdf);map.put("bytes", bytesRes);map.put("title", System.currentTimeMillis() + "培训服务报告.docx");fos.close();template.close();return Response.successJson(map);} catch (Exception e) {throw new RuntimeException(e);}
pdf版本
依赖
<!--aspose 破解 word转pdf--><dependency><groupId>com.aspose</groupId><artifactId>aspose-words</artifactId><version>16.8.0-jdk16</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/aspose-words-16.8.0-jdk16.jar</systemPath></dependency>
license放到resources下面 license.xml
<License><Data><Products><Product>Aspose.Total for Java</Product><Product>Aspose.Words for Java</Product></Products><EditionType>Enterprise</EditionType><SubscriptionExpiry>20991231</SubscriptionExpiry><LicenseExpiry>20991231</LicenseExpiry><SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber></Data><Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>
word转pdf工具类
package com.gangwantech.web.utils;import com.aspose.words.*;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;public class Doc2PdfUtil {/*** 加载授权配置文件** @return*/private static boolean getLicense() {boolean result = false;try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("license.xml")) {// License的包路径必须为com.aspose.words.LicenseLicense license = new License();license.setLicense(in);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** doc转pdf** @return*/public static byte[] doc2Pdf(byte[] bytes) {System.out.println("pdf转换中...");long old = System.currentTimeMillis();try (ByteArrayOutputStream fos = new ByteArrayOutputStream()) {// 验证if (!getLicense()) {throw new RuntimeException("文件转换失败!");}// 加载字体//FontSettings settings = FontSettings.getDefaultInstance();//String[] fontFamilyNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();//settings.setFontsFolders(fontFamilyNames, true);//LoadOptions loadOptions = new LoadOptions();//loadOptions.setFontSettings(settings); 加载字体//FontSettings settings = FontSettings.getDefaultInstance();//settings.setFontsFolder("C:\\Windows\\Fonts", true);//LoadOptions loadOptions = new LoadOptions();//loadOptions.setFontSettings(settings);ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);//Document document = new Document(inputStream, loadOptions);Document document = new Document(inputStream);document.save(fos, SaveFormat.PDF);byte[] buffer = fos.toByteArray();long now = System.currentTimeMillis();System.out.println("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒");return buffer;} catch (Exception e) {e.printStackTrace();throw new RuntimeException("文件转换失败!");}}
}
pdf版本填充代码,并生成pdf下载
// 培训详情CultivateDetail cultivateDetail = cultivateDetailService.selectOne(new QueryWrapper<CultivateDetail>().eq("work_id", visitationTask.getWorkOrderId()));HashMap<String, Object> textMap = new HashMap<>();textMap.put("projectNo", projectInitiation.getProjectNo());textMap.put("projectName", projectInitiation.getProjectName());// 查看培训人员(扫码查看)QrConfig config = new QrConfig(300, 300);// 设置边距,既二维码和背景之间的边距config.setMargin(3);HashMap<String, String> qrMap = new HashMap<>();qrMap.put("type", RandomUtil.randomString(5) + "train");qrMap.put("data", AESUtils.encodeBase64(String.valueOf(visitationTask.getId())));String qr = QrCodeUtil.generateAsBase64(JsonUtils.objectToJsonString(qrMap), config, ImgUtil.IMAGE_TYPE_JPG);textMap.put("detailPages", Pictures.ofBase64(qr, PictureType.JPEG).size(100, 100).create());// 选中textMap.put("redio", "\u2611");textMap.put("customerSignature", Objects.isNull(cultivateDetail.getCustomerSignature()) ? "" : Pictures.ofUrl(cultivateDetail.getCustomerSignature(), PictureType.JPEG).size(100, 50).create());textMap.put("engineerSignature", Objects.isNull(cultivateDetail.getEngineerSignature()) ? "" : Pictures.ofUrl(cultivateDetail.getEngineerSignature(), PictureType.JPEG).size(100, 50).create());// 获取文件流try {InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/培训服务报告.docx");XWPFTemplate template = XWPFTemplate.compile(inputStream).render(textMap);Map<String, Object> map = new HashMap<>();ByteArrayOutputStream fos = new ByteArrayOutputStream();template.write(fos);byte[] bytes = fos.toByteArray();byte[] convertToPdf = Doc2PdfUtil.doc2Pdf(bytes);String bytesRes = StringUtils.bytesToHexString2(convertToPdf);map.put("bytes", bytesRes);map.put("title", System.currentTimeMillis() + "培训服务报告.docx");fos.close();template.close();return Response.successJson(map);} catch (Exception e) {throw new RuntimeException(e);}
前端下载方法
word下载
if (res.data.code === 0) {const data = res.data.dataconst bytes = hexStr2Byte(data.bytes)const blob = new Blob([bytes], {type: `application/vnd.openxmlformats-officedocument.wordprocessingml.document`})const objectUrl = URL.createObjectURL(blob)const link = document.createElement('a')link.href = objectUrllink.setAttribute('download', data.title)document.body.appendChild(link)link.click()} else {this.$message.error(res.data.msg)}
pdf下载
const data = res.data.dataconst bytes = hexStr2Byte(data.bytes)const blob = new Blob([bytes], {type: `application/pdf`})const objectUrl = URL.createObjectURL(blob)const link = document.createElement('a')link.href = objectUrllink.setAttribute('download', `${data.title}.pdf`)document.body.appendChild(link)link.click()} else {this.$message.error(res.data.msg)}
相关文章:
使用poi-tl填充word模板,并转化为pdf输出
后端 依赖 <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.0</version> </dependency>Word版本 Word版本填充代码 // 培训详情HashMap<String, Object> textMap new Ha…...
计算机视觉-机器学习-人工智能 顶会会议召开地址
计算机视觉-机器学习-人工智能 顶会会议召开地址 最近应该要整理中文资料的参考文献,很多会议文献都需要补全会议地点(新国标要求)。四处百度感觉也挺麻烦的,而且没有比较齐全的网站可以搜索。因此自己整理了一下计算机视觉-机器…...

GAN的原理分析与实例
为了便于理解,可以先玩一玩这个网站:GAN Lab: Play with Generative Adversarial Networks in Your Browser! GAN的本质:枯叶蝶和鸟。生成器的目标:让枯叶蝶进化,变得像枯叶,不被鸟准确识别。判别器的目标&…...

什么是POM设计模式?
为什么要用POM设计模式 前期,我们学会了使用PythonSelenium编写Web UI自动化测试线性脚本 线性脚本(以快递100网站登录举栗): import timefrom selenium import webdriver from selenium.webdriver.common.by import Bydriver …...

没有数据线,在手机上查看电脑备忘录怎么操作
在工作中,电脑和手机是我最常用的工具。我经常需要在电脑上记录一些重要的工作事项,然后又需要在手机上查看这些记录,以便随时了解工作进展。但是,每次都需要通过数据线来传输数据,实在是太麻烦了。 有一次࿰…...

Elasitcsearch--解决CPU使用率升高
原文网址:Elasitcsearch--解决CPU使用率升高_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何解决ES导致的CPU使用率升高的问题。 问题描述 线上环境 Elasticsearch CPU 使用率飙升常见问题如下: Elasticsearch 使用线程池来管理并发操作的 CPU 资源。…...
vue和jQuery有什么区别
Vue 和 jQuery 是两种不同类型的前端工具,它们有一些显著的区别: Vue 响应式数据绑定:Vue 提供了双向数据绑定和响应式更新的能力,使得数据与视图之间的关系更加直观和易于维护。组件化开发:Vue 鼓励使用组件化的方式…...
[Android] Binder all-in-all
前言: Binder 是一种 IPC 机制,使用共享内存实现进程间通讯,既可以传递消息,也可以传递创建在共享内存中的对象,而Binder本身就是用共享内存实现的,因此遵循Binder写法的类是可以实例化后在进程间传递的。…...

无人零售柜:快捷舒适购物体验
无人零售柜:快捷舒适购物体验 通过无人零售柜和人工智能技术,消费者在购物过程中可以自由选择商品,根据个人需求和喜好查询商品清单。这种自主选择的购物环境能够为消费者提供更加舒适和满意的体验。此外,无人零售柜还具有节约时间…...
Bash script进阶笔记
数组类型 arr(1 2 3) # 最基础的方式声明数组,用小括号(),元素之间逗号分隔 arr([1]10 [2]20 [3]30) # 初始化时指定index declare -a arr(1 2 3) # 用declare -a声明数组,小括号外面可选使用单引号、双引号 declare -a arr‘(1 2 3)’…...
OpenCV图像处理——Python开发中OpenCV视频流的多线程处理方式
前言 在做视觉类项目中,常常需要在Python环境下使用OpenCV读取本地的还是网络摄像头的视频流,之后再调入各种模型,如目标分类、目标检测,人脸识别等等。如果使用单线程处理,很多时候会出现比较严重的时延,…...

webGL开发智慧城市流程
开发智慧城市的WebGL应用程序涉及多个方面,包括城市模型、实时数据集成、用户界面设计等。以下是一个一般性的流程,您可以根据项目的具体需求进行调整,希望对大家有所帮助。 1.需求分析: 确定智慧城市应用程序的具体需求和功能。考…...

Django讲课笔记02:Django环境搭建
文章目录 一、学习目标二、相关概念(一)Python(二)Django 三、环境搭建(一)安装Python1. 从官方网站下载最新版本的Python2. 运行安装程序并按照安装向导进行操作3. 勾选添加到路径复选框4. 完成安装过程5.…...

黑豹程序员-原生JS拖动div到任何地方-自定义布局
效果图 代码html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html xmlns"http://www.w3.org/1999/xhtml"> <head> <meta http-equiv"Content-Type" content"text/html; charsetutf-8" /…...
<软考高项备考>《论文专题 - 7 论文的项目背景之技术架构》
1 技术架构概况 ➢ 架构前端:HTML ➢ 后端:Java ➢ 数据库: Oracle ➢ 大数据:MapReduce ➢ 人工智能:Python ➢ 物联网:RFID识别,http传输,Java ➢ 开发APP: IOS、Android 2 常用开发语言 序号语言说明1JavaJava是一种跨平台的编程语言,广…...

6.3 C++11 原子操作与原子类型
一、原子类型 1.多线程下的问题 在C中,一个全局数据在多个线程中被同时使用时,如果不加任何处理,则会出现数据同步的问题。 #include <iostream> #include <thread> #include <chrono> long val 0;void test() {for (i…...

智能优化算法应用:基于狮群算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于狮群算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于狮群算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.狮群算法4.实验参数设定5.算法结果6.参考文献7.MA…...
BERT、GPT学习问题个人记录
目录 1. 为什么过去几年大家都在做BERT, 做GPT的人少。 2. 但最近做GPT的多了以及为什么GPT架构的scaling(扩展性)比BERT好。 3.BERT是否可以用来做生成,如果可以的话为什么大家都用GPT不用BERT. 4. BERT里的NSP后面被认为是没用的&#x…...

HeartBeat监控Mysql状态
目录 一、概述 二、 安装部署 三、配置 四、启动服务 五、查看数据 一、概述 使用heartbeat可以实现在kibana界面对 Mysql 服务存活状态进行观察,如有必要,也可在服务宕机后立即向相关人员发送邮件通知 二、 安装部署 参照章节:监控组件…...
软件开发经常出现的bug原因有哪些
软件开发中出现bug的原因是多方面的,这些原因可能涉及到开发流程、人为因素、设计问题以及其他一系列因素。以下是一些常见的导致bug的原因: 1. 错误的需求分析: 不正确、不完整或者模糊的需求分析可能导致开发人员误解客户的需求࿰…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...