2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 使用freemarker引擎动态生成word文件

使用freemarker引擎动态生成word文件

时间:2024-02-12 10:32:40

相关推荐

使用freemarker引擎动态生成word文件

使用freemarker引擎动态生成word文件

0 前言1 工具与环境配置1.1 sublime1.2 依赖包1.3 word模版ftl文件生成步骤2 Word Xml基本语法介绍3 动态数据填充单元测试ftl模板4 动态表格生成单元测试ftl模板5 动态目录与动态标题结构单元测试ftl模板6 插入图片单元测试ftl模板

0 前言

本文使用freemarker模板引擎动态建立word文件,可以实现数据填充,文档结构和目录的变化,表格生成等功能,使用WPS,jdk版本1.8.0_141,maven版本3.1.1,freemarker版本2.3.23,idea版本Community Edition .1.1。

1 工具与环境配置

1.1 sublime

安装sublime,选择Preferences–>Package Control–>Install Package–>安装HTML/CSS/JS Prettify。

1.2 依赖包

以maven工程为例,新建项目,在pom.xml文件中引入freemarker、junit、lombok依赖

<dependency><groupId>freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.23</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.8</version></dependency>

1.3 word模版ftl文件生成步骤

freemarker使用专门的模板文件ftl(FreeMarker Template Language)格式,为了快速建立word模板文件,可以采用反编译的方式。

新建一个doc格式的word文档;另存为xml格式文件,注意并非word xml文件;修改后缀名为ftl;使用sublime打开和编辑,在空白处右键,HTML/CSS/JS Prettify–>Prettify Code可以格式化代码。

2 Word Xml基本语法介绍

ftl文件采用word xml格式的语法。以这种格式存储的文件可以通过其他软件的编译创建word文档,不需要用专门的文稿软件打开。一个简单ftl文件如下所示

<?xml version="1.0"?><w:wordDocument xmlns:w="/office/word//wordml"><w:body><w:p><w:r><w:t>tyler</w:t></w:r></w:p></w:body></w:wordDocument>

文档内容包含在<w:body>标签之间。<w:p><w:r><w:t>是三个基本标签。

<w:p>标签表示一个段落,段落属性用<w:pPr>来指定,一个段落中可以包含很多“执行段”<w:r>。在执行段中,包含文本、制表符、回车符等特殊符号。<w:rPr>可以指定该执行段的属性。<w:t>之间包含真实的文本。

参考资料officeopenxml

3 动态数据填充

很多时候,人们会制定一些模板,如会议通知等,仅在会议时间、地点处留出空白,这样下次使用的时候只需要填写时间、地点就可以快速生成一个会议通知。因此我们首先实现文档内数据内容的动态填充。新建maven工程,工程目录如下

建立word工具类WordUtil,按照路径读取已有的ftl模板

import freemarker.cache.FileTemplateLoader;import freemarker.cache.TemplateLoader;import freemarker.template.Configuration;import freemarker.template.Template;import java.io.*;import java.util.Map;import lombok.Getter;import lombok.Setter;@Getter@Setterpublic class WordUtil {private Configuration configure;public WordUtil() {configure = new Configuration(Configuration.VERSION_2_3_23);configure.setDefaultEncoding("utf-8");}public boolean createWord(Map<String, Object> dataMap, String inputFilePath, String outFilePath) {boolean flag = false;try {TemplateLoader templateLoader;templateLoader=new FileTemplateLoader(new File("./"));configure.setTemplateLoader(templateLoader);Template template=configure.getTemplate(inputFilePath,"UTF-8");Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(outFilePath)), "utf-8"), 10240);template.process(dataMap, out);out.close();flag = true;} catch (Exception e) {e.printStackTrace();}return flag;}}

建立Person模型

import lombok.Getter;import lombok.Setter;@Setter@Getterpublic class Person {String name;String age;String gender;public Person(String name, String age, String gender) {this.name = name;this.age = age;this.gender = gender;}}

单元测试

建立单元测试,调用WordUtil的createWord方法。其入参为存储待填充的数据的map、ftl的存储路径、生成文档的路径。文件名以时间戳命名,避免每次生成文件覆盖。

