基于xdocreport导出复杂word文档
引入 maven 依赖
<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>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
controller 层
@ApiOperation(value = "导出(下载)", notes = "导出(下载)")
@GetMapping("exportReport")
public void exportReport(@RequestParam("unitOrgNum") String unitOrgNum, HttpServletResponse response) {
logger.error("导出报告,入参:{}", unitOrgNum);
OutputStream out = null;
try {
TResult<AnalysisReportDto> r = xxxService.getAnalysisReport(unitOrgNum);
PrettyHandleUtils.handle2Result().throwBizMessage(r);
//获取Word模板,模板存放路径在项目的resources目录下
InputStream ins = this.getClass().getResourceAsStream("/templates/AnalysisReportTemplate.docx");
//注册xdocreport实例并加载FreeMarker模板引擎
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(ins, TemplateEngineKind.Freemarker);
//创建xdocreport上下文对象
IContext context = report.createContext();
generateMsWordData(report, context, r.getTarget());
response.setCharacterEncoding("UTF-8");
response.setContentType("application/msword");
response.setHeader("Content-Disposition", " attachment; filename=".concat(String.valueOf(URLEncoder.encode(unitOrgNum + ".docx", "UTF-8"))));
out = response.getOutputStream();
report.process(context, out);
out.flush();
} catch (Exception e) {
logger.error("unitOrgNum:{}---导出报告:{}", unitOrgNum, e.getMessage(), e);
throw BizException.newInstance(Constants.ERROR.RESPONSE_ERROR,e.getMessage());
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void generateMsWordData(IXDocReport report, IContext context, AnalysisReportDto target) throws XDocReportException {
context.put("legalName", target.getLegalName());
context.put("unitOrgNum", target.getUnitOrgNum());
context.put("baseSituation", target.getBaseSituation());
context.put("tender3", target.getAchievement().getTender3());
context.put("punishItems", target.getPerformanceScore().getSpecialAnalysis().getPunishItems());
//创建字段元数据
FieldsMetadata fm = report.createFieldsMetadata();
fm.load("baseSituation", LegalBaseSituationDto.class, false);
fm.load("tender3", TenderSituationNearDto.class, false);
fm.load("punishItems", SpecialPunishItemDto.class, true);
report.setFieldsMetadata(fm);
}
freemarker 模板
其中,«@before-row[#list punishItems as item]»«${item?index+1}»«@after-row[/#list]»,分别是 «@before-row[#list punishItems as item]» 和 «${item?index+1}»«@after-row[/#list]»
操作步骤
1.在Word模板中选中要替换的文本,然后键盘使用 Ctrl + F9 组合键将其设置为域,此时文本会被"{}"包围,接着鼠标右键选择【编辑域(E)...】:
«${tender3.intervalMap["T1"]}»为map对象使用
«${baseSituation.dataTimestamp!}»指定默认值为空,通过!(感叹号)号实现
也可指定默认值为其他的,如«${baseSituation.engagedIndustryField!'暂无»
2.在弹出的对话框中,类别选择“邮件合并”,域名选择 "MergeField",域属性中的域名填入模版表达式${legalName!},点击【确定】按钮;
常见语法
1、${....}
用于变量展示,也可以用作对象属性或者map值的展示,用法如下:
对象属性:${object.XXX}
map:${object["XXX"]}
2、list
数组、列表的循环展示,一般写法
[#list list as item]
${item.a}
[/#list]
参考文档
https://blog.csdn.net/lzh_java_demo/article/details/121122932
https://blog.csdn.net/plxddyxnmd/article/details/109129838