(三)、JAVA基于OPENXML的word文档插入、合并、替换操作系列之html转word

系列笔记传送门

富文本转word文档

准备待转换内容

内容清理与格式化

转换成word文档

输出结果展示

附加内容、常见错误

结束语

系列笔记传送门

本系列笔记包含以下几篇,本篇主要是吹牛、理论、外加做个目录,等不及的可以直接传送门起飞:

(一)、JAVA基于OPENXML的word文档插入、合并、替换操作系列之基础篇

(二)、JAVA基于OPENXML的word文档插入、合并、替换操作系列之基础篇-图片在word结构中的存放、插入、替换图片

(三)、JAVA基于OPENXML的word文档插入、合并、替换操作系列之html转word

(四)、JAVA基于OPENXML的word文档插入、合并、替换操作系列之word转html(待更新…)

(五)、JAVA基于OPENXML的word文档插入、合并、替换操作系列之word文件合并(待更新…)

(六)、JAVA基于OPENXML的word文档插入、合并、替换操作系列之动态模板、占位符(待更新…)

(七)、JAVA基于OPENXML的word文档插入、合并、替换操作系列之模板综合应用、文字、图片、富文本内容填充(待更新…)

富文本转word文档

我们经常会遇到在项目中,需要将一段内容输出到word、 比如通过在你的项目中放一个富文本编辑器,通过用户的输入提交后,将它做一些处理之后这个内容生成一个word文档,然后提供用户下载使用,或者用户上传一个word文档,需要在你项目的界面上显示出来,那么这篇笔记或许可以帮到你, 当然这只是其中一个实现方案,网上有许多其他实现方案不在此做探讨

准备待转换内容

我们先来准备一段富文内容,通过OPENXML转成word需要一个完整的html格式文档,比如有不支持属性的、属性有单引号、没有引号的等各种不标准的HTML代码,在处理过程中会出错,或者被忽略掉。

内容清理与格式化

此处我们通过借助 Jsoup来将html转为 xhtml ,操作之后html代码段就会被格式化属性="属性值" 这种标准的格式,当然还有更多其他效果,具体请自行动手体验。

public String cleanHtmlQuot(String htmlContent){

if(StringUtils.isBlank(htmlContent))

return htmlContent;

// 这步是将html代码中转义的代码进行恢复, 从富文编辑提交过来的内容,会进行一个特殊字符转义

// 去除本地图片(file://)或地址为空的图片,(?i)不区分大小写, 我的代码中去掉了,你可以不要

String unescape = StringEscapeUtils.unescapeHtml4(htmlContent)

.replaceAll("(?i)","");

return Jsoup.clean(unescape, user_content_filter)

.replace("windowtext","#000"); //windowtext 不识别,改成 #000

}

/**

* html 格式化,转成标准的 xhtml 格式

* 1px=0.75pt,常见的宋体9pt=12px pt=px乘以3/4。

* 1mm约等于2.83pt,A4尺寸是21cm*29.7cm,所以应该是594.3pt*840.51pt

* @param html

* @return

*/

public String html2xhtml(String html){

final Document htmldoc = Jsoup.parse( this.cleanHtmlQuot(trimNull(html)));

htmldoc.outputSettings().syntax(Document.OutputSettings.Syntax.xml).escapeMode(Entities.EscapeMode.xhtml);

return htmldoc.html();//.replaceAll("(?i)( )|( )"," ");

}

格式化后的效果是这样的, 没有它都给自动加上了

转换成word文档

此处通过 DOCX4J 将html内容转成POI的XWPFDocument对象,然后直接输出为word文档.

/**

* @param htmlBody

* @return

*/

public XWPFDocument html2WordDocument(String htmlBody){

if(StringUtils.isBlank(htmlBody)){

return null;

}

final String htmlContent = html2xhtml(htmlBody);

try(ByteArrayOutputStream bos = new ByteArrayOutputStream()){

WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();

XHTML2WordImporterImpl XHTMLImporterImpler = new XHTML2WordImporterImpl(wordMLPackage);

// XHTMLImporterImpler.setXHTMLImageHandler(new XHTML2WordImageHandler(XHTMLImporterImpler));

// 延迟解析比率 ,解决报错: java.io.IOException: Zip bomb detected!

// 参考 https://stackoverflow.com/questions/46796874/java-io-ioexception-failed-to-read-zip-entry-source

ZipSecureFile.setMinInflateRatio(-1.0d);

wordMLPackage.getMainDocumentPart().getContent().addAll(XHTMLImporterImpler.convert(htmlContent,""));

wordMLPackage.save(bos);

// logger.info("tmpFile:{}", tmpFile.getAbsolutePath());

// wordMLPackage.save(new File("/Users/tenney/Desktop/word.docx"));

return verifyContent4MSOffice(new XWPFDocument(new ByteArrayInputStream(bos.toByteArray())));

} catch (Exception e) {

logger.error("解析HTML为WORD内容出错:{}", e.getMessage(), e);

}

return null;

}

@Test

public void html2Word() throws IOException {

WrodPlaceholderProcessor processor = new WrodPlaceholderProcessor(null,null,null);

long start = System.currentTimeMillis();

// XWPFDocument doc = processor.html2DOCXDocument(htmlText);

// System.err.println(processor.cleanHtmlQuot(htmlText));

XWPFDocument doc = processor.html2WordDocument(htmlText);

System.err.println(doc.getDocument().getBody().xmlText());

FileOutputStream dest = new FileOutputStream(new File("/Users/tenney/Desktop/2222222222.docx"));

// document.write(dest);

doc.write(dest);

// IOUtils.closeQuietly(dest);

System.err.println("用时:"+ (System.currentTimeMillis() - start) + " ms");

}

输出结果展示

转换过程会生成一个符合OPENXML规范的内容,如下

附加内容、常见错误

在我的实践过程中发现,转换表格时偶尔会出现,表格中转换出的行标签,却没有列内容引发报错,以下为我的解决方案,实现逻辑为:

在该行中创建一个列,并根据定义的列数进行列合并,最终目的其实就是转换为一个有效的空行。

/**

* 较验生成的内容是否符合微软office的格式要求

* @param document

* @return

*/

public XWPFDocument verifyContent4MSOffice(XWPFDocument document){

//较验表格

/**

*

* * * ....

*

* *

*

*

*

*

*

*

*

* *

*

* // 该处没有 tc(column),将导致ms office打开报错

*

*

* *

*

* * *

*

*

* *

*

*

*

*

*

*

*

* *

*

*

*

* *

*/

// document.getDocument().getBody().getSectPr().getPgSz();

document.getDocument().getBody().getTblList().forEach(tbl->{

// tbl.getTblPr().getTblW().setW(BigInteger.valueOf(2000));

// tbl.getTblPr().getTblW().setType(STTblWidth.DXA);

// tbl.getTblPr().addNewTblStyle().setVal("StyledTable");

CTTblGrid grid = tbl.getTblGrid();

List rows = tbl.getTrList();

try{

rows.forEach(row->{

if(row.getTcList() == null || row.getTcList().isEmpty()){

CTTc tc= row.addNewTc();

tc.addNewP().addNewR().addNewT();

if(grid != null){

CTTcPr pr = tc.addNewTcPr();

pr.addNewGridSpan().setVal(BigInteger.valueOf(grid.getGridColList().size()));

tc.setTcPr(pr);

}

}

});

}catch (Exception e){

logger.warn("较验文档内容有效性出错:{}", e.getMessage());

}

});

return document;

}

结束语

网上其实有很多html转成word的方法,鄙人也看过很多,比如直接通过POI实现的,甚至有手动逐个解析word中每个元素,比如图片、表格、段落等等然后再逐一用html代码拼出来的,当然这些方法我也用过,只是未能达到我的目的,要么转换的效果不够好,要么转换不完整,所以经过我长时间的折腾拼凑出这么一个方法,虽然也算不上很完美,但在我见过的方法中应该算是比较好用的了,唠叨这么一段只是提示一点解决问题的思路,方法千千万,每个方法也有每个方法特色和应用场景,找到适合自己的就是最完美的!

