欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

程序员文章站 2023-04-07 23:02:46
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个方案只能在java中运行,无法在Android项目中运行。所以此方案是:APP将表单数据发送给后台,后台通过freemarker将表单数据根据模板ftl文件生成Word文件,然后返回给APP,由APP进行展现。 前期准备 1、下 ......

版权声明:本文为haiyuking原创文章,转载请注明出处!

前言

这个方案只能在java中运行,无法在android项目中运行。所以此方案是:app将表单数据发送给后台,后台通过freemarker将表单数据根据模板ftl文件生成word文件,然后返回给app,由app进行展现。

前期准备

1、下载freemarker.jar文件

官网下载地址:

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

 FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

后续将freemarker.jar文件添加到项目中。

2、制作模板ftl文件

(1)先用office2003或更高版本word软件编辑好word模版文件【版本要2003以上,2003以下的不支持另存为xml格式功能】

注意:

  • 在word模板中写入相对真实的数据【注意,不要使用英文,尽量使用中文、数字,见附录1】;
  • 对于对勾样式的数据,在word模板文件中统一用安卓代替(后续需要通过java代码传入带有对勾样式的数据);
  • 需要设置图片的话,需要在word模板文件中放入真实的图片占位;请尽量选择小于50k的图片,并且把图片的大小和位置调整好。选择小图片的原因是避免xml文件过大导致打开时缓慢甚至卡死。

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

例子:

 FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

(2)另存为word 2003 xml文档

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

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

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

(3)下载firstobject xml editor软件

 下载firstobject xml editor软件(免安装版):下载地址:

 FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】  FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

官网下载的软件打开文件的时候可能会出现崩溃的问题建议使用foxe_chs.exe软件进行编辑。下载地址见项目demo下载地址。

(4)使用firstobject xml editor软件将xml打开,将真实数据换成freemarker标记

首先进行“缩进排版”

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

查找真实数据,替换成freemarker标记,其实就是map<string, object>中key,如${writedate},对应map的key值就是writedate。

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

替换成:

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

对于文本按照上面的方式进行替换,而对于图片需要这样替换:

图片是以base64编码存在的,且这些编码放在<w:bindata>标签之中。将这些base64编码使用占位符代替,然后java代码中将图片生成base64编码,传入值就能正常显示了。

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

替换成

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

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

 FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

注意:一定不要用word打开ftl模板文件查看,否则xml内容会发生变化,导致前面的工作白做了;可以使用editplus打开查看。

使用步骤

一、项目组织结构图

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

二、导入步骤

1、在项目中引入freemarker.jar

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

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

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

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);
    }
}

注意:map数据中的key值,对应ftl文件中的${xxxx}这里面的xxxx值。

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

4、运行

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

5、效果

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

附录

1、word模板中输入真实数据的技巧

1、不要使用英文;

2、如果想要保证一个整体,不要将中文、数字、标点符号一起使用(这里指占位区域);

3、日期想要作为一个整体,不要数字+中文输入,而是通过enter键输入;

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

下面记录的是不同输入的效果(使用firstobject xml editor软件打开xml文件)

使用英文:

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

使用数字:

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

使用中文:

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

 日期采用数字+中文:

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

日期采用enter键输入:

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

中文+标点符号:

FreemarkerJavaDemo【Android将表单数据生成Word文档的方案之一(基于freemarker2.3.28,只能java生成)】

参考资料

java生成word的几种方案

沫沫金:使用java模版引擎freemarker生成复杂的word文档

firstobject xml 编辑器

用freemarker导出word文档

android利用freemarker自动生成文件

freemarker入门案例

freemarker生成各类文件,含图片

freemaker解析word模板(含图片)生成word文档

项目demo下载地址

链接:https://pan.baidu.com/s/19apniywxt5gmn_kdqjfcra 提取码:eo0n