![知识共享许可协议](https://csdnimg.cn/release/phoenix/images/creativecommons/80x15.png)
原文地址:https://liujiao111.github.io/2019/07/04/html2word/
背景介绍
由于在项目中需要将富文本生成的HTML文档内容导出为word,并且里面的图片可能来自于用户上传,也可能是来源于网络图片,因此需要在生成的word中做特别的处理。导出的工具使用freemaker,首先说明的是这个也有一定的局限性,在样式匹配度上可能有一定的差异,不过功能是没问题的,先看一下示例。
这是最初设置的模板:
替换的HMTL文本(其中替换为模板的${content}处):
<p>3333333333333333<img src=\"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1707394542,3094357330&fm=15&gp=0.jpg\" /></p>\n" + "<table style=\"border-collapse: collapse; width: 100%;\" border=\"1\">\n" + "<tbody>\n" + "<tr>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "</tr>\n" + "<tr>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "</tr>\n" + "<tr>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "</tr>\n" + "<tr>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "</tr>\n" + "<tr>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "</tr>\n" + "<tr>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "</tr>\n" + "<tr>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "</tr>\n" + "<tr>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "</tr>\n" + "<tr>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "</tr>\n" + "<tr>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "<td style=\"width: 10%;\"> </td>\n" + "</tr>\n" + "</tbody>\n" + "</table>"
其中img标签的src地址来源于网络。
替换内容后的结果展示:
步骤大致分为两个阶段,一是制作模板,二是编码。以下为各个步骤的详细介绍。
模板制作
-
用office的word(最好是高版本),新建一个word文档,设置文本样式以及占位符,如
${content}
,后面会在程序中根据关键字content替换其中的内容。 -
将word另存为.mth结尾的单个网页文件,并保存到桌面,如下所示:
-
用文本编辑器打开文件内容,推荐使用notepad++之类,接下来需要修改文本内容,是重点:
-
将里面的gb2312字符全部替换为utf-8,大概有四处。
-
使用搜索功能搜索
<?xml version=3D"1.0"
,大概在1300多行的样子,在这个xml头部定义下方加上
${imagesBase64String!""}
并且记录下下方的------=_NextPart_01D53273.A82F7D10
中_号后面的字符串:01D53273.A82F7D10
以及下方的Content-Location: file:///C:/213792E5/set_template.files/header.htm
(在程序中使用),看图就知道了:
- 在文本倒数第二行加上
${imagesXmlHrefString!""}
- 修改就算完成了,然后保存,将文件后缀修改为ftl,该ftl下面会在程序中读取使用。
编码
- 新建一个springboot项目,引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.8.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.directory.studio/org.apache.commons.codec -->
<dependency>
<groupId>org.apache.directory.studio</groupId>
<artifactId>org.apache.commons.codec</artifactId>
<version>1.8</version>
</dependency>
- 在src/main/resources目录下新建文件夹templates, 将模板制作最后的ftl文件拷贝到templates目录下。
- 然后就是读取HTML进行解析、转换,图片处理,写入Word的一系列操作,具体代码见
https://github.com/liujiao111/html2word
修改Html2WordTest中main方法里面的参数即可运行出效果,具体注意事项已有标注。
经过测试, 多张图片也是可以的哦。