站点图标 AI技术聚合

java利用模板导出word文档

一.通过XDocReportFreeMarker模板引擎生成Word文档的方法。

1.依赖:

</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>

二.数据类型

1.普通数据

2.表格

三.实现

3.1编辑模板:选中区域,按ctrl+F9,右键编辑域,选择邮件合并,输入参数

参数后面加“!”可以避免参数为null而报错,

 3.2.代码: 

//获取Word模板,模板存放路径在项目的resources目录下
InputStream ins = this.getClass().getResourceAsStream("/RE22-08.docx");
//注册xdocreport实例并加载FreeMarker模板引擎
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(ins,TemplateEngineKind.Freemarker);
//创建xdocreport上下文对象
IContext context = report.createContext();
//往模板里填充数据(普通数据)
context.put("projectFile",itemPlanVo.getNumber());
context.put("projectName",itemPlanVo.getProjectName());
context.put("startTime",Handler.dateToString1(itemPlanVo.getStartTime()));
context.put("endTime",Handler.dateToString1(itemPlanVo.getEndTime()));
context.put("sumDay",itemPlanVo.getSumDay());
context.put("step1StartTime",Handler.dateToString2(itemPlanVo.getStep1StartTime()));
context.put("step1EndTime",Handler.dateToString2(itemPlanVo.getStep1EndTime()));
context.put("step2StartTime",Handler.dateToString2(itemPlanVo.getStep2StartTime()));
context.put("step2EndTime",Handler.dateToString2(itemPlanVo.getStep2EndTime()));
context.put("step3StartTime",Handler.dateToString2(itemPlanVo.getStep3StartTime()));
context.put("step3EndTime",Handler.dateToString2(itemPlanVo.getStep3EndTime()));
context.put("step4StartTime",Handler.dateToString2(itemPlanVo.getStep4StartTime()));
context.put("step4EndTime",Handler.dateToString2(itemPlanVo.getStep4EndTime()));
context.put("step5StartTime",Handler.dateToString2(itemPlanVo.getStep5StartTime()));
context.put("step5EndTime",Handler.dateToString2(itemPlanVo.getStep5EndTime()));
context.put("step6StartTime",Handler.dateToString2(itemPlanVo.getStep6StartTime()));
context.put("step6EndTime",Handler.dateToString2(itemPlanVo.getStep6EndTime()));
context.put("step7StartTime",Handler.dateToString2(itemPlanVo.getStep7StartTime()));
context.put("step7EndTime",Handler.dateToString2(itemPlanVo.getStep7EndTime()));
context.put("step8StartTime",Handler.dateToString2(itemPlanVo.getStep8StartTime()));
context.put("step8EndTime",Handler.dateToString2(itemPlanVo.getStep8EndTime()));
context.put("step9StartTime",Handler.dateToString2(itemPlanVo.getStep9StartTime()));
context.put("step9EndTime",Handler.dateToString2(itemPlanVo.getStep9EndTime()));
context.put("step10StartTime",Handler.dateToString2(itemPlanVo.getStep10StartTime()));
context.put("step10EndTime",Handler.dateToString2(itemPlanVo.getStep10EndTime()));
context.put("step11StartTime",Handler.dateToString2(itemPlanVo.getStep11StartTime()));
context.put("step11EndTime",Handler.dateToString2(itemPlanVo.getStep11EndTime()));
context.put("step12StartTime",Handler.dateToString2(itemPlanVo.getStep12StartTime()));
context.put("step12EndTime",Handler.dateToString2(itemPlanVo.getStep12EndTime()));
context.put("step13StartTime",Handler.dateToString2(itemPlanVo.getStep13StartTime()));
context.put("step13EndTime",Handler.dateToString2(itemPlanVo.getStep13EndTime()));
context.put("step1Hour",itemPlanVo.getStep1Hour());
context.put("step2Hour",itemPlanVo.getStep2Hour());
context.put("step3Hour",itemPlanVo.getStep3Hour());
context.put("step4Hour",itemPlanVo.getStep4Hour());
context.put("step5Hour",itemPlanVo.getStep5Hour());
context.put("step6Hour",itemPlanVo.getStep6Hour());
context.put("step7Hour",itemPlanVo.getStep7Hour());
context.put("step8Hour",itemPlanVo.getStep8Hour());
context.put("step9Hour",itemPlanVo.getStep9Hour());
context.put("step10Hour",itemPlanVo.getStep10Hour());
context.put("step11Hour",itemPlanVo.getStep11Hour());
context.put("step12Hour",itemPlanVo.getStep12Hour());
context.put("step13Hour",itemPlanVo.getStep13Hour());
context.put("sumHour1",itemPlanVo.getSumHour1());
context.put("sumHour",itemPlanVo.getSumHour());
往模板里填充数据(表格)
int j = 0;
List<ProjectTestItemsRelationEntity> projectTestItemsRelationEntities = projectTestItemsRelationRepository.findAllByFileNumber(fileNumber);
ArrayList<TestItemDocx> testItemDocxes = new ArrayList<>();
for (ProjectTestItemsRelationEntity entity : projectTestItemsRelationEntities) {
    TestItemDocx testItemDocx = new TestItemDocx();
    BeanUtils.copyProperties(entity,testItemDocx);
    testItemDocx.setIndex(++j);
    testItemDocxes.add(testItemDocx);
}
context.put("testItemDocx", testItemDocxes);

FieldsMetadata fm = report.createFieldsMetadata();
//Word模板中的表格数据对应的集合类型
fm.load("roleAndDutyDocx", RoleAndDutyDocx.class,true);
fm.load("testItemDocx", TestItemDocx.class, true);
fm.load("hardWareDocx", HardWareDocx.class, true);
fm.load("softWareDocx", SoftWareDocx.class, true);

//输出到本地目录
FileOutputStream out = new FileOutputStream(new File("D:\\Desktop\\RE22-08 测试实施方案.docx"));
report.process(context, out);

3.3展示

四.freemaker不同数据类型取值方法

1.数据类型

布尔型:等价于java的Boolean类型,不同的是不能直接输出,可转化为字符串输出

日期型:等价于java的Date类型,不同的是不能直接输出,需要转换为字符串再输出

数值型:等价于java中int,float,double等数值类型   (有三种显示形式:数值型(默认)、货币型、百分比型)

字符型:等价于java中的字符串,有很多内置函数

sequence类型:等价于java中的数组,list,set等集合类型

hash类型:等价于java中的Map类型

2.取值

1.布尔类型

在freeMarker页面中不能直接输出,如果要输出需要转换成字符串

方式一:?c
方式二:?string 或 ?string(‘为true时显示的内容’,’为false时显示的内容’)
方式三:?then(‘为true时显示的内容’,’为false时显示的内容’)
–>

Boolean flage = true
${flag?c}
${flag?string}
${flag?string(‘yes’,’no’)}
${flag?string(‘喜欢’,’不喜欢’)}
${flag?then(‘yes’,’no’)}
${flag?then(‘喜欢’,’不喜欢’)}

2.日期类型

在freemarker中日期类型不能直接输出:如果输出要先转成日期型或字符串
1.年月日   ?date
2.时分秒   ?time
3.年月日时分秒 ?datetime
4.指定格式   ?string (”自定义格式”)
y: 年 M:月 d:日
H: 时 m:分 s:秒
–>
<#– 输出日期格式 –>
    ${createDate?date}
<#– 输出时间格式 –>
    ${createDate?time}
<#– 输出日期时间格式 –>
    ${createDate?datetime} 
<#– 输出格式化日期格式 –>
    ${createDate?string(“yyyy年MM月dd日 HH:mm:ss”)}

3.数值类型

在freemarker中数值类型可以直接输出;
1.转字符串
普通字符串   ?c
货币型字符串  ?string.currency
百分比型字符串 ?string.percent
2.保留浮点型数值指定小数位(#表示一个小数位)
?string[“0.##”
–>
<#– 直接输出数值型 –>
${age} 
${salary} 
${avg} 
<#– 将数值转换成字符串类型 –>
${salary?c} 
<#– 将数值转化成货币类型字符串 –>
${salary?string.currency}
<#– 将数值转化成百分比类型的字符串 –>
${avg?string.percent}
<#– 将浮点型的数值转换成指定小数位输出(四舍五入) –>
${avg?string[“0.##”]} 

4.字符串类型

 在freemarker中字符串类型可以直接输出:
        1.截取字符串(左闭右开)?substring(start,end)
        2.首字母小写输出 ?uncap_first
        3.首字母大写输出 ?cap_first
        4.字母转小写输出 ?lower_case
        5.字母转大写输出 ?upper_case
        6.获取字符串长度 ?length
        7.是否以指定字符开头(boolean 类型) ?starts_with(“xx”)?string
        8.是否以指定字符结尾(boolean 类型) ?ends_with(“xx”)?string
        9.获取指定字符的索引 ?index_of(“xx”)
        10.去除字符串前后空格 ?trim
        11.替换指定字符串 ?replace(“xx”,”xx”)
–>
${msg} — ${msg2} 
${msg?string} — ${msg2?string} 
<#–1.截取字符串(左闭右开)?substring(start,end)–>
${msg?substring(0,2)}
<#–2.首字母小写输出 ?uncap_first–>
${msg?uncap_first}
<#–3.首字母大写输出 ?cap_first–>
${msg?cap_first}
<#–4.字母转小写输出 ?lower_case–>
${msg?lower_case}
<#–5.字母转大写输出 ?upper_case–>
${msg2?upper_case}
<#–6.获取字符串长度 ?length–>
${msg?length}<
<#–7.是否以指定字符开头(boolean 类型) ?starts_with(“xx”)?string–>
${msg?starts_with(“a”)?string}
<#–8.是否以指定字符结尾(boolean 类型) ?ends_with(“xx”)?string–>
${msg?ends_with(“o”)?string}
<#–9.获取指定字符的索引 ?index_of(“xx”)–>
${msg2?index_of(“m”)}
<#–10.去除字符串前后空格 ?trim–>
${msg2?trim}
<#–11.替换指定字符串 ?replace(“xx”,”xx”)–>
${msg?replace(“he”,”we”)}

5.空值类型

<#–
字符串空值情况处理:
        FreeMarker的变量必须赋值,否则就会抛出异常。而对于FreeMarker来说,null值和不存在的变量是完全一样的,因为FreeMarker无法理解null值。
        FreeMarker提供两个运算符来避免空值:
①!:指定缺失变量的默认值
    ${value!}:如果value值为空,则默认值是空字符串
    ${value!”默认值”}:如果value值为空,则默认值是字符串“默认值”
②??:判断变量是否存在
    如果变量存在,返回true,否则返回false
    ${(value??)?string}
–>
<#– 如果值不存在,直接输出会报错 –>
<#– ${bb}–>
<#– 值为null的数据 –>
<#–${str1}<br/>–>
<#– 值为空字符串的数据 –>
${str2}<br/>
<#– 使用!,当值不存在时,默认显示空字符串 –>
${str!}<br/>
<#– 使用!”xx”,当值不存在时,默认显示指定字符串 –>
${str!”这是一个默认值”}<br/>
<#– 使用??,判断字符串是否为空;返回布尔类型,如果想要输出,需要将布尔类型转换成字符串–>
${(str??)?string}

6.sequence类型

<#–
    FreeMarker 数据类型
        序列类型 (数组、List、Set)
        通过list指令输出序列
        <#list 序列名 as 元素名>
            ${元素名}
        </#list>

        获取序列的长度        ${序列名?size}
        获取序列元素的下标     ${元素名?index}
        获取第一个元素        ${序列名?first}
        获取最后一个元素       ${序列名?last}
        倒序输出    序列名?reverse
        升序输出    序列名?sort
        降序输出    序列名?sort?reverse
        指定字段名排序   序列名?sort_by(“字段名”)
    注:一般是JavaBean集合,对应的字段名需要提供get方法
–>
<#– 数组操作 –>
<#list stars as star>
    下标:${star?index}-姓名:${star}<br/>
</#list>
获取序列的长度:  ${stars?size}<br/>
获取第一个元素:   ${stars?first}<br/>
获取最后一个元素:  ${stars?last}<br/>

<#– List操作 –>
<#list cityList as city>
    ${city}-
</#list>
<br/>
<#–倒序输出    序列名?reverse–>
<#list cityList?reverse as city>
    ${city}-
</#list>
<br/>
<#–升序输出    序列名?sort–>
<#list cityList?sort as city>
    ${city}-
</#list>
<br/>
<#–降序输出    序列名?sort?reverse–>
<#list cityList?sort?reverse as city>
    ${city}-
</#list>
<br/>
<#list userList as user>
    编号:${user.id} 姓名:${user.username} ${user.age}<br/>
</#list>
<#–指定字段名排序   序列名?sort_by(“字段名”)–>
<#list userList?sort_by(“age”) as user>
    编号:${user.id} 姓名:${user.username} ${user.age}<br/>
</#list>

7.hash类型

<#–
    数据类型:hash类型
        key遍历输出
            <#list hash?keys as key>
                ${key} — ${hash[key]}
            </#list>
         value遍历输出
            <#list hash?values as value>
                ${value}
            </#list>
–>
<#– key遍历输出 –>
<#list cityMap?keys as key>
    ${key} — ${cityMap[key]} <br/>
</#list>
 
<#–value遍历输出–>
<#list cityMap?values as value>
    ${value}<br/>
</#list>

 参考:Java导出Word文档的几种方法_Archie_java的博客-CSDN博客

Freemarker简单概述及其数据类型的简单学习—快速入门(一)_freemark 判断日期类型_@夜魅的博客-CSDN博客

版权声明:本文为博主作者:lyt5701原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/qq_41786090/article/details/132317719

退出移动版