Java 利用XDocReport 根据word模板导出
配置文件所需jar包
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls</artifactId>
<version>2.6.0</version>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls-poi</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.core</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.document</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.template</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
<version>2.0.2</version>
</dependency>
模板设置示例和介绍
以下是个人设置的模板的示例,我这边是通过WPS编辑word模板的。
1.新建word文档
2.根据需求设置内容,以及替换需要动态填充的数据
(模板示例)
【Ctrl+F9】:
【右击选择编辑域】
【首先替换文本的字段】
${title}
${} 是固定的格式
title 是要替换的字段
【图片设置】
首先插入一张图片用于替换,然后在插入书签中设置标记名
点击书签设置标签名
[#if password??] 判断内容是否要展示 [/#if]
下面是我的密码是否要展示,完整代码如下 :
设置三个编辑域:
第一个:[#if password??] 第二个:${password} 第三个: [/#if]
表格遍历:可以用代码设置开始行和结束行,其中 h 为自己存放list集合数据,
设置两个编辑域,分别写入开始和结束标识
@before-row[#list h as data]
@after-row[/#list]
也可以不写,但是要在代码中标记h 为list 集合,并标明参数类型
fieldsMetadata.load("h",TestPicNameVo.class,true);
多个数据遍历展示
三个编辑域,设置开头,遍历对象,遍历结束标记
[#list data.pics1 as item1] 所需遍历的文本或者图片 [/#list]
代码完整示例如下
实体1
import lombok.Data;
import java.util.List;
@Data
public class TestPicNameVo {
private String name1;
private String name2;
private List<TestPicVo> picVoList;
private List<TestPicVo> pics2;
}
实体2
import fr.opensagres.xdocreport.document.images.IImageProvider;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestPicVo {
private IImageProvider pic;
}
控制类:
@GetMapping("testPic")
public void testPic() throws Exception {
WordUtils.testPic();
}
工具类:
import cn.hutool.extra.template.TemplateException;
import com.mskj.common.utils.StringUtils;
import com.mskj.organization.vo.*;
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.images.ByteArrayImageProvider;
import fr.opensagres.xdocreport.document.images.FileImageProvider;
import fr.opensagres.xdocreport.document.images.IImageProvider;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
import fr.opensagres.xdocreport.template.formatter.NullImageBehaviour;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
public class WordUtils {
//test实现类
public static void testPic() throws Exception {
//1.通过freemarker模板引擎加载文档,并缓存到registry中
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream("F:\\upload\\testTemple\\h_rf.docx");
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
//2.设置填充字段、填充类以及是否为list。
FieldsMetadata fieldsMetadata = report.createFieldsMetadata();
IContext context = report.createContext();
context.put("title","标题测试名");
context.put("userName","张三");
context.put("password","123456");
List<TestPicNameVo> list = new ArrayList<>();
TestPicNameVo picNameVo1 = new TestPicNameVo();
picNameVo1.setName1("one");
picNameVo1.setName2("one_after");
List<TestPicVo> picVoList = new ArrayList<>();
TestPicVo testPicVo1 = new TestPicVo(new FileImageProvider(new File("D:\\mskjcloud\\1.jpeg")));
TestPicVo testPicVo2 = new TestPicVo(new FileImageProvider(new File("D:\\mskjcloud\\2.jpg")));
picVoList.add(testPicVo1);
picVoList.add(testPicVo2);
picNameVo1.setPicVoList(picVoList);
List<TestPicVo> pics2 = new ArrayList<>();
TestPicVo testPicVo5 = new TestPicVo(new FileImageProvider(new File("D:\\mskjcloud\\1.jpeg")));
TestPicVo testPicVo6 = new TestPicVo(new FileImageProvider(new File("D:\\mskjcloud\\2.jpg")));
pics2.add(testPicVo6);
pics2.add(testPicVo5);
picNameVo1.setPics2(pics2);
list.add(picNameVo1);
// 第二行
TestPicNameVo picNameVo2 = new TestPicNameVo();
picNameVo2.setName1("two");
picNameVo2.setName2("two_after");
List<TestPicVo> picVoList1 = new ArrayList<>();
IImageProvider imageProvider1 = new FileImageProvider(new File("D:\\mskjcloud\\1.jpeg"));
imageProvider1.setSize(80f,90f);
TestPicVo testPicVo3 = new TestPicVo(imageProvider1);
picVoList1.add(testPicVo3);
picNameVo2.setPicVoList(picVoList1);
List<TestPicVo> pics3 = new ArrayList<>();
TestPicVo testPicVo8 = new TestPicVo(new FileImageProvider(new File("D:\\mskjcloud\\1.jpeg")));
pics3.add(testPicVo8);
picNameVo2.setPics2(pics3);
list.add(picNameVo2);
context.put("h", list); // 设置h为list 集合
fieldsMetadata.load("h",TestPicNameVo.class,true);
fieldsMetadata.addFieldAsImage("pic","list.pic",NullImageBehaviour.RemoveImageTemplate);
fieldsMetadata.addFieldAsImage("pic2","list2.pic",NullImageBehaviour.RemoveImageTemplate);
out = new FileOutputStream(new File("F:\\upload\\testTemple\\h_rf_out.docx"));
report.setFieldsMetadata(fieldsMetadata);
report.process(context, out);
} catch (IOException e) {
log.error("读取Word模板异常",e);
} catch (XDocReportException e) {
log.error("word模板生成失败",e);
} finally {
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
导出样子,图片若没有设置大小会默认的,设置大小如下补充代码
补充这个是设置图片规则的
IImageProvider imageProvider1 = new FileImageProvider(new File("D:\\mskjcloud\\1.jpeg"));
imageProvider1.setSize(80f,90f);
// 可以转化成PDF,只需要把
report.process(context, out);
// 换成以下代码
Options options = Options.getTo(ConverterTypeTo.PDF).via(ConverterTypeVia.XWPF);
report.convert(context, options, out);
参考链接
https://blog.csdn.net/weixin_44684303/article/details/128654324
补充demo链接地址
https://download.csdn.net/download/weixin_35332034/87789220