XDocReport
简介
XDocReport是GitHub上根据麻省理工学院许可证开源的Wrod导出框架。XDocReport可以根据ODT、Doc、Docx文档模板通过模板引擎语法(Freemarker、Velocity)转换为另外一种格式文档(Doc、Docx、XHTML、PDF)。
XDocReport特性
XDocReport是模块化而且非常轻便(不需要在你的服务器安装MS Office、LiberOffice)。你可以选择要管理的XML类型文档(docx、odt…)和选择熟悉的模板引擎(Freemarker、Velocity)组合使用。
- 支持OpenOffice、MS Word格式。
- 默认支持Freemarker、Velocity语法,也可以自己扩展语法。
- 支持报告生成的调试过程。
- 支持表格循环遍历。
- 支持动态图像替换。
- 在OSGI环境中管理XDcoReport。
- 支持格式转换器,默认支持的转换器(ODT 2 PDF、Docx 2 PDF).
- 支持实现自己的模板引擎。默认情况下实现了FreeMarker、Velocity。
- 支持转换器扩展。默认实现了ODT 2 PDF(通过ODFDOM+iText)、Docx 2 PDF(通过POI+iText)。
基本原理
工具类封装
package org.leaf.word.xdocreport;import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;import java.io.FileInputStream;
import java.io.IOException;public class WordUtils {public static ExportData getExportData(String url) throws IOException, XDocReportException {final IXDocReport report = createReport(url);final IContext context = report.createContext();return new ExportData(report, context);}private static IXDocReport createReport(String url) throws IOException, XDocReportException {final FileInputStream fileInputStream = new FileInputStream(url);return XDocReportRegistry.getRegistry().loadReport(fileInputStream, TemplateEngineKind.Freemarker);}}
package org.leaf.word.xdocreport;import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;import java.io.IOException;
import java.io.OutputStream;public class ExportData {private IXDocReport report;private IContext context;public ExportData(IXDocReport report, IContext context) {this.report = report;this.context = context;}public void process(OutputStream out) throws IOException, XDocReportException {report.process(context, out);}public void setData(String key, Object value) {FieldsMetadata fieldsMetadata = report.getFieldsMetadata();fieldsMetadata = fieldsMetadata == null ? new FieldsMetadata() : fieldsMetadata;fieldsMetadata.addFieldAsList(key);context.put(key, value);}
}
快速开始
模板
- 创建ODTHelloWordWithVelocity.docx文档,输入内容Hello ${name}。
- ${name}设置步骤
- Ctrl + F9,选择邮件合并类型,输入"${name}"
Maven
<!--org.leaf.word.to.pdf.aspose--><dependencies><!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/xdocreport --><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>xdocreport</artifactId><version>${xdocreport.version}</version></dependency><!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/fr.opensagres.xdocreport.document.docx --><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.document.docx</artifactId><version>${xdocreport.version}</version></dependency><!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/fr.opensagres.xdocreport.template --><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId><version>${xdocreport.version}</version></dependency><!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/fr.opensagres.xdocreport.template --><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.document</artifactId><version>${xdocreport.version}</version></dependency><!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/fr.opensagres.xdocreport.template --><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.core</artifactId><version>${xdocreport.version}</version></dependency><!-- https://mvnrepository.com/artifact/fr.opensagres.xdocreport/fr.opensagres.xdocreport.template --><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.converter</artifactId><version>${xdocreport.version}</version></dependency><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.converter.docx.xwpf</artifactId><version>${xdocreport.version}</version></dependency><dependency><groupId>fr.opensagres.xdocreport</groupId><artifactId>fr.opensagres.xdocreport.template.velocity</artifactId><version>${xdocreport.version}</version></dependency></dependencies>
示例代码
public static void main(String[] args) throws IOException, XDocReportException {final ExportData exportData = WordUtils.getExportData("F:\\idea-workspace\\my_source\\word-document\\src\\main\\resources\\xdocreport\\ODTHelloWordWithVelocity.docx");exportData.setData("name", "world");exportData.process(new FileOutputStream("F:\\idea-workspace\\my_source\\word-document\\src\\main\\resources\\xdocreport\\ODTHelloWordWithVelocity_out.docx"));}
结果
基本设置
普通域对象
图片对象
图片对象的设置使用书签设置
数据设置
Java
package org.leaf.word.xdocreport;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import fr.opensagres.xdocreport.core.XDocReportException;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;public class Demo1 {public static void main(String[] args) throws IOException, XDocReportException {final ExportData exportData = WordUtils.getExportData("F:\\idea-workspace\\my_source\\word-document\\src\\main\\resources\\xdocreport\\ODTHelloWordWithVelocity.docx");exportData.setData("data", readJSON());exportData.process(new FileOutputStream("F:\\idea-workspace\\my_source\\word-document\\src\\main\\resources\\xdocreport\\ODTHelloWordWithVelocity_out.docx"));}public static JSONObject readJSON() throws IOException {ObjectMapper mapper = new ObjectMapper();return mapper.readValue(new File("F:\\idea-workspace\\my_source\\word-document\\src\\main\\resources\\xdocreport\\xdocreport.json"), JSONObject.class);}}
JSON
{"userName": "张三","applyDate": "2022-12-12","applyDetail": [{"sqxm": "北京出差","sqje": 123458.695,"sxmx": "住宿","sqr": "张三","sqrq": "2022-12-26"},{"sqxm": "北京出差","sqje": 1238.695,"sxmx": "路费","sqr": "张三","sqrq": "2022-12-26"},{"sqxm": "北京出差","sqje": 128.695,"sxmx": "吃饭","sqr": "张三","sqrq": "2022-12-26"}],"list": ["1、飞机票", "2、电影票", "3、住宿发票"]
}
文本
普通文本使用${}
条件
条件使用[#if condition] [/#if]
表格
表格使用@before-row[#list data as d]和@after-row[/#list]表示遍历的开始和结束,文本的输入和普通文本一样
列表
列表遍历使用[#list data.list as l]开始和[/#list]结束