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生成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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM