freemark导出word的文档

相关的工具类:工具类

1、引入freemark依赖:

<!-- freemaker引擎 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

2、拿到word文档之后,先将需要变更的地方用占位符代替,如下:

freemaker文件名乱码 freemarker导出word打不开_数据

3、将文档另存为,xml格式的

freemaker文件名乱码 freemarker导出word打不开_java_02

4、在项目中resource下,建立template文件夹,放入xml文件,并且把后缀改成ftl

freemaker文件名乱码 freemarker导出word打不开_word_03

5、打开生成好的ftl文件,这个时候会发现生成的格式有问题,如下

freemaker文件名乱码 freemarker导出word打不开_xml_04


这个时候需要删掉多余的部分,改成如下:注意格式不要误删了!

freemaker文件名乱码 freemarker导出word打不开_java_05

需要了解一下,freemark中,word.xml的标签

<w:p> <!--表示一个段落-->
<w:val > <!--表示一个值-->
<w:r> <!--表示一个样式串,指明它包括的文本的显示样式,表示一个特定的文本格式-->
<w:t> <!--表示真正的文本内容-->
<w:rPr> <!--是<w:r>标签内的标签,对Run文本属性进行修饰-->
<w:pPr> <!--是<w:p>标签内的标签,对Paragraph文本属性进行修饰-->
<w:rFronts> <!--字体-->
<w:drawing > <!--图片-->
<wp:extent> <!--绘图对象大小-->
<wp:effectExtent > <!--嵌入图形的效果-->

6、了解freemark标签语法

http://www.51gjie.com/javaweb/1093.html

freemaker文件名乱码 freemarker导出word打不开_freemaker文件名乱码_06

7、替换模版中的数据,如图: 这种写法跟前端相似,拿到数据,进行循环遍历,以下是职责任务的遍历,list中嵌套list

freemaker文件名乱码 freemarker导出word打不开_freemaker文件名乱码_07

8、图片的问题

  • id不要大于1000,会变成1,000,然后就打不开了
    首先要将手册所有的动态图片,放进一个list中
    图片要求:
1、图片名字:image开头,如image1.png,后面要加后缀
2、还需要返回图片类型,有如下类型:image/png,image/jpeg,image/gif,image/jpeg,image/webp
3、 id必须唯一
4、 value值(图片值)必修是base64

freemaker文件名乱码 freemarker导出word打不开_word_08

5、开始修改模版数据,先把所有图片添加进资源里面,循环list

binaryData :图片的base64格式数据包

```groovy
<#if imageList??>
    <#list imageList as image>
        <pkg:part pkg:name="/word/media/${image.name}" pkg:contentType="${image.type}" pkg:compression="store">
            <pkg:binaryData>
                ${image.value}
            </pkg:binaryData>
        </pkg:part>
    </#list>
</#if>

图片的源定义,创建关联:

Relationship:图片展示位置与数据包的关联

放在如图红线位置里面:通过图片名字与图片数据资源进行绑定

freemaker文件名乱码 freemarker导出word打不开_freemaker文件名乱码_09

如下图:所有图片定义好了,展示图片时只需要通过id就可以绑定图片资源了

freemaker文件名乱码 freemarker导出word打不开_freemaker文件名乱码_10

展示图片:需要注意的地方,id前面要加rId

freemaker文件名乱码 freemarker导出word打不开_java_11

下面是展示图片的代码:

<w:drawing>
    <wp:inline distT="0" distB="0"
               distL="0"
               distR="0"
               wp14:anchorId="4E968DF3"
               wp14:editId="00D0897C">
        <#--  <wp:extent cx="624840" cy="509676"/>-->
        <wp:extent cx="1249680"
                   cy="1019352"/>

        <wp:effectExtent l="0" t="0"
                         r="0"
                         b="0"/>
        <wp:docPr id="3"
                  name="图片 3"/>
        <wp:cNvGraphicFramePr>
            <a:graphicFrameLocks
                    xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
                    noChangeAspect="1"/>
        </wp:cNvGraphicFramePr>
        <a:graphic
                xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
            <a:graphicData
                    uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
                <pic:pic
                        xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
                    <pic:nvPicPr>
                        <pic:cNvPr
                                id="1"
                                name="图片 1"/>
                        <pic:cNvPicPr/>
                    </pic:nvPicPr>
                    <pic:blipFill>
                        <a:blip r:embed="rId${image.id}"
                                cstate="print">
                            <a:extLst>
                                <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
                                    <a14:useLocalDpi
                                            xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main"
                                            val="0"/>
                                </a:ext>
                            </a:extLst>
                        </a:blip>
                        <a:stretch>
                            <a:fillRect/>
                        </a:stretch>
                    </pic:blipFill>
                    <pic:spPr>
                        <a:xfrm>
                            <a:off x="0"
                                   y="0"/>
                            <a:ext cx="1617272"
                                   cy="1319192"/>
                            <#--<a:ext cx="808636" cy="659596"/>-->
                        </a:xfrm>
                        <a:prstGeom
                                prst="rect">
                            <a:avLst/>
                        </a:prstGeom>
                    </pic:spPr>
                </pic:pic>
            </a:graphicData>
        </a:graphic>
    </wp:inline>
</w:drawing>
6、图片变形问题

导致图片变形,压缩或者拉伸。下面看一下图片位置里面代码有两个核心的地方:

<wp:extent cx="1249680" cy="1019352"/>
<a:ext cx="1617272" cy="1319192"/>

这里我采用固定图片的格式:

freemaker文件名乱码 freemarker导出word打不开_word_12

9、动态模版(动态表格)

首先,取到步骤模版的表头,组成一个list,做成动态表头:

freemaker文件名乱码 freemarker导出word打不开_java_13

将数据内容组装成List结构循环:

freemaker文件名乱码 freemarker导出word打不开_word_14

这个时候,拿到模版的数据,要判断一下,如果是模版一和模版二,是有图片,这个时候要插入图片数据,判断如果是第三列数据,就换成图片格式,if,else判断

freemaker文件名乱码 freemarker导出word打不开_java_15

10、分页问题

判断如果是第一页(首页)不需要分页,其他需要分页,红色标注为分页标签

freemaker文件名乱码 freemarker导出word打不开_word_16

11、创建目录

目录有一部分是固定数据,一部分是动态数据,职责任务和阶段性绩效评估表是动态数据,动态加,其他保留之前格式。

freemaker文件名乱码 freemarker导出word打不开_word_17

12、合并单元格

根据list索引判断,如果第一个开始合并,<w:vMerge w:val=“restart”/>,否则 合并结束

<w:vMerge/>
<#if (task_index??) &&(task_index==0)>
    <w:vMerge w:val="restart"/>
<#else>
    <w:vMerge/>
</#if>

13、换行、空格

换行:<w:br />
空格: 

14、表格渲染

动态表头和数据,<w:tbl>标签 tr为行,tc为列

freemaker文件名乱码 freemarker导出word打不开_数据_18

15、创建freemark工具类

需要传递的参数有:模版名称,文档名称,相关数据map,HttpServletResponse等参数

freemaker文件名乱码 freemarker导出word打不开_word_19

自动装配

freemaker文件名乱码 freemarker导出word打不开_freemaker文件名乱码_20

获取装配的模版:

freemaker文件名乱码 freemarker导出word打不开_word_21

输出文档路径及名称 ,以临时文件的形式

freemaker文件名乱码 freemarker导出word打不开_xml_22

导出文件,返回前端

freemaker文件名乱码 freemarker导出word打不开_java_23

需要整体注意的是,改一个地方就要运行生成看看,不然到后面很难发现问题,因为freemark对格式要求很严格,多符号,少符号,word就打不开,改的时候本地留备份!

参考网址:
https://blog.51cto.com/kaigejava/4851882?b=totalstatistic