当前位置: 首页 > news >正文

java 富文本(含图片)导出为docx文件,以及docx文件的合并

应用场景:

本身是用easypoi来进行导出docx文件的,但是发现easypoi 不支持导出富文本格式。于是有了此场景。

解决思路:

  1. 先把富文本(含图片)内容转为docx文件。
  2. 将easypoi导出的文件 与 富文本转出的docx文件 合并。
  3. 获取到最终文件
  4. 注释清楚的一批,又不会的直接留言。不经常看,回复的可能不及时

使用工具:
使用了e-iceblue依赖,来进行对docx文档的操作(富文本转docx,合并文档)。(缺点就是有水印,需要去除文档中的水印)

用到的依赖(应该有多余的):

 <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.1.0</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>4.1.0</version></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>4.1.0</version></dependency><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.13.1</version></dependency><dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency><dependency><groupId>e-iceblue</groupId><artifactId>spire.doc</artifactId><version>12.4.1</version></dependency>
<!--poi--><dependency><groupId>org.apache.poi</groupId><artifactId>poi-examples</artifactId><version>3.14</version></dependency></dependencies><repositories><repository><id>com.e-iceblue</id><name>e-iceblue</name><url>http://repo.e-iceblue.cn/repository/maven-public/</url></repository></repositories>