java openxml 操作 word,(三)、JAVA基于OPENXML的word文档插入、合并、替换操作系列之html转word...相关推荐

  1. (一)JAVA基于OPENXML的word文档插入、合并、替换操作系列之基础篇

    (一)JAVA基于OPENXML的word文档插入.合并.替换操作系列之基础篇 前言 什么是Open Xml? Open XML SDK 这系列笔记要做点什么? 涉及技术点 关于word.openxm ...

  2. (五)、JAVA基于OPENXML的word文档插入、合并、替换操作系列之word文件合并[支持多文件]

    (五).JAVA基于OPENXML的word文档插入.合并.替换操作系列之word文件合并[支持多文件] 二.word合并的多种方案简单比较 三.基于Open Xml WordprocessingML ...

  3. java word设置纸张a3,Word中进行设置A3文档纸张大小的操作技巧

    在工作中最常用的纸质文档是A4的,但是我们有时候也需要用一些A3甚至其他纸张的文档,那么,在做文档的时候该如何设置呢?今天,学习啦小编就教大家在Word中进行设置A3文档纸张大小的操作技巧. Word ...

  4. Java使用Aspose组件进行多文档间的转换操作

    什么是Aspose? Aspose.Total是Aspose公司旗下的最全的一套office文档管理方案,主要提供.net跟java两个开发语言的控件套包,通过它,我们可以有计划地操纵一些商业中最流行 ...

  5. 基于JAVA糖果销售管理系统计算机毕业设计源码+数据库+lw文档+系统+部署

    基于JAVA糖果销售管理系统计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA糖果销售管理系统计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S架构 开发语 ...

  6. 基于JAVA汽车租赁系统计算机毕业设计源码+系统+lw文档+部署

    基于JAVA汽车租赁系统计算机毕业设计源码+系统+lw文档+部署 基于JAVA汽车租赁系统计算机毕业设计源码+系统+lw文档+部署 本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 开发软 ...

  7. 基于Java毕业设计在线直播平台源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计在线直播平台源码+系统+mysql+lw文档+部署软件 基于Java毕业设计在线直播平台源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开发语言: ...

  8. 基于Java毕业设计弹幕视频网站源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计弹幕视频网站源码+系统+mysql+lw文档+部署软件 基于Java毕业设计弹幕视频网站源码+系统+mysql+lw文档+部署软件 开发语言:Java语言 开发软件:idea ec ...

  9. 基于JAVA电子设备销售网站计算机毕业设计源码+系统+lw文档+部署

    基于JAVA电子设备销售网站计算机毕业设计源码+系统+lw文档+部署 基于JAVA电子设备销售网站计算机毕业设计源码+系统+lw文档+部署 本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 ...

最新文章

  1. 亚马逊新品流量是上架开始算吗?
  2. 【必读】文案都写不好,还谈什么互联网思维
  3. java执行sql文件_面试官:MyBatis SQL是如何执行的?把这篇文章甩给他
  4. Java Web——文件下载时中文文件名乱码问题解决方案
  5. Maven项目,项目上出现红叉,项目内没有报错,可以运行
  6. 【WebRTC---源码篇】(二)PeerConnectionFactory
  7. 关于JDK8采坑JCE加密限制版本问题
  8. 抖音去水印解析网址入口_抖音去水印 视频去水印 小工具
  9. 支持中国西安申办ICCV2025,见证计算机视觉蓬勃发展的20年 | Vote for ICCV2025 Xi'an China...
  10. 关于数据库记录排序问题
  11. input text 输入即可识别
  12. php扩展介绍,初步介绍PHP扩展开发经验分享
  13. 典型三种近场通信的特点以及未来趋势
  14. java计算机毕业设计快滴预约平台MyBatis+系统+LW文档+源码+调试部署
  15. 传奇3单机显示服务器进不去,传奇3私服单机 数据库连接不上 dafe
  16. Kettle Carte集群 在windows 上的部署与运行
  17. 【转载】腾讯服务器centos服务器下mysql的安装
  18. Java闲杂笔记摘抄
  19. Freemarker静态页面使用方法详解+指令
  20. Qt应用程序缺少DLL

热门文章

  1. 一般的商城系统运营模式
  2. Exploiting Shared Representations for Personalized Federated Learning 论文笔记+代码解读
  3. 《 Python程序设计项目案例》— (期末大作业、课程设计、毕业设计)基于Python与Django的职工健康档案管理系统设计(附代码)
  4. thinkphp 5.0 “No input file specified”问题
  5. SSH使用及协议分析
  6. 适合企业的IT运维软件应具有哪些特点?
  7. 极路由1S 开启临时ssh 并刷breed成功
  8. 【Yocto移植】技术分享
  9. Cassandra官方文档整理
  10. 文件服务器ipc,看图理解进程间通信IPC