FreemarkerJavaDemo【Android將表單數據生成Word文檔的方案之一(基於freemarker2.3.28,只能java生成)】

版權聲明:本文爲HaiyuKing原創文章,轉載請註明出處!html

前言

這個方案只能在java中運行,沒法在Android項目中運行。因此此方案是:APP將表單數據發送給後臺,後臺經過freemarker將表單數據根據模板ftl文件生成Word文件,而後返回給APP,由APP進行展示。java

前期準備

一、下載freemarker.jar文件

官網下載地址:https://freemarker.apache.org/freemarkerdownload.html數據庫

 

後續將freemarker.jar文件添加到項目中。apache

二、製做模板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文件!ide

(3)下載FirstObject XML Editor軟件

 下載FirstObject XML Editor軟件(免安裝版):下載地址:http://www.firstobject.com/dn_editor.htm測試

   

官網下載的軟件打開文件的時候可能會出現崩潰的問題建議使用foxe_CHS.exe軟件進行編輯。下載地址見項目Demo下載地址。this

(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、項目組織結構圖

2、導入步驟

一、在項目中引入freemarker.jar

二、將製做的模板文件leaveTemplet.ftl和圖片資源複製到D:/temp目錄下

三、將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值。

四、運行

五、效果

附錄

一、Word模板中輸入真實數據的技巧

一、不要使用英文;

二、若是想要保證一個總體,不要將中文、數字、標點符號一塊兒使用(這裏指佔位區域);

三、日期想要做爲一個總體,不要數字+中文輸入,而是經過Enter鍵輸入;

下面記錄的是不一樣輸入的效果(使用FirstObject XML Editor軟件打開xml文件)

使用英文:

使用數字:

使用中文:

 日期採用數字+中文:

日期採用Enter鍵輸入:

中文+標點符號:

參考資料

java生成word的幾種方案

沫沫金:使用Java模版引擎FreeMarker生成複雜的Word文檔

模板引擎freemarker的簡單使用教程

使用freemarker生成word,步驟詳解並奉上源代碼

firstobject XML 編輯器

freemarker官網

用Freemarker導出word文檔

Android利用FreeMarker自動生成文件

Freemarker入門案例

freeMarker生成各種文件,含圖片

FreeMaker解析Word模板(含圖片)生成Word文檔

項目demo下載地址

連接:https://pan.baidu.com/s/19aPNIYWXt5GMN_KDQjFCRA 提取碼:eo0n

相關文章
相關標籤/搜索