基于xdocreport+freemarker导出复杂word文档

1,214 阅读1分钟

基于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 模板

1692849193534.png

其中,«@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)...】:

1691477496215.png

«${tender3.intervalMap["T1"]}»为map对象使用 «${baseSituation.dataTimestamp!}»指定默认值为空,通过!(感叹号)号实现 也可指定默认值为其他的,如«${baseSituation.engagedIndustryField!'暂无»

2.在弹出的对话框中,类别选择“邮件合并”,域名选择 "MergeField",域属性中的域名填入模版表达式${legalName!},点击【确定】按钮;

1691477587700.png

常见语法

1、${....}

用于变量展示,也可以用作对象属性或者map值的展示,用法如下:
对象属性:${object.XXX}
map:${object["XXX"]}

2list

数组、列表的循环展示,一般写法

[#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