使用XDocReport将HTML格式数据转换为Word
文档地址:https://github.com/opensagres/xdocreport/wiki/DocxReportingQuickStart
本文采用XDocReport集合Freemaiker进行处理
1. 引入Maven依赖:
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>xdocreport</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
2. 创建Word模版
新建Word,在光标处通过快捷键Ctrl+F9 或 工具栏“插入”->“文档部件或文本”->“域”
根据电脑系统不同出现的界面不同,但内容都差不多,${text} 这个text就是后期要替换的变量了。

3. Java代码处理逻辑
String templateFilePath = request.getSession().getServletContext().getRealPath("/WEB-INF/templates/freemarkerTest.docx");
File file = new File(templateFilePath);
InputStream in = new FileInputStream(file);
IXDocReport report;
String targetPath = basePath + lawDownDto.getLawsName() + ".docx";
try {
report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
// 设置内容为HTML格式
FieldsMetadata metadata = report.createFieldsMetadata();
metadata.addFieldAsTextStyling("text", SyntaxKind.Html);
// 创建内容-text为模版中对应都变量名称
IContext context = report.createContext();
context.put("text", content);
// 生成文件
OutputStream out = new FileOutputStream(targetPath);
report.process(context, out);
} catch (XDocReportException e) {
e.printStackTrace();
}
文件下载:在生成文件逻辑后创建读取流返回即可。
=============================================================
如果文件中有图片需要处理:
图片方案一:单个图片且位置固定,可通过XDocReport配置模版处理
图片方案二:多个图片且位置不固定,可通过POI结合Freemarker进行处理
图片方案一:
1. 在模版中插入临时图片,选中图片并添加“书签”,书签名称是后续作为替换的变量

