java操作富文本插入到word模板

最近项目有个需求,大致流程是前端保存富文本(html的代码)到数据库,后台需要将富文本代码转成带格式的文字,插入到word模板里,然后将word转成pdf,再由前端调用接口下载pdf文件!

1、思路

这里的主要难点就是将html的格式带入到word里,所以这里要先将格式写入到html里。怎么写入到html里呢?这里提供一下思路,就是把你的word模板先转成html代码,为啥是代码不是html文件呢?因为我要用这个html代码去把富文本插进去,怎么插呢?首先要标记一个替换符在word模板里,这里有了替换符我们就可以用replace把富文本代码替换掉这个替换符,这样富文本就插进去了嘛!然后再把html代码转成word文档,再进行你的逻辑操作就可以了!
总结: 大致意思就是将word模板提取成html代码,再把富文本替换进去,然后把替换完的代码转成word。

2、依赖

主要就是用的aspose-words,因为好用所以一直在用,这里用aspose主要是文件的转换。我的业务逻辑需要把数据放到word指定的位置里,所以我要用替换的方式去替换数据,这里也用到了poi-tl。
贴一下我的版本,这里的aspose我是放到lib里了

依赖想下载的直接去下载:https://download.csdn.net/download/weixin_44953395/88565563
不要积分的

<!-- word转pdf-->
<dependency><groupId>com.aspose</groupId><artifactId>aspose-words</artifactId><version>15.8.0</version><scope>system</scope><systemPath>${project.basedir}/lib/aspose-words-15.8.0-jdk16.jar</systemPath>
</dependency>
<!--poi-tl-->
<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.10.4</version>
</dependency>

3、代码

说了一堆废话,还是得看代码,谁也挡不住复制粘贴!

@Test
public void testDocToHtml() {String html = WordToPdfUtil.parseWord2Html("D:\\environment\\idea\\company\\ceshi\\test.docx");String fwb = "<ol><li>古诗</li></ol><p>《南歌子·似带如丝柳》</p><p><span style=\"color: rgb(212, 56, 13);\"><u>唐·温庭筠</u></span></p><p><span style=\"background-color: rgb(115, 209, 61);\">似带如丝柳,团酥握雪花。</span></p><p><span style=\"color: rgb(89, 126, 247);\">帘卷玉钩斜,九衢尘欲暮,逐香车。</span></p>";assert html != null;String fwbHtml = html.replaceAll("Fwb1", fwb);System.out.println(fwbHtml);WordToPdfUtil.htmlToWord(fwbHtml.getBytes(StandardCharsets.UTF_8), 20, "D:\\environment\\idea\\company\\ceshi\\ceshi.docx");
}
package com.byqh.utils;import com.aspose.words.*;import java.io.*;
import java.nio.charset.StandardCharsets;/*** word转Pdf帮助类* <p>* 备注:需要引入 aspose-words-15.8.0-jdk16.jar*/
public class WordToPdfUtil {private static boolean getLicense() {boolean result = false;try {InputStream is = WordToPdfUtil.class.getClassLoader().getResourceAsStream("license.xml");License asposeLic = new License();asposeLic.setLicense(is);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** word转pdf* * @param wordPath 需要被转换的word全路径带文件名* @param pdfPath  转换之后pdf的全路径带文件名*/public static void docToPdf(String wordPath, String pdfPath) {// 验证License 若不验证则转化出的pdf文档会有水印产生if (!getLicense()) {return;}try {long old = System.currentTimeMillis();//新建一个pdf文档File file = new File(pdfPath);FileOutputStream os = new FileOutputStream(file);//wordPath是将要被转化的word文档Document doc = new Document(wordPath);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换doc.save(os, SaveFormat.PDF);long now = System.currentTimeMillis();os.close();//转化用时System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");} catch (Exception e) {e.printStackTrace();}}/*** word转html文本** @param wordPath 需要转换的doc文件* @return html代码*/public static String parseWord2Html(String wordPath) {// 验证License 若不验证则转化出的pdf文档会有水印产生if (!getLicense()) {return null;}HtmlSaveOptions saveOptions = new HtmlSaveOptions();saveOptions.setExportHeadersFootersMode(ExportHeadersFootersMode.NONE); ByteArrayOutputStream htmlStream = new ByteArrayOutputStream();String htmlText = "";try {Document doc = new Document(wordPath);doc.save(htmlStream, saveOptions);htmlText = new String(htmlStream.toByteArray(), StandardCharsets.UTF_8);htmlStream.close();} catch (Exception e) {System.out.println(e.getMessage());}return htmlText;}/*** html字节数组转word字节数组** @param content  html字节数组* @param toType   值为SaveFormat.DOCX-20或SavaFormat.Doc-10对应的值* @param filePath 转换完成之后的文件路径*/public static void htmlToWord(byte[] content, Integer toType, String filePath) {// 验证License 若不验证则转化出的pdf文档会有水印产生if (!getLicense()) {return;}try {File file = new File(filePath);FileOutputStream os = new FileOutputStream(file);InputStream is = new ByteArrayInputStream(content);Document doc = new Document();DocumentBuilder builder = new DocumentBuilder(doc);InputStreamReader streamReader = new InputStreamReader(is, StandardCharsets.UTF_8);BufferedReader reader = new BufferedReader(streamReader);String line;StringBuilder html = new StringBuilder();while ((line = reader.readLine()) != null) {html.append(line);}reader.close();builder.insertHtml(String.valueOf(html));doc.save(os, toType);System.out.println("html转word成功!");} catch (Exception e) {System.out.println(e.getMessage());}}}

效果:

替换之前:(这里的Fwb1就是一个标志符)
在这里插入图片描述
替换之后:
在这里插入图片描述
这里的富文本是用的wangeditor,网站是:https://www.wangeditor.com/

写在富文本的样子是下图这样的,总体来说还可以!
在这里插入图片描述

4、替换

替换用的是poi-tl,它的网址说明文档:http://deepoove.com/

@Test
public void testDocTh() throws IOException {Map<String, Object> map = new HashMap<>();map.put("sj01", "测试-test01");map.put("sj02", "测试-test02");List<PictureRenderData> list = new ArrayList<>();//这里的size设置的是宽和高list.add(Pictures.ofStream(new FileInputStream("D:\\environment\\idea\\company\\ceshi\\400X350.png")).size(400, 350).create());list.add(Pictures.ofStream(new FileInputStream("D:\\environment\\idea\\company\\ceshi\\400X400.png")).size(400, 400).create());for (int i = 0; i < list.size(); i++) {map.put("tp0" + (i + 1), list.get(i));}XWPFTemplate template = XWPFTemplate.compile("D:\\environment\\idea\\company\\ceshi\\test.docx").render(map);FileOutputStream out1 = new FileOutputStream("D:\\environment\\idea\\company\\ceshi\\out_template.docx");template.write(out1);out1.close();
}

替换之前:
在这里插入图片描述
替换之后:
在这里插入图片描述
说明一下,这里的两张图片一个是400X350的一个是400X400的两个大小差不太多,所以大小不太明显!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/167041.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第30天|回溯总结 332. 重新安排行程

回溯是递归的副产品&#xff0c;只要有递归就会有回溯&#xff0c;所以回溯法也经常和二叉树遍历&#xff0c;深度优先搜索混在一起&#xff0c;因为这两种方式都是用了递归。 回溯法就是暴力搜索&#xff0c;并不是什么高效的算法&#xff0c;最多再剪枝一下。 回溯算法能解…

从零学算法400

400.给你一个整数 n &#xff0c;请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …] 中找出并返回第 n 位上的数字。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;n 11 输出&#xff1a;0 解释&#xff1a;第…

乐得瑞LDR6020 VR串流线方案:实现同时充电传输视频信号

VR&#xff08;Virtual Reality&#xff09;&#xff0c;俗称虚拟现实技术&#xff0c;是一项具有巨大潜力的技术创新&#xff0c;正在以惊人的速度改变我们的生活方式和体验&#xff0c;利用专门设计的设备&#xff0c;如头戴式显示器&#xff08;VR头盔&#xff09;、手柄、定…

三菱PLC定时中断应用编程(计数器+比较器)

三菱PLC如何开启定时中断可以查看下面文章链接: PLC定时中断程序应用注意事项(西门子三菱信捷)_plc设置断点之后会怎样_RXXW_Dor的博客-CSDN博客文章浏览阅读2.5k次,点赞5次,收藏6次。首先我们了解下什么是中断。中断(打断的意思),在PLC执行当前程序时,由于系统出现了…

基于SSM的老年公寓信息管理(有报告)。Javaee项目

演示视频&#xff1a; 基于SSM的老年公寓信息管理&#xff08;有报告&#xff09;。Javaee项目 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring SpringMvc …

堆的实现(C语言版)

文章目录 概述堆的实现初始化销毁插入删除取堆顶元素求堆的长度判断堆是否为空 完整代码 概述 如果有一个关键码的集合K {k0,k1,k2…kn-1}&#xff0c;把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中&#xff0c;并满足&#xff1a;Ki <K2*i1 且 Ki<K2…

Python Opencv实践 - 全景图片拼接stitcher

做一个全景图片切片的程序Spliter 由于手里没有切割好的全景图片资源&#xff0c;因此首先写了一个切片的程序spliter。 如果有现成的切割好的待拼接的切片文件&#xff0c;则不需要使用spliter。 对于全景图片的拼接&#xff0c;需要注意一点&#xff0c;各个切片图片之间要有…

NX二次开发UF_CSYS_map_point 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CSYS_map_point Defined in: uf_csys.h int UF_CSYS_map_point(int input_csys, double input_point [ 3 ] , int output_csys, double output_point [ 3 ] ) overview 概述 Ma…

Android11编译第七弹:串口文件读写

问题&#xff1a;需要对SIM卡进行管理&#xff0c;支持APP切换SIM卡。此功能需要访问串口文件&#xff0c;并且对串口文件进行读写。APP操作串口文件/dev/ttyUSB1时&#xff0c;串口文件打开失败。 2023-11-23 10:59:44.092 14264-14264 MULTI_CARD_SerialHandle com.wellnkio…

三分钟快速理解 ChatGPT 背后的大模型技术

在过去的十年中&#xff0c;人工智能领域取得了重大突破&#xff0c;其中自然语言处理&#xff08;NLP&#xff09;是其重要子领域之一。NLP使用的模型之一是大型语言模型&#xff08;LLMs&#xff09;。LLMs被设计用于处理大量文本数据&#xff0c;采用先进的神经网络架构&…

鼠标拖拽问题,不选中文本不触发单击事件

文章目录 1. 为什么鼠标单击的时候触发了mousemove事件&#xff1f;明明鼠标没有移动2. 鼠标拖拽元素怎么能不触发单击事件&#xff1f;怎么处理鼠标在元素内的相对定位&#xff0c;而不是每次定位到左上角&#xff1f;方式一&#xff1a;拖拽的元素没有注册click监听就不会触发…

10年测试老鸟,自动化测试经验10条建议,一路狂飙...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、哪一刻&#x…

Postman如何使用(二):Postman Collection的创建/使用/导出分享等

一、什么是Postman Collection&#xff1f; Postman Collection是可让您将各个请求分组在一起。 您可以将这些请求组织到文件夹中。中文经常将collection翻译成收藏夹。如果再下文中看到这样的翻译不要觉得意外。Postman Collection会使你的工作效率更上一层楼。Postman Colle…

教师工作就业前景

在这个知识爆炸的时代&#xff0c;当老师无疑是社会发展的重要基石。随着科技的进步和社会的发展&#xff0c;教育行业的需求也在不断增长。那么&#xff0c;教师工作的就业前景如何呢&#xff1f; 我们来看看教师工作的市场需求。随着国家对教育的重视和投入的增加&#xff0c…

C/C++ 实现Socket交互式服务端

在 Windows 操作系统中&#xff0c;原生提供了强大的网络编程支持&#xff0c;允许开发者使用 Socket API 进行网络通信&#xff0c;通过 Socket API&#xff0c;开发者可以创建、连接、发送和接收数据&#xff0c;实现网络通信。本文将深入探讨如何通过调用原生网络 API 实现同…

「Java开发中文指南」IntelliJ IDEA插件安装(一)

IntelliJ IDEA是java编程语言开发的集成环境。IntelliJ在业界被公认为最好的Java开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能是非常强大的。 插件扩展了Intel…

【分布式】分布式中的时钟

一、物理时钟 vs 逻辑时钟 时钟的存在主要是为了标识事件的发生顺序。 分布式系统不使用物理时钟记录事件&#xff0c;分布式系统中每个节点记录的时间并不一样&#xff0c;即使设置了 NTP 时间同步节点间也存在毫秒级别的偏差 所以需要有另外的方法记录事件顺序关系&#x…

vue2中使用echarts

1,安装echarts npm install --save echarts 2&#xff0c;具体页面 <template><div class"app-container"><div class"aa" id"main" style"width: 500px; height: 400px;"></div></div> </te…

PDF 批量处理软件BatchOutput PDF mac中文版介绍

BatchOutput PDF mac是一款适用于 Mac 的 PDF 批量处理软件。它可以帮助用户将多个 PDF 文件进行异步处理&#xff0c;提高工作效率。 BatchOutput PDF 可以自动化执行许多任务&#xff0c;包括 PDF 文件的打印、转换、分割、压缩、加密、重命名等&#xff0c;而且它还可以将自…

Elasticsearch知识

目录 Elasticsearch逻辑设计和物理设计 逻辑设计物理设计Elasticsearch原理 倒排索引文档的分析过程保存文档搜索文档写数据的底层原理 数据刷新&#xff08;fresh&#xff09;事务日志的写入ES在大数据量下的性能优化 文件系统缓存优化数据预热文档&#xff08;Document&…