版权声明:本文为HaiyuKing原创文章,转载请注明出处!html
这个方案只能在java中运行,没法在Android项目中运行。因此此方案是:APP将表单数据发送给后台,后台经过freemarker将表单数据根据模板ftl文件生成Word文件,而后返回给APP,由APP进行展示。java
官网下载地址:https://freemarker.apache.org/freemarkerdownload.html数据库
后续将freemarker.jar文件添加到项目中。apache
注意:服务器
例子:编辑器
对于Word2016,另存为后会自动打开xml文件,因此须要先关闭xml文件,而后再使用FirstObject XML Editor软件打开xml文件!ide
下载FirstObject XML Editor软件(免安装版):下载地址:http://www.firstobject.com/dn_editor.htm测试
官网下载的软件打开文件的时候可能会出现崩溃的问题。建议使用foxe_CHS.exe软件进行编辑。下载地址见项目Demo下载地址。this
首先进行“缩进排版”编码
查找真实数据,替换成FreeMarker标记,其实就是Map<String, Object>中key,如${writeDate},对应Map的key值就是writeDate。
替换成:
对于文本按照上面的方式进行替换,而对于图片须要这样替换:
图片是以base64编码存在的,且这些编码放在<w:binData>标签之中。将这些base64编码使用占位符代替,而后java代码中将图片生成base64编码,传入值就能正常显示了。
替换成
注意:必定不要用word打开ftl模板文件查看,不然xml内容会发生变化,致使前面的工做白作了;可使用EditPlus打开查看。
package com.why.main; import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.util.HashMap; import java.util.Map; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import sun.misc.BASE64Encoder; /** * 生成Doc文档 */ public class DocumentHandler { //测试 public static void main(String[] args) { DocumentHandler documentHandler = new DocumentHandler(); documentHandler.createDoc(); } // 配置实例:只须要一个实例(单例模式) private Configuration configuration = null; private String tempDirPath = "D:/temp"; public DocumentHandler() { // 经过Freemaker的Configuration读取相应的ftl configuration = new Configuration(Configuration.VERSION_2_3_28); configuration.setDefaultEncoding("UTF-8");// 设置默认编码方式 } /** * 生成DOC文档 */ public void createDoc() { // 要填入模本的数据文件 Map<String,Object> dataMap = new HashMap<String,Object>(); getData(dataMap); // 设置模本装置方法和路径,FreeMarker支持多种模板装载方法。能够重servlet,classpath,数据库装载, // 若是模板是放在程序代码的包下面 //configuration.setClassForTemplateLoading(this.getClass(),"../"); //若是放到服务器目录中,则使用下面的代码 try { configuration.setDirectoryForTemplateLoading(new File(tempDirPath)); } catch (IOException e2) { e2.printStackTrace(); } //这里要设置取消使用Local语言环境 configuration.setLocalizedLookup(false); Template template = null; try { // leaveTemplet.ftl为要装载的模板 template = configuration.getTemplate("leaveTemplet.ftl","UTF-8"); } catch (IOException e) { e.printStackTrace(); } // 输出文档路径及名称 File dir = new File(tempDirPath); File outFile = new File(tempDirPath + "/请假条.doc"); if (!dir.isDirectory()) { dir.mkdir(); if (!outFile.exists()) { try { outFile.createNewFile(); } catch (IOException e) { System.out.println("建立文件失败"); e.printStackTrace(); } } } Writer out = null; try { try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } catch (FileNotFoundException e1) { System.out.println("输出文件失败"); e1.printStackTrace(); } try { template.process(dataMap, out); System.out.println("it's success!"); } catch (TemplateException e) { System.out.println("生成失败"); e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 注意dataMap里存放的数据Key值要与模板中的参数相对应 */ private void getData(Map<String,Object> dataMap) { String imgBase64Str = getImageStr(tempDirPath + "/leaderopinion_img.png"); // 使用String的有参构造方法 dataMap.put("writeDate","2018年10月13日");//填写日期 dataMap.put("name","HaiyuKing");//姓名 dataMap.put("dept","移动组");//部门 dataMap.put("leaveType","☑倒休 √年假 ✔事假 ☐病假 ☐婚假 ☐产假 ☐其余");//请假类型 dataMap.put("leaveReason","倒休休息两天");//请假理由 dataMap.put("leaveStartDate","2018年10月13日上午");//请假开始日期 dataMap.put("leaveEndDate","2018年10月14日下午");//请假结束日期 dataMap.put("leaveDay","2");//请假天数 dataMap.put("leaveLeader","赞成");//直属领导意见 dataMap.put("leaveDeptLeaderImg",imgBase64Str);//部门领导意见 } /** * 获取图片的base64值*/ private String getImageStr(String imgFile) { InputStream in = null; byte[] data = null; try { in = new FileInputStream(imgFile); data = new byte[in.available()]; in.read(data); in.close(); } catch (IOException e) { e.printStackTrace(); } BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(data); } }
注意:Map数据中的key值,对应ftl文件中的${xxxx}这里面的xxxx值。
一、不要使用英文;
二、若是想要保证一个总体,不要将中文、数字、标点符号一块儿使用(这里指占位区域);
三、日期想要做为一个总体,不要数字+中文输入,而是经过Enter键输入;
下面记录的是不一样输入的效果(使用FirstObject XML Editor软件打开xml文件)
使用英文:
使用数字:
使用中文:
日期采用数字+中文:
日期采用Enter键输入:
中文+标点符号:
沫沫金:使用Java模版引擎FreeMarker生成复杂的Word文档
FreeMaker解析Word模板(含图片)生成Word文档
连接:https://pan.baidu.com/s/19aPNIYWXt5GMN_KDQjFCRA 提取码:eo0n