1. 程式人生 > >【freemarker】使用模板匯出word

【freemarker】使用模板匯出word

1. 需求

           每週固定統計一些資料,然後通過 word 的形式將資料匯出。

2. 思路

              ①  使用poi 的XWPFDocument 相關 api 操作  word 中的資料 。

                   * 存在的問題  :  在獲取 XWPFRun 物件時,對於 run 區域的劃分會有問題,有時候會把需要替換的字元 拆分 , 從而導致在替換時找不到而出錯 。並沒有找到解決的辦法

              ②   使用 freemarker 對 ftl 模板檔案中的特定字串替換掉 ,採取此方法     freemarker 官網


3. 具體實現

               ★  gradle  引用 jar 包   

compile (
'org.freemarker:freemarker:2.3.20',
)

               ★ 生成 ftl 模板檔案 (idea 要作為資原始檔存在 resource包中,方便freemarker獲取)

                         首先是 .doc 的模板檔案 , 將 .doc 中需要動態新增的欄位 用特殊字元替換 (如11h等,這樣可以防止在另存為ftl檔案之後被拆分),然後另存為.xml 檔案 ,另存為.ftl檔案 ,使用編輯器編輯 ftl 檔案 ,將之前特定字元替換成可以被替換的內容(形如${}) 

    ★ 相關程式碼

WordGenerator  util 類

package com.vastio.util;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

import static com.google.common.io.Resources.getResource;

/**
 * Created by xlch on 2016/4/14.
 */
public class WordGenerator {

    private Map<String,String> replaceMap = null;
    private static Configuration config = null;
    private static Map<String,Template> templateMap = null;

    static {
        config = new Configuration();
        config.setDefaultEncoding("utf-8");
        config.setClassForTemplateLoading(WordGenerator.class,"/com/vastio/ftl"); //官方給出三種方法獲取模板檔案
        templateMap = new HashMap<String, Template>();
        try {
            Template template = config.getTemplate("report.ftl");
            templateMap.put("template",template);  //儲存到map中
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public WordGenerator(Map<String, String> replaceMap) {
        this.replaceMap = replaceMap;
    }

    public void exportWord(Writer out){
        Template template = templateMap.get("template");
        try {
            template.process(replaceMap,out);
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //解決設定名稱時的亂碼
    public static String processFileName(HttpServletRequest request, String fileNames) {
        String codedfilename = null;
        try {
            String agent = request.getHeader("USER-AGENT");
            if (null != agent && -1 != agent.indexOf("MSIE") || null != agent
                    && -1 != agent.indexOf("Trident")) {// ie

                String name = java.net.URLEncoder.encode(fileNames, "UTF8");

                codedfilename = name;
            } else if (null != agent && -1 != agent.indexOf("Mozilla")) {// 火狐,chrome等


                codedfilename = new String(fileNames.getBytes("UTF-8"), "iso-8859-1");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return codedfilename;
    }
}

controller 請求  (下載word不可以用非同步請求)
 /**
     * 下載word
     */
    @RequestMapping(value = "/download",method = RequestMethod.POST)
    public String export(HttpServletRequest request, HttpServletResponse response, @RequestParam("week")String week, RedirectAttributes redirectAttributes){
        int isHasData = wordExportService.exportWord(request,response,week); //通過返回值判斷資料庫是否有資料是否需要下載 ,但是若可以下載這裡往下走會有點問題
        if (isHasData == 1){
            return "redirect:/word/home";
        }else{
            redirectAttributes.addFlashAttribute("isHasData",isHasData);
            redirectAttributes.addFlashAttribute("weekNow",week);
            return "redirect:/word/home";
        }
    }

service  的 exportWord 方法
 /**
     * 生成word並匯出
     * @param request
     * @param response
     */
    public int exportWord(HttpServletRequest request, HttpServletResponse response,String week){
        Calendar calendar =  Calendar.getInstance();
        calendar .setTime(DateTimeUtil.strToDate(week,"yyyyMMdd"));
        calendar.add(Calendar.DAY_OF_MONTH,-6);
        String lastWeekBegin = DateTimeUtil.dateToStr(calendar.getTime(),"yyyyMMdd");
        String lastWeekEnd = week;
        Map<String,String> fieldMap = this.modelReplace(lastWeekBegin,lastWeekEnd);
        if (fieldMap == null || fieldMap.size()==0){
            return 0;
        }else{
            WordGenerator generator = new WordGenerator(fieldMap);
            String filename = WordGenerator.processFileName(request,"通報"+lastWeekBegin+"-"+lastWeekEnd+".doc");
            try {
                Writer out =  response.getWriter();
                response.reset();
                response.setContentType("application/msword;charset=utf-8");
                response.setHeader("Content-disposition","attachment;filename="+filename);
                response.setBufferSize(1024);
                generator.exportWord(out);
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return 1;
        }
    }

modelReplace 方法替換模板中的字元
  private Map<String,String> modelReplace(String lastWeekBegin,String lastWeekEnd){
        Map<String,String> fieldMap = new HashMap<String, String>();
    //查詢資料存放在map中   
    // 如 fieldMap.put("login_week_dpt", largePlatformAppStaEntity.getIntPf().toString()); //模板中有 形如 ${login_week_dpt},將會替換資料
}



相關推薦

freemarker使用模板匯出word

1. 需求            每週固定統計一些資料,然後通過 word 的形式將資料匯出。 2. 思路               ①  使用poi 的XWPFDocument 相關 api 操作  word 中的資料 。                    *

Apache POIJava Web根據模板匯出word檔案

最近工作中遇到一個需求:根據word模板文件匯出word檔案。 查閱了一些資料,發現Apache POI可以實現文件讀寫的功能,於是就研究了一下,總結如下: POI詳細介紹: Apache POI是一個開源的Java讀寫Excel、WORD等微軟OLE2元件

Java導出word文檔之freemarker導出

cep tput 代碼 on() 另存為 stat i+1 depend fig Java導出word文檔有很多種方式,本例介紹freemarker導出,根據現有的word模板進行導出 一、簡單導出(不含循環導出)   1、新建一個word文件。如下圖:       2、使

java使用freemarker模板匯出word(帶有合併單元格)文件

前言:最近要做一個匯出word功能,其實網上有很多的例子,但是我需要的是合併單元格的,可是查了好久都沒有自己想要的。研究了幾天其實挺簡單的,在這兒我就簡單的介紹一下吧!(此方法只是一種思路,借鑑者還有根據需求來具體寫程式碼) 一、準備工作 1、jar包:freemarker

FreeMarker利用freemarker生成word版報表

前言: 在很多業務系統中,都需要生成月報,週報的報表。freemarker就很適合生成word版報表,freemarker就是利用word本身自帶的xml格式進行文字替換,圖片替換等操作的,當然除了簡單的替換文字之外,他還有其他的高階用法,詳情請見fre

使用freemarker模板匯出帶表格word文件

一.製作模板    1.將word文件製作成以下樣式,需要替換的內容放佔位符,並按照佔位符名字替換資料。表格裡,使用RR.XXX的形式的佔位符。RR表示當前行物件的名字,XXX相當於物件的屬性名。寫後臺的時候,根據這些名將資料存為map,即名字為鍵值。例子如下:    2.將

FreeMarker程式開發模板載入,模板快取

模板載入器 模板載入器是載入原生文字資料物件。這由具體的模板載入器物件來確定他們取得請求資料時使用了什麼樣的資料來源(資料夾中的檔案,資料等)。當呼叫cfg.getTemplate(Configuration cfg)時,FreeMarker詢問模板載入器是否已經為cfg建

hdu 1863 [最小生成樹+hdu2544floyed+hdu1874dijdtra~~~模板復習~~~

ref define str print break ++ 題目 n) div 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1863 #include<stdio.h> #include<strin

轉載模板:線段樹

int pac 數據 pri note ont tag == else if 感謝勤奮的srf大蒟蒻!! 線段樹1 #include <bits/stdc++.h> #define maxn 100000 #define LL long long using

CCF模板生成系統

== req 文本 fin nth mat vid using 規模 問題描述   成成最近在搭建一個網站,其中一些頁面的部分內容來自數據庫中不同的數據記錄,但是頁面的基本結構是相同的。例如,對於展示用戶信息的頁面,當用戶為 Tom 時,網頁的源代碼是  而當用戶為 Jer

線段樹P3372模板-線段樹

1.5 情況 一行 標記 ask lan build put 同時 百度百科 Definition&Solution   線段樹是一種log級別的樹形結構,可以處理區間修改以及區間查詢問題。期望情況下,復雜度為O(nlogn)。    核心思想見百度百科,線段

hdu1269 有向圖強連通 Targan(模板)

== color truct 相同 ext 結束 數據 訓練 算法 <題目鏈接> 題目大意: 為了訓練小希的方向感,Gardon建立了一座大城堡,裏面有N個房間(N<=10000)和M條通道(M<=100000),每個通道都是單向的,就是說若稱某通道

Tarjan+topsort(DP)P3387 [模板]縮點

Description 給定一個n個點m條邊有向圖,每個點有一個權值,求一條路徑,使路徑經過的點權值之和最大。你只需要求出這個權值和。 允許多次經過一條邊或者一個點,但是,重複經過的點,權值只計算一次。 Input 第一行,n,m 第二行,n個整數,依次代表點權 第三至m+2行,

6、C++模板

C++ 模板     模板是泛型程式設計的基礎,泛型程式設計即以一種獨立於任何特定型別的方式編寫程式碼。 1、函式模板 int swap(int &a, int &b){int temp = a;a = b; b=temp;} float swap

FreeMarker比ajax更好用的展示資料的工具

一、什麼是FreeMarker Freemarker是一個模板引擎,基於模板生成文字輸出的通用工具,是一個java類庫,程式設計師可以嵌入他們所開發產品的元件。 Freemarker主要用於MVC中的view層,生成html展示資料給客戶端,可以完全替代jsp。  Free

caffe模板分離編譯模式和工廠模式

本文轉自: https://blog.csdn.net/raby_gyl/article/details/68489152  caffe中的模板分離編譯模式和工廠模式 1.caffe中模板分離編譯模式的實現方式是在每一個模板原始檔的最後新增一條類似於下面的語句: INST

JSjson匯出到excel,自定義檔名和字尾名

json匯出excel表格 HTML <el-button type="danger" class="ml10 fr" @click="exportForm">匯出表格</el-button> JS 表格輸出的數字,如果太長,會自動計算

UVA1401Remember the Word Trie+dp

題目大意:給定一個字串和一個字串集合,問從集合中選出若干個串組成給定母串的不同方案數。 題解:有些類似於揹包問題。狀態很好表示,為:\(dp[i]\) 表示母串前 i 個字元的不同方案數,因此,有狀態轉移方程為:\(dp[i]=\Sigma dp[j],s[j+1...i]=s_0,s_0\in set\)

java使用freemarker作為模板匯出Excel表格

1:首先新建一個excel表格自己弄好格式如下圖 2:把excel 表格另存為xml格式檔案如下圖 3:這個時候的檔案就是xml 格式的檔案了,在eclipse裡面專案工程裡面新建一個檔案字尾為.ftl 然後把弄好的xml檔案內容直接複製貼上到.ftl檔案裡面 4.

使用FreeMarker自定義匯出word

根據網上的資料和自己在實踐過程中整理總結一下用freemarker自定義匯出word模板 1. 首先準備好一個Word模板 如圖所示,我定義了一個很簡單的模板,然後將所需變數用${}副號定義,例:${username},如圖所示 說明:這裡填寫變數