2. 代码中追加逻辑
在上面代码10后追加
// logo为模版中标签名称
metadata.addFieldAsImage("logo");
report.setFieldsMetadata(metadata);
在上面代码14行后追加
// IImageProvider可通过3种方式创建(File/IO流/ClassPath下文件)具体可参考顶部文档-Dynamic Image
IImageProvider logo = new FileImageProvider(new File("1950737_195902644.png"));
context.put("logo", logo);
图片方案二:
1. 在上面读取模版之前进行数据替换
// 处理文本中的图片,使用imgReplace变量替换
Map<String, Object> param = new HashMap<String, Object>();
if (StringUtils.isNotBlank(content)) {
content = HtmlUtils.htmlUnescape(content);
List<HashMap<String, String>> imgs = getImgStrContent(content);
int count = 0;
for (HashMap<String, String> img : imgs) {
count++;
//处理替换以“/>”结尾的img标签
content = content.replace(img.get("img"), "${imgReplace" + count + "}");
//处理替换以“>”结尾的img标签
content = content.replace(img.get("img1"), "${imgReplace" + count + "}");
Map<String, Object> header = new HashMap<String, Object>();
String result = "";
result = img.get("src");
//如果没有宽高属性,默认设置为
if(img.get("width") == null || img.get("height") == null) {
header.put("width", 150);
header.put("height", 150);
}else {
header.put("width", (int)(Double.parseDouble(img.get("width"))));
header.put("height", (int) (Double.parseDouble(img.get("height"))));
}
if( StringUtils.isNotBlank(result) ){
String type1 = result.substring(result.lastIndexOf(".") , result.length());
header.put("type", type1);
header.put("content",this.imageToInputStream(result));
}
param.put("${imgReplace" + count + "}", header);
}
}
//获取html中的图片元素信息
private List<HashMap<String, String>> getImgStrContent(String htmlStr) {
List<HashMap<String, String>> pics = new ArrayList<HashMap<String, String>>();
Document doc = Jsoup.parse(htmlStr);
if( doc != null ){
Elements imgs = doc.select("img");
if( imgs != null && imgs.size() > 0 ){
for (Element img : imgs) {
HashMap<String, String> map = new HashMap<String, String>();
if(!"".equals(img.attr("width"))) {
map.put("width", img.attr("width"));
}
if(!"".equals(img.attr("height"))) {
map.put("height", img.attr("height"));
}
map.put("img", img.toString().substring(0, img.toString().length() - 1) + "/>");
map.put("img1", img.toString());
map.put("src", img.attr("src"));
pics.add(map);
}
}
}
return pics;
}
// 读取生成的文件
readStream = new FileInputStream(targetPath);
ByteArrayOutputStream docxOs = new ByteArrayOutputStream();
int b = 0;
byte[] buf = new byte[1024];
while ((b = readStream.read(buf)) != -1) {
docxOs.write(buf, 0, b);
}
docxResponseStream = new ByteArrayInputStream(docxOs.toByteArray());
// 创建word 对象
XWPFDocument document = new XWPFDocument(docxResponseStream);
newOS = new ByteArrayOutputStream();
if (document != null && param != null) {
// 生成带图片的word(如需工具类请给我发邮件)
XWPFDocument customXWPFDocument = WordUtil.getWord(param, document);
// 设置表格边框样式(另外一片文章会介绍)
// List<XWPFTable> list = formatTableBorder(customXWPFDocument);
// 处理合并单元格(另外一片文章会介绍)
// mergeCell(content, list);
// 写入输出流返回
customXWPFDocument.write(newOS);
document.close();
customXWPFDocument.close();
resultInpu = new ByteArrayInputStream(newOS.toByteArray());
}else{
resultInpu = docxResponseStream;
}
以上内容即可完成Word中多图片的动态展示。
后续会写处理表格边框、单元格合并及段落都相关内容。
使用XDocReport将HTML格式数据转换为Word的更多相关文章
- Python将JSON格式数据转换为SQL语句以便导入MySQL数据库
前文中我们把网络爬虫爬取的数据保存为JSON格式,但为了能够更方便地处理数据.我们希望把这些数据导入到MySQL数据库中.phpMyadmin能够把MySQL数据库中的数据导出为JSON格式文件,但却 ...
- tensorflow学习笔记(10) mnist格式数据转换为TFrecords
本程序 (1)mnist的图片转换成TFrecords格式 (2) 读取TFrecords格式 # coding:utf-8 # 将MNIST输入数据转化为TFRecord的格式 # http://b ...
- 将JSON格式数据转换为javascript对象 JSON.parse()
<html><body><h2>通过 JSON 字符串来创建对象</h3><p>First Name: <span id=" ...
- Java导出带格式的Excel数据到Word表格
前言 在Word中创建报告时,我们经常会遇到这样的情况:我们需要将数据从Excel中复制和粘贴到Word中,这样读者就可以直接在Word中浏览数据,而不用打开Excel文档.在本文中,您将学习如何使用 ...
- 记录几种有关libsvm格式数据的list和dict用法
# list元素求和 sum = reduce(lambda x,y: x+y, mylist) # 比较两个 lists 的元素是否完全一致 if all(x==y for x, y in zip( ...
- CAJ Viewer安装流程以及CAJ或Pdf转换为Word格式
不多说,直接上干货! pdf转word格式,最简单的就是,实用工具 Adobe Acrobat DC 首先声明的是,将CAJ或者Pdf转换成Word文档,包括里面的文字.图片以及格式,根本不需 ...
- java 导出数据为word文档(保持模板格式)
导出数据到具体的word文档里面,word有一定的格式,需要保持不变 这里使用freemarker来实现: ①:设计好word文档格式,需要用数据填充的地方用便于识别的长字符串替换 如 aaaaa ...
- C# 将PDF文件转换为word格式
Pdf(Portable Document Format)意为“便携式文档格式”,是现在最流行的文件格式之一,它有很多优点如:尺寸较小.阅读方便.操作系统平台通用等,非常适合在网络上传播和使用.如今在 ...
- 数据转换为json格式的方法
数据转换为json格式: 如果一张表中存在主外键关系,模板自动生成的类是不可以转换成JSON格式的,此时需要重新写一个类,类前面需加[DataContract],字段前需加[DataMember],实 ...
随机推荐
- Pycharm工具使用和安装
1.安装包:https://pan.baidu.com/s/1O9JwuowlodhTR1m0VaKmhg 2.双击安装包安装: 3.选择安装目录 4.安装选项,Create Associations ...
- Junit框架使用(4)--JUnit常用断言及注解
从别人博客中抄过来一点东西 原文地址:http://blog.csdn.net/wangpeng047/article/details/9628449 断言是编写测试用例的核心实现方式,即期望值是多少 ...
- Graph Embedding Review:Graph Neural Network(GNN)综述
作者简介: 吴天龙 香侬科技researcher 公众号(suanfarensheng) 导言 图(graph)是一个非常常用的数据结构,现实世界中很多很多任务可以描述为图问题,比如社交网络,蛋白体 ...
- 「总结」插头$dp$
集中做完了插头$dp$ 写一下题解. 一开始学的时候还是挺蒙的. 不过后来站在轮廓线$dp$的角度上来看就简单多了. 其实就是一种联通性$dp$,只不过情况比较多而已了. 本来转移方式有两种.逐行和逐 ...
- 洛谷 P4053 [JSOI2007]建筑抢修
传送门 思路 首先题意比较容易明白: n个建筑需要修复,只能同时修一个建筑,每个建筑修复需要t1时间,且必须在t2时间前修完,否则此建筑报废 问最多能修好多少个建筑 如果一个建筑在规定时间内没有修好的 ...
- WIMBuilder2软件包及精简方案,请把补丁包放到指定位置
WIMBuilder2软件包及精简方案请把补丁包放到指定位置WimBuilder2-20190901\Projects\WIN10XPE\目录下面精简方案测试适用于LTSB2019.17763.316 ...
- jquery.pagination.js的使用
html页面 //要显示内容表格 <table id="gifts"> <tr class='first'> <th>时间</th> ...
- EPPlus.Core 处理 Excel 报错之天坑 WPS
最近工作中常常有有数据处理的需求,一个Excel动不动就是上十万的数据量,在用 EPPlus.Core 导入数据入库的时候遇到了一个莫名其妙的问题 The given key 'rId2' was n ...
- Java中HashMap和TreeMap的区别
什么是Map集合在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.这就是我们平时说的键值对. HashMap ...
- 强大的Scala模式匹配
用过Scala的模式匹配,感觉Java的弱爆了.Scala几乎可以匹配任何数据类型,如果默认的不能满足你的要求,你可以自定义模式匹配. 介绍Scala的模式匹配前,我们先了解清楚unapply()与u ...