富文本转为docx文档

 /*** 富文本导出为docx文档* @param htmlContext 富文本内容* @param temporaryFileName  导出的临时文件名称* @param titleName  这一块富文本内容的标题,看自己需求* @return* @throws IOException*/private String htmlStringToWord(String htmlContext, String temporaryFileName, String titleName) throws IOException {
//        替换img 标签中  src的代理路径,换成自己的 profile为我图片的保存路径,自己替换htmlContext = htmlContext.replace("/dev-api/profile", profile).replace("/prod-api/profile", profile).replace("http://localhost", "");//临时保存文件路径String filePath = profile + temporaryFilePath + temporaryFileName + ".docx";//新建Document对象com.spire.doc.Document document = new com.spire.doc.Document();
//         在此docx文件中 创一个标题样式-可以不要ParagraphStyle style1 = new ParagraphStyle(document);style1.setName("titleStyle");style1.getCharacterFormat().setBold(true);style1.getCharacterFormat().setFontSize(16f);style1.getCharacterFormat().setFontName("Times New Roman");document.getStyles().add(style1);//添加sectionSection sec = document.addSection();//        先新增一个标题 可以不要Paragraph para1 = sec.addParagraph();
//        titleName 为 方法传入 可以不要para1.appendText(titleName);para1.applyStyle("titleStyle");//        img标签的 正则表达式String imgPattern = "<img\\s+[^>]*src=\"([^\"]*)\"[^>]*>";Pattern pattern = Pattern.compile(imgPattern);Matcher matcher = pattern.matcher(htmlContext);//        创建表格Table table = sec.addTable(true);
//        只有一个单元格table.resetCells(1,1);// 获取左页边距float leftMargin = sec.getPageSetup().getMargins().getLeft();// 获取右页边距float rightMargin = sec.getPageSetup().getMargins().getRight();double pageWidth = sec.getPageSetup().getPageSize().getWidth() - leftMargin - rightMargin;//        获取第(1,1)单元格TableCell cell = table.getRows().get(0).getCells().get(0);int lastIndex = 0;while (matcher.find()) {// 获取 img 标签之前的 HTML 片段String textBeforeImg = htmlContext.substring(lastIndex, matcher.start());// 添加 HTML 片段到段落Paragraph textParagraph = cell.addParagraph();textParagraph.appendHTML(textBeforeImg);// 获取 src 属性的值String imgSrc = matcher.group(1);// 添加图片到新段落Paragraph imgParagraph = cell.addParagraph();DocPicture picture = new DocPicture(document);picture.loadImage(imgSrc);imgParagraph.getChildObjects().insert(0, picture);// 更新 lastIndexlastIndex = matcher.end();}
//        新增表格的段落Paragraph remainingTextParagraph = cell.addParagraph();remainingTextParagraph.appendHTML(htmlContext.substring(lastIndex));
//        表格宽度table.getRows().get(0).getCells().get(0).setCellWidth((float)(pageWidth * 1.3), CellWidthType.Point);//文档另存为docxdocument.saveToFile(filePath, FileFormat.Docx);return filePath;}

合并文档

/*** 合并文档  另起一页合并* @param filePath1  最终留存文件路径* @param filePath2 被合并文档路径* @return*/private String mergeDocx(String filePath1, String filePath2, String finalFilePath){//创建 Document 类的对象并从磁盘加载 Word 文档com.spire.doc.Document document = new com.spire.doc.Document(filePath1);//将另一个文档插入当前文档document.insertTextFromFile(filePath2, FileFormat.Docx);//保存结果文档document.saveToFile(finalFilePath, FileFormat.Docx);return finalFilePath;}/*** 合并文档  内容合并  不另起一页* @param filePath1  最终留存文件路径* @param filePath2 被合并文档路径* @return*/private String mergeDocxFile(String filePath1, String filePath2, String finalFilePath){com.spire.doc.Document document1  = new com.spire.doc.Document(filePath1);com.spire.doc.Document document2  = new com.spire.doc.Document(filePath2);//在第二个文档中循环获取所有节for (Object sectionObj : (Iterable) document2.getSections()) {Section sec=(Section)sectionObj;//在所有节中循环获取所有子对象for (Object docObj :(Iterable ) sec.getBody().getChildObjects()) {DocumentObject obj=(DocumentObject)docObj;//获取第一个文档的最后一节Section lastSection = document1.getLastSection();//将所有子对象添加到第一个文档的最后一节中Body body = lastSection.getBody();body.getChildObjects().add(obj.deepClone());}}//保存结果文档document1.saveToFile(finalFilePath, FileFormat.Docx);return finalFilePath;}

相关文章:

  • 【免费Web系列】大家好 ,今天是Web课程的第二二天点赞收藏关注,持续更新作品 !
  • Suno AI如何解决中文多音字的问题? 耗费500积分,亲测有效 ,V4版本会不会直接支持呢?
  • Unity 材质系统优化(mesh相同,图片不同,但是可以将所有的图片合成一张图集)
  • 1V升3V升压LED驱动WT7013
  • 解析文字示例
  • Starknet架构之Starknet state、State commitment
  • 000003 - Hadoop集群配置
  • 快人一步!利用LLM实现数据处理自动化
  • Linux之管道符
  • 嵌入式操作系统_2.嵌入式操作系统的一般架构
  • Redis-数据结构-跳表详解
  • 中国银行信息科技运营中心、软件中心春招笔试测评面试体检全记录
  • KIVY AliasProperty 运用报错汇总
  • 一行代码实现鼠标横向滚动
  • Ubuntu的文件权限介绍
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • JavaScript异步流程控制的前世今生
  • Octave 入门
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • Vue2.x学习三:事件处理生命周期钩子
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 码农张的Bug人生 - 初来乍到
  • 排序(1):冒泡排序
  • 配置 PM2 实现代码自动发布
  • 区块链技术特点之去中心化特性
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 如何在GitHub上创建个人博客
  • 入手阿里云新服务器的部署NODE
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 探索 JS 中的模块化
  • 网络应用优化——时延与带宽
  • 我的面试准备过程--容器(更新中)
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 一天一个设计模式之JS实现——适配器模式
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 云大使推广中的常见热门问题
  • const的用法,特别是用在函数前面与后面的区别
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • (1)svelte 教程:hello world
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (16)Reactor的测试——响应式Spring的道法术器
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (LeetCode C++)盛最多水的容器
  • (机器学习的矩阵)(向量、矩阵与多元线性回归)
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (十八)SpringBoot之发送QQ邮件
  • (十六)Flask之蓝图
  • (四)模仿学习-完成后台管理页面查询
  • (学习总结16)C++模版2
  • .net 中viewstate的原理和使用
  • .NET 中创建支持集合初始化器的类型
  • .NET程序员迈向卓越的必由之路
  • .NET开源项目介绍及资源推荐:数据持久层 (微软MVP写作)