FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言
这个方案只能在java中运行,无法在Android项目中运行。所以此方案是:APP将表单数据发送给后台,后台通过freemarker将表单数据根据模板ftl文件生成Word文件,然后返回给APP,由APP进行展现。
前期准备
1、下载freemarker.jar文件
官网下载地址:https://freemarker.apache.org/freemarkerdownload.html


后续将freemarker.jar文件添加到项目中。
2、制作模板ftl文件
(1)先用office2003或更高版本word软件编辑好word模版文件【版本要2003以上,2003以下的不支持另存为xml格式功能】
注意:
- 在word模板中写入相对真实的数据【注意,不要使用英文,尽量使用中文、数字,见附录1】;
- 对于对勾样式的数据,在word模板文件中统一用安卓代替(后续需要通过java代码传入带有对勾样式的数据);
- 需要设置图片的话,需要在word模板文件中放入真实的图片占位;请尽量选择小于50K的图片,并且把图片的大小和位置调整好。选择小图片的原因是避免xml文件过大导致打开时缓慢甚至卡死。

例子:

(2)另存为Word 2003 XML文档


对于Word2016,另存为后会自动打开xml文件,所以需要先关闭xml文件,然后再使用FirstObject XML Editor软件打开xml文件!

(3)下载FirstObject XML Editor软件
下载FirstObject XML Editor软件(免安装版):下载地址:http://www.firstobject.com/dn_editor.htm

官网下载的软件打开文件的时候可能会出现崩溃的问题。建议使用foxe_CHS.exe软件进行编辑。下载地址见项目Demo下载地址。
(4)使用FirstObject XML Editor软件将xml打开,将真实数据换成FreeMarker标记
首先进行“缩进排版”

查找真实数据,替换成FreeMarker标记,其实就是Map<String, Object>中key,如${writeDate},对应Map的key值就是writeDate。

替换成:

对于文本按照上面的方式进行替换,而对于图片需要这样替换:
图片是以base64编码存在的,且这些编码放在<w:binData>标签之中。将这些base64编码使用占位符代替,然后java代码中将图片生成base64编码,传入值就能正常显示了。

替换成

(5)然后保存,直接将文件后缀修改为.ftl(FreeMarker模板)

注意:一定不要用word打开ftl模板文件查看,否则xml内容会发生变化,导致前面的工作白做了;可以使用EditPlus打开查看。
使用步骤
一、项目组织结构图

二、导入步骤
1、在项目中引入freemarker.jar

2、将制作的模板文件leaveTemplet.ftl和图片资源复制到D:/temp目录下

3、将DocumentHandler.java文件复制到项目中
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);
}
}
DocumentHandler.java
注意:Map数据中的key值,对应ftl文件中的${xxxx}这里面的xxxx值。

4、运行


5、效果


附录
1、Word模板中输入真实数据的技巧
1、不要使用英文;
2、如果想要保证一个整体,不要将中文、数字、标点符号一起使用(这里指占位区域);
3、日期想要作为一个整体,不要数字+中文输入,而是通过Enter键输入;

下面记录的是不同输入的效果(使用FirstObject XML Editor软件打开xml文件)
使用英文:

使用数字:

使用中文:

日期采用数字+中文:

日期采用Enter键输入:

中文+标点符号:

参考资料
沫沫金:使用Java模版引擎FreeMarker生成复杂的Word文档
FreeMaker解析Word模板(含图片)生成Word文档
项目demo下载地址
链接:https://pan.baidu.com/s/19aPNIYWXt5GMN_KDQjFCRA 提取码:eo0n
FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】的更多相关文章
- Android根据word模板文档将表单数据生成word文档的方案整理
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 尝试的方案包括以下几种: freemarker 只能在java项目上运行,无法在Android项目上运行: 参考资料:<Fre ...
- PoiDocxDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0),目前只能java生成】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个是<PoiDemo[Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)]>的扩展,上一篇是根 ...
- PoiDemo【Android将表单数据生成Word文档的方案之二(基于Poi4.0.0)】
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 使用Poi实现android中根据模板文件生成Word文档的功能.这里的模板文件是doc文件.如果模板文件是docx文件的话,请阅读 ...
- Java 导出数据库表信息生成Word文档
一.前言 最近看见朋友写了一个导出数据库生成word文档的业务,感觉很有意思,研究了一下,这里也拿出来与大家分享一波~ 先来看看生成的word文档效果吧 下面我们也来一起简单的实现吧 二.Java 导 ...
- 使用freemarker模板引擎生成word文档的开发步骤
1.准备模板文档,如果word文档中有表格,只保留表头和第一行数据:2.定义变量,将word文档中的变量用${var_name}替换:3.生成xml文件,将替换变量符后的word文档另存为xml文件: ...
- PowerDesigner将PDM导出生成WORD文档
PowerDesigner将PDM导出生成WORD文档 环境 PowerDesigner15 1.点击Report Temlates 制作模板 2.如果没有模板,单击New图标创建.有直接双击进入. ...
- 将HTML导出生成word文档
前言: 项目开发中遇到了需要将HTML页面的内容导出为一个word文档,所以有了这边随笔. 当然,项目开发又时间有点紧迫,第一时间想到的是用插件,所以百度了下.下面就介绍两个导出word文档的方法. ...
- POI生成word文档完整案例及讲解
一,网上的API讲解 其实POI的生成Word文档的规则就是先把获取到的数据转成xml格式的数据,然后通过xpath解析表单式的应用取值,判断等等,然后在把取到的值放到word文档中,最后在输出来. ...
- FreeMarker生成Word文档
FreeMarker简介: FreeMarker是一款模板引擎:即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页.电子邮件.配置文件.源代码等)的通用工具,它不是面向最终用户的,而是一个 ...
随机推荐
- MySQL数据库开发规范知识点
前言: 设计规范更多的是为了确保数据库设计的合理性.为了项目最终的协调稳定性,而命名规范则更多的是为了确保设计的正式和统一. 约定优先于配置(Convention Over Configuration ...
- 关于django migrations的使用
django 1.8之后推出的migrations机制使django的数据模式管理更方便容易,现在简单谈谈他的机制和一些问题的解决方法: 1.谈谈机制:migrations机制有两个指令,第一个是ma ...
- C#避免踩坑之如何添加paint事件
看截图: 首先,右击->属性 然后出来这个界面. 接下来,注意看这个界面的上面:鼠标悬停这个闪电符号,看到没,事件!! 那个闪电符号,点它! 然后下拉找到这个: 你要事先在代码里面添加Form1 ...
- JeeSite数据分页与翻页
本文章介绍的是JeeSite开源项目二次开发时的一些笔记,对于没有使用过JeeSite的可以不用往下看了,因为下面的代码是跟JeeSite二次开发相关的代码,不做JeeSite的二次开发,以下代码对您 ...
- Lua读取CSV文件到table中
创建Lua函数载入CSV文件并保存到表中的函数: function GetLines(fileName) indx = 0 myLines ={} for line in io.line(string ...
- C/C++静态代码安全检查工具
静态代码安全检查工具是一种能够帮助程序员自动检测出源程序中是否存在安全缺陷的软件.它通过逐行分析程序的源代码,发现软件中潜在的安全漏洞.本文针对 C/C++语言程序设计中容易存在的多种安全问题,分别分 ...
- 阿里Java架构师谈谈架构和如何成为一个Java架构师
架构的定义 我们来看看软件架构的一般定义: 程序和计算系统软件体系结构是指系统的一个或多个结构. 该结构包括软件的构建,构建的外部可见属性以及它们之间的相互关系. 该体系结构不是可操作的软件. 具体来 ...
- 双网卡+mitmproxy+iptables搭建SSL中间人(支持非HTTPS协议)
"想要解决一个问题,最根本方法的就是了解这一切是如何工作的,而不是玄学." --ASCII0X03 最近学习发现现在很多现成的安卓SSL中间人工具和教程都只针对HTTPS流量,比如 ...
- LVM基本应用,扩展及缩减实现!
LVM概述 [百度百科] LVM是逻辑盘卷管理(LogicalVolumeManager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬盘和 分区之上的一个逻辑层,来提高磁 ...
- java语言浅显理解
从厉害的c语言.到经久不衰的java语言.到不太火的安卓和IOS,到当下流行的python,这些都是软件开发中的一员. 之前在传智播客上的免费视频资源上,听了老师对java语言的介绍,感觉挺好了.今天 ...