import com.tyler.freemarker.model.Person;import com.tyler.freemarker.WordUtil;import org.junit.Test;import java.text.SimpleDateFormat;import java.util.*;public class WordGenerateTest {@Testpublic void variableTest() {SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");Date date = new Date(System.currentTimeMillis());String outputFileName = formatter.format(date);String inputFilePath = "./src/main/resources/template.ftl";String outFilePath = "./src/main/resources/"+outputFileName+".doc";WordUtil wu = new WordUtil();Map<String, Object> map = new HashMap<>();Person person = new Person("Tyler", "18", "male");map.put("person", person);wu.createWord(map, inputFilePath, outFilePath);}}

ftl模板

ftl模板中留出了Person的属性的位置,可以通过读取map的数据填充进去。在freemarker中,${variable}可以获取变量variable的值,person是传进来Person类实例的一个key值,通过key值访问到这个实例。和Java一样,类的属性可以通过.操作符获取。这样就建立了Java类与ftl中数据的映射,实现了对同一个模板的复用,给定不同的数据可以生成很多相同格式的word文档。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><?mso-application progid="Word.Document"?><w:wordDocument xmlns:w="/office/word//wordml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:sl="/schemaLibrary//core" xmlns:aml="/aml/2001/core" xmlns:wx="/office/word//auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve"><w:body><w:p><w:r><w:t>姓名:${person.name}</w:t></w:r></w:p><w:p><w:r><w:t>年龄:${person.age}</w:t></w:r></w:p><w:p><w:r><w:t>性别:${person.gender}</w:t></w:r></w:p></w:body></w:wordDocument>

生成结果展示

4 动态表格生成

表格是数据展示的重要方式。在可以填充数据的基础上,可以将这些数据以表格的形式展示。比如用一个表格统计公司员工的基本信息,姓名、年龄、性别。只需要在map中存储一个List<Person>,再设计一个与之对应的表格并留出空白就好。

但是另一个公司也想用这套模板,但是两个公司的员工数量不同,因此需要修改表格的行数。接下来实现表格的动态生成,行数与List的尺寸对应。这就需要用到循环语句。

freemarker可以设定计数循环,如

<#list 1..5 as i><w:t>${i}</w:t></#list>

也可以直接循环List的内容

<#list personList as pl><w:t>${pl.name}</w:t></#list>

此处选择第二种,直接循环personList的元素。建立单元测试,生成一个List<Person>作为数据传输给ftl模板。

单元测试

import com.tyler.freemarker.model.Person;import com.tyler.freemarker.WordUtil;import org.junit.Test;import java.text.SimpleDateFormat;import java.util.*;public class WordGenerateTest {@Testpublic void tableTest() {SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");Date date = new Date(System.currentTimeMillis());String outputFileName = formatter.format(date);String inputFilePath = "./src/main/resources/template.ftl";String outFilePath = "./src/main/resources/"+outputFileName+".doc";WordUtil wu = new WordUtil();Map<String, Object> map = new HashMap<>();List<Person> personList = new ArrayList<>();personList.add(new Person("Tyler", "18", "male"));personList.add(new Person("Tom", "20", "male"));personList.add(new Person("Marry", "19", "female"));map.put("personList", personList);wu.createWord(map, inputFilePath, outFilePath);}}

ftl模板

freemarker中,表格内容在<w:tbl> </w:tbl>中间,此处的ftl模板包含了很多表格的属性设置,在应用过程中,可以按照想要的表格样式先建立一个带有空表格的word文档,再反编译成ftl模板,避免手动设置属性。这里只实现了动态的行数,列数同理。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><?mso-application progid="Word.Document"?><w:wordDocument xmlns:w="/office/word//wordml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:sl="/schemaLibrary//core" xmlns:aml="/aml/2001/core" xmlns:wx="/office/word//auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve"><w:body><w:tbl><w:tblPr><w:tblStyle w:val="a63" /><w:tblW w:w="9243" w:type="dxa" /><w:tblInd w:w="0" w:type="dxa" /><w:tblBorders><w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /><w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /><w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /><w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /><w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /><w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /></w:tblBorders><w:tblLayout w:type="Fixed" /><w:tblCellMar><w:top w:w="0" w:type="dxa" /><w:left w:w="108" w:type="dxa" /><w:bottom w:w="0" w:type="dxa" /><w:right w:w="108" w:type="dxa" /></w:tblCellMar></w:tblPr><w:tblGrid><w:gridCol w:w="3499" /><w:gridCol w:w="5744" /></w:tblGrid><!-->以下开始循环内容,list的每个元素为一行,总共三行<--><#list personList as pl><w:tr><w:tblPrEx><w:tblBorders><w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /><w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /><w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /><w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /><w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /><w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto" /></w:tblBorders><w:tblCellMar><w:top w:w="0" w:type="dxa" /><w:left w:w="108" w:type="dxa" /><w:bottom w:w="0" w:type="dxa" /><w:right w:w="108" w:type="dxa" /></w:tblCellMar></w:tblPrEx><w:trPr><w:trHeight w:val="361" w:h-rule="atLeast" /></w:trPr><w:tc><w:tcPr><w:tcW w:w="3499" w:type="dxa" /><w:shd w:val="clear" w:color="auto" w:fill="auto" /><w:noWrap w:val="0" /><w:vAlign w:val="center" /></w:tcPr><w:p><w:pPr><w:spacing w:before-lines="50" w:after-lines="50" w:line="240" w:line-rule="auto" /><w:jc w:val="left" /><w:rPr><w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:fareast="宋体" w:hint="default" /><w:color w:val="auto" /><w:sz-cs w:val="21" /></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:fareast="宋体" w:cs="宋体" w:hint="fareast" /><w:color w:val="auto" /><w:kern w:val="0" /><w:sz-cs w:val="21" /></w:rPr><w:t>${pl.name}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="5744" w:type="dxa" /><w:shd w:val="clear" w:color="auto" w:fill="auto" /><w:noWrap w:val="0" /><w:vAlign w:val="center" /></w:tcPr><w:p><w:pPr><w:spacing w:before-lines="50" w:after-lines="50" w:line="240" w:line-rule="auto" /><w:jc w:val="left" /><w:rPr><w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:fareast="宋体" w:hint="default" /><w:sz-cs w:val="21" /><w:lang w:val="EN-US" w:fareast="ZH-CN" /></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:fareast="宋体" w:hint="fareast" /><w:sz-cs w:val="21" /><w:lang w:val="EN-US" w:fareast="ZH-CN" /></w:rPr><w:t>${pl.age}</w:t></w:r></w:p></w:tc><w:tc><w:tcPr><w:tcW w:w="5744" w:type="dxa" /><w:shd w:val="clear" w:color="auto" w:fill="auto" /><w:noWrap w:val="0" /><w:vAlign w:val="center" /></w:tcPr><w:p><w:pPr><w:spacing w:before-lines="50" w:after-lines="50" w:line="240" w:line-rule="auto" /><w:jc w:val="left" /><w:rPr><w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:fareast="宋体" w:hint="default" /><w:sz-cs w:val="21" /><w:lang w:val="EN-US" w:fareast="ZH-CN" /></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:fareast="宋体" w:hint="fareast" /><w:sz-cs w:val="21" /><w:lang w:val="EN-US" w:fareast="ZH-CN" /></w:rPr><w:t>${pl.gender}</w:t></w:r></w:p></w:tc></w:tr></#list></w:tbl></w:body></w:wordDocument>

生成结果展示

5 动态目录与动态标题结构

使用循环结构,我们还可以建立动态的文档框架。一个文档的框架由一级标题、二级标题等确定。如果各级标题的数量和内容也由List控制,那么文档就可以实现动态结构。同理也可以实现动态的目录。

首先建立一个Company类做为一级标题,每个Company包含一个长度不等的List<Person>

import lombok.Getter;import lombok.Setter;import java.util.List;@Getter@Setterpublic class Company {String name;List<Person> personList;public Company(String name, List<Person> personList) {this.name = name;this.personList = personList;}}

单元测试

建立单元测试

import com.tyler.freemarker.FigureUtil;import com.tyler.freemarker.WordUtil;import com.tyler.pany;import com.tyler.freemarker.model.Person;import org.junit.Test;import java.text.SimpleDateFormat;import java.util.*;public class WordGenerateTest {@Testpublic void titleTest() {Random r = new Random();SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");Date date = new Date(System.currentTimeMillis());String outputFileName = formatter.format(date);String inputFilePath = "./src/main/resources/template.ftl";String outFilePath = "./src/main/resources/"+outputFileName+".doc";WordUtil wu = new WordUtil();Map<String, Object> map = new HashMap<>();List<Company> companyList = new ArrayList<>();for (int i = 0; i < r.nextInt(5)+2; i++) {List<Person> personList = new ArrayList<>();for (int j = 0; j <r.nextInt(4)+2 ; j++) {Person person = new Person("name"+r.nextInt(15), ""+r.nextInt(50), "male");personList.add(person);}Company company = new Company("company"+r.nextInt(13), personList);companyList.add(company);}map.put("companyList", companyList);wu.createWord(map, inputFilePath, outFilePath);}}

ftl模板

ftl模版文件,此处使用了嵌套的双层循环,外层循环一级标题,内层循环二级标题。目录与标题之间需要建立超链接,点击目录可以跳转正文标题。目录处<w:instrText> HYPERLINK \l ${cl.name} </w:instrText>是建立超链接,<w:instrText> PAGEREF ${cl.name} </w:instrText>是将超链接与页码关联。这两个地方的索引${cl.name}必须和标题的<aml:annotation aml:id="0" w:type="Word.Bookmark.Start" w:name="${cl.name}" />一致,才能建立超链接。因此为了避免索引冲突,这里选取名字作为索引值,也可以自行设定其他不会冲突的字符串,保证唯一性就可以。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><?mso-application progid="Word.Document"?><w:wordDocument xmlns:w="/office/word//wordml"xmlns:v="urn:schemas-microsoft-com:vml"xmlns:w10="urn:schemas-microsoft-com:office:word"xmlns:sl="/schemaLibrary//core"xmlns:aml="/aml/2001/core"xmlns:wx="/office/word//auxHint"xmlns:o="urn:schemas-microsoft-com:office:office"xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no"xml:space="preserve"><w:body><wx:sect><w:p><w:pPr><w:spacing w:before="0" w:before-lines="0" w:after="0" w:after-lines="0" w:line="240" w:line-rule="auto" /><w:ind w:left="0" w:left-chars="0" w:right="0" w:right-chars="0" w:first-line="0" w:first-line-chars="0" /><w:jc w:val="center" /></w:pPr><w:r><w:rPr><w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:fareast="宋体" w:hint="default" /><w:sz w:val="21" /></w:rPr><w:t>目录</w:t></w:r></w:p><#list companyList as cl><w:p><w:pPr><w:pStyle w:val="a4" /><w:tabs><w:tab w:val="right" w:leader="dot" w:pos="8306" /></w:tabs></w:pPr><w:r><w:fldChar w:fldCharType="begin" /></w:r><w:r><w:instrText>TOC \o &quot;1-3&quot; \h \u </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate" /></w:r><w:r><w:fldChar w:fldCharType="begin" /></w:r><w:r><w:instrText> HYPERLINK \l ${cl.name} </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate" /></w:r><w:r><w:rPr><w:rFonts w:hint="fareast" /><w:lang w:fareast="ZH-CN" /></w:rPr><w:t>${cl.name}</w:t></w:r><w:r><w:tab /></w:r><w:r><w:fldChar w:fldCharType="begin" /></w:r><w:r><w:instrText> PAGEREF ${cl.name} </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate" /></w:r><w:r><w:t>1</w:t></w:r><w:r><w:fldChar w:fldCharType="end" /></w:r><w:r><w:fldChar w:fldCharType="end" /></w:r></w:p><#list cl.getPersonList() as pl><w:p><w:pPr><w:pStyle w:val="a5" /><w:tabs><w:tab w:val="right" w:leader="dot" w:pos="8306" /></w:tabs></w:pPr><w:r><w:fldChar w:fldCharType="begin" /></w:r><w:r><w:instrText> HYPERLINK \l ${pl.name} </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate" /></w:r><w:r><w:rPr><w:rFonts w:hint="fareast" /><w:lang w:val="EN-US" w:fareast="ZH-CN" /></w:rPr><w:t>${pl.name}</w:t></w:r><w:r><w:tab /></w:r><w:r><w:fldChar w:fldCharType="begin" /></w:r><w:r><w:instrText> PAGEREF ${pl.name} </w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate" /></w:r><w:r><w:t>1</w:t></w:r><w:r><w:fldChar w:fldCharType="end" /></w:r><w:r><w:fldChar w:fldCharType="end" /></w:r></w:p></#list></#list><w:p><w:r><w:fldChar w:fldCharType="end" /></w:r></w:p><#list companyList as cl><w:p><w:pPr><w:pStyle w:val="2" /><w:rPr><w:rFonts w:hint="fareast" /><w:lang w:val="EN-US" w:fareast="ZH-CN" /></w:rPr></w:pPr><aml:annotation aml:id="0" w:type="Word.Bookmark.Start" w:name="${cl.name}" /><w:r><w:rPr><w:rFonts w:hint="fareast" /><w:lang w:fareast="ZH-CN" /><w:sz w:val="50" /></w:rPr><w:t>${cl.name}</w:t></w:r><aml:annotation aml:id="0" w:type="Word.Bookmark.End" /></w:p><#list cl.getPersonList() as pl><w:p><w:pPr><w:pStyle w:val="3" /><w:rPr><w:rFonts w:hint="fareast" /><w:lang w:val="EN-US" w:fareast="ZH-CN" /></w:rPr></w:pPr><aml:annotation aml:id="1" w:type="Word.Bookmark.Start" w:name="${pl.name}" /><w:r><w:rPr><w:rFonts w:hint="fareast" /><w:lang w:val="EN-US" w:fareast="ZH-CN" /><w:sz w:val="30" /></w:rPr><w:t>${pl.name}</w:t></w:r><aml:annotation aml:id="1" w:type="Word.Bookmark.End" /></w:p></#list></#list><w:sectPr><w:pgSz w:w="11906" w:h="16838" /><w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0" /><w:cols w:space="720" /><w:docGrid w:type="lines" w:line-pitch="312" /></w:sectPr></wx:sect></w:body></w:wordDocument>

生成结果展示

注:上述生成的文件中,暂时无法做到更新页码,只能手动打开word文件,右键–>更新域–>更新整个目录。

目录更新的实现思路可以参考:代码操作Word时,目录自动更新的两种方法

6 插入图片

插入word的图片要转码成base64码,才能写入ftl文件中,因此先建立转码处理的接口。生成的base64码以字符串形式存储。

import java.util.Base64;import java.util.Base64.Encoder;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;public class FigureUtil {public static String getImageStr(String imgFilePath) {InputStream in = null;byte[] data = null;try {in = new FileInputStream(imgFilePath);int avai = in.available();data = new byte[avai];in.read(data);in.close();} catch (Exception e) {e.printStackTrace();}finally {if(in !=null){try{in.close();} catch(IOException e) {e.printStackTrace();}}}Encoder encoder = Base64.getEncoder();;return encoder.encodeToString(data);}}

单元测试

建立单元测试

import com.tyler.freemarker.FigureUtil;import com.tyler.freemarker.WordUtil;import org.junit.Test;import java.text.SimpleDateFormat;import java.util.*;public class WordGenerateTest {@Testpublic void figureTest() {String imgFilePath = "./src/main/resources/1.jpg";SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");Date date = new Date(System.currentTimeMillis());String outputFileName = formatter.format(date);String inputFilePath = "./src/main/resources/template.ftl";String outFilePath = "./src/main/resources/"+outputFileName+".doc";WordUtil wu = new WordUtil();Map<String, Object> map = new HashMap<>();String img = FigureUtil.getImageStr(imgFilePath);map.put("img", img);wu.createWord(map, inputFilePath, outFilePath);}}

ftl模板

ftl模版文件,base64码非常长,这里使用img来代替base64码字符串

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><?mso-application progid="Word.Document"?><w:wordDocument xmlns:w="/office/word//wordml"xmlns:v="urn:schemas-microsoft-com:vml"xmlns:w10="urn:schemas-microsoft-com:office:word"xmlns:sl="/schemaLibrary//core"xmlns:aml="/aml/2001/core"xmlns:wx="/office/word//auxHint"xmlns:o="urn:schemas-microsoft-com:office:office"xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"w:macrosPresent="no" w:embeddedObjPresent="no"w:ocxPresent="no" xml:space="preserve"><w:body><wx:sect><w:p><w:pPr><w:rPr><w:rFonts w:hint="default" /><w:lang w:val="EN-US" w:fareast="ZH-CN" /></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:hint="default" /><w:lang w:val="EN-US" w:fareast="ZH-CN" /></w:rPr><w:pict><w:binData w:name="wordml://1.png">${img}</w:binData><v:shape id="_x0000_s1026" o:spt="75" alt="1" type="#_x0000_t75"style="height:140.9pt;width:211.35pt;" filled="f"o:preferrelative="t" stroked="f" coordsize="21600,21600"><v:path /><v:fill on="f" focussize="0,0" /><v:stroke on="f" /><v:imagedata src="wordml://1.png" o:title="1" /><o:lock v:ext="edit" aspectratio="t" /><w10:wrap type="none" /><w10:anchorlock /></v:shape></w:pict></w:r></w:p><w:sectPr><w:pgSz w:w="11906" w:h="16838" /><w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0" /><w:cols w:space="720" /><w:docGrid w:type="lines" w:line-pitch="312" /></w:sectPr></wx:sect></w:body></w:wordDocument>

生成结果展示

建议预先生成模版的时候随便插入一个图片占位,并设置好格式和位置。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。