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.pswp.cn/news/167041.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/167041.shtml
英文地址,請注明出處:http://en.pswp.cn/news/167041.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

代碼隨想錄算法訓練營第30天|回溯總結 332. 重新安排行程

回溯是遞歸的副產品&#xff0c;只要有遞歸就會有回溯&#xff0c;所以回溯法也經常和二叉樹遍歷&#xff0c;深度優先搜索混在一起&#xff0c;因為這兩種方式都是用了遞歸。 回溯法就是暴力搜索&#xff0c;并不是什么高效的算法&#xff0c;最多再剪枝一下。 回溯算法能解…

Linux安裝Tesseract-OCR(操作系統CentOS)

Linux安裝Tesseract-OCR 第一步&#xff0c;安裝依賴第二步&#xff0c;下載安裝包第三步&#xff0c;安裝leptonica庫第四步&#xff0c;安裝tesseract第五步&#xff0c;添加語言包第六步&#xff0c;測試 第一步&#xff0c;安裝依賴 sudo yum install libpng-devel rpm -q…

從零學算法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;第…

ubuntu22.04 arrch64版在線安裝mysql8

腳本 # todo參考鏈接 Ubuntu服務器配置mysql8_ubuntu安裝mysql8-CSDN博客

樂得瑞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執行當前程序時,由于系統出現了…

抖音推廣實戰,教你如何快速成長

一、背景介紹 隨著移動互聯網的飛速發展&#xff0c;抖音作為一款短視頻平臺&#xff0c;已經成為越來越多人生活中的一部分。它不僅提供了豐富多彩的內容&#xff0c;還為商家提供了推廣產品的絕佳平臺。本文將為大家詳細解析抖音推廣實戰&#xff0c;幫助大家快速成長。 二…

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

演示視頻&#xff1a; 基于SSM的老年公寓信息管理&#xff08;有報告&#xff09;。Javaee項目 項目介紹&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三層體系結構&#xff0c;通過Spring SpringMvc …

Spring Boot 應用的 Docker 化:從 Maven 構建到 Docker 部署的完整指南

1. 使用Dockerfile部署 # 使用Java 8基礎鏡像 FROM java:8 LABEL authors"mabh"# 設置時區為Asia/Shanghai&#xff0c;可以根據需要更改 ENV TIME_ZONEAsia/Shanghai# 更新時區 RUN ln -snf /usr/share/zoneinfo/$TIME_ZONE /etc/localtime && echo $TIME_…

堆的實現(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;采用先進的神經網絡架構&…

nodejs 文件目錄監聽 chokidar watchpack

文件監聽實現&#xff0c;推薦使用chokidar&#xff1a; chokidar 默認是基于事件監聽文件 const chokidar require("chokidar"); const folderToWatch path.join(__dirname, "lib"); const watcher chokidar.watch(folderToWatch, { ignored: /(^|[…

在Vue中使用Echarts

文章目錄 Echarts1. 介紹2. 體驗NPM 安裝 Echarts定義 Echarts 容器引入 Echarts 3. 基礎配置 Echarts 1. 介紹 常見的數據可視化庫&#xff1a; D3.js 目前 Web 端評價最高的 Javascript 可視化工具庫(入手難)ECharts.js 百度出品的一個開源 Javascript 數據可視化庫Highch…

鼠標拖拽問題,不選中文本不觸發單擊事件

文章目錄 1. 為什么鼠標單擊的時候觸發了mousemove事件&#xff1f;明明鼠標沒有移動2. 鼠標拖拽元素怎么能不觸發單擊事件&#xff1f;怎么處理鼠標在元素內的相對定位&#xff0c;而不是每次定位到左上角&#xff1f;方式一&#xff1a;拖拽的元素沒有注冊click監聽就不會觸發…

10年測試老鳥,自動化測試經驗10條建議,一路狂飆...

目錄&#xff1a;導讀 前言一、Python編程入門到精通二、接口自動化項目實戰三、Web自動化項目實戰四、App自動化項目實戰五、一線大廠簡歷六、測試開發DevOps體系七、常用自動化測試工具八、JMeter性能測試九、總結&#xff08;尾部小驚喜&#xff09; 前言 1、哪一刻&#x…

Java面試題(每天10題)-------連載(37)

目錄 Mysql篇 1、Mysql如何優化DISTINCT&#xff1f; 2、如何輸入字符為十六進制數字&#xff1f; 3、如何顯示前50行&#xff1f; 4、可以使用多少列創建索引&#xff1f; 5、NOW()和CURRENT_DATE()有什么區別&#xff1f; 6、什么樣的對象可以使用CREATE語句創建&…

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

一、什么是Postman Collection&#xff1f; Postman Collection是可讓您將各個請求分組在一起。 您可以將這些請求組織到文件夾中。中文經常將collection翻譯成收藏夾。如果再下文中看到這樣的翻譯不要覺得意外。Postman Collection會使你的工作效率更上一層樓。Postman Colle…