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

一、   步驟

一、    用word編輯好模板

一、 普通字符串替換爲 ${string}javascript

二、 表格循環用標籤java

<#list  userList as user>
    姓名:${user.userName}   , 性別:${user.sex}
</#list>

word模板原型以下圖:apache

最終生成的結果以下:app

二、    將word模板另存爲xml格式

選中 [ 僅保存數據 ]dom

選擇 [ 保持wordML(K) ]jsp

三、    將xml模板文件後綴名改成.ftl

四、    編輯ftl文件

搜索關鍵字,補入 <#list userList  as user> </#list>或其它freemarker標籤工具

以下圖:this

二、   Java代碼

package com.lun.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;
import freemarker.template.Configuration;
import freemarker.template.Template;

/**
 * @Desc:word操做工具類
 * @Author:張輪
 * @Date:2014-1-22下午05:03:19
 */
public class WordUtil {

    /**
     * @Desc:生成word文件
     * @Author:張輪
     * @Date:2014-1-22下午05:33:42
     * @param dataMap word中須要展現的動態數據,用map集合來保存
     * @param templateName word模板名稱,例如:test.ftl
     * @param filePath 文件生成的目標路徑,例如:D:/wordFile/
     * @param fileName 生成的文件名稱,例如:test.doc
     */
    @SuppressWarnings("unchecked")
    public static void createWord(Map dataMap, String templateName,
            String filePath, String fileName) {
        try {
            // 建立配置實例
            Configuration configuration = new Configuration();
            // 設置編碼
            configuration.setDefaultEncoding("UTF-8");
            // ftl模板文件統一放至 com.lun.template 包下面
            configuration.setClassForTemplateLoading(WordUtil.class,
                    "/com/lun/template/");
            // 獲取模板
            Template template = configuration.getTemplate(templateName);
            // 輸出文件
            File outFile = new File(filePath + File.separator + fileName);
            // 若是輸出目標文件夾不存在,則建立
            if (!outFile.getParentFile().exists()) {
                outFile.getParentFile().mkdirs();
            }
            // 將模板和數據模型合併生成文件
            Writer out = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(outFile), "UTF-8"));
            // 生成文件
            template.process(dataMap, out);
            // 關閉流
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
package com.lun.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.struts2.ServletActionContext;
import com.lun.utils.WordUtil;
import com.opensymphony.xwork2.ActionSupport;

/**
 * @Desc:生成word
 * @Author:張輪
 * @Date:2014-1-22下午04:52:03
 */
@SuppressWarnings("serial")
public class WordAction  extends ActionSupport{

 private String filePath; //文件路徑
 private String fileName; //文件名稱
 private String fileOnlyName; //文件惟一名稱

 /**
  * @Desc:生成word文檔
  * @Author:張輪
  * @Date:2014-1-22下午07:29:58
  * @return
  */
    public String createWord() {
        /** 用於組裝word頁面須要的數據 */
        Map<String, Object> dataMap = new HashMap<String, Object>();
        /** 組裝數據 */
        dataMap.put("userName","張三");
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日");
        dataMap.put("currDate",sdf.format(new Date()));
        dataMap.put("content","這是其它內容這是其它內容這是其它內容這是其它內容這是其它內容這是其它內容這是其它內容這是其它內容這是其它內容這是其它內容這是其它內容這是其它內容這是其它內容");
List
<Map<String, Object>> newsList=new ArrayList<Map<String,Object>>();
     for(int i=1;i<=10;i++){   Map<String, Object> map=new HashMap<String, Object>();   map.put("title", "標題"+i);   map.put("content", "內容"+(i*2));   map.put("author", "做者"+(i*3));   newsList.add(map); } dataMap.put("newsList",newsList); /** 文件名稱,惟一字符串 */ Random r=new Random(); SimpleDateFormat sdf1=new SimpleDateFormat("yyyyMMdd_HHmmss_SSS"); StringBuffer sb=new StringBuffer(); sb.append(sdf1.format(new Date())); sb.append("_"); sb.append(r.nextInt(100)); //文件路徑 filePath=ServletActionContext.getServletContext().getRealPath("/")+"upload"; //文件惟一名稱 fileOnlyName = "用freemarker導出的Word文檔_"+sb+".doc"; //文件名稱 fileName="用freemarker導出的Word文檔.doc"; /** 生成word */ WordUtil.createWord(dataMap, "news.ftl", filePath, fileOnlyName); return "createWordSuccess"; }
 /**
  * @Desc:下載生成的word文檔,入口,用來跳轉至struts XML配置
  * @Author:張輪
  * @Date:2014-1-22下午07:36:29
  * @return
  */
    public String dowloadWord() {
        /** 先判斷文件是否已生成  */
        try {
           //解決中文亂碼
           filePath = URLDecoder.decode(filePath, "UTF-8");
           fileOnlyName = URLDecoder.decode(fileOnlyName, "UTF-8");
           fileName = URLDecoder.decode(fileName, "UTF-8");
         
           //若是文件不存在,則會跳入異常,而後能夠進行異常處理
            new FileInputStream(filePath + File.separator +  fileOnlyName);
        } catch (Exception e) {
         e.printStackTrace();
           return "error";
        }
        return "dowloadWord";
    }
/**
     * @Desc:下載生成的word文檔
     * 該方法是struts.xml文件中的: <param name="inputName">wordFile</param> 中自動對應的get方法,該方法自動調用
     * @Author:張輪
     * @Date:2014-1-22下午07:36:29
     * @return 返回最終生成的word文檔 文件流
     */
    public InputStream getWordFile(){
        try {
           //解決中文亂碼
           fileName = URLDecoder.decode(fileName, "UTF-8");
         
            /** 返回最終生成的word文件流  */
            return new FileInputStream(filePath + File.separator + fileOnlyName);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

   public String getFilePath() {
      return filePath;
   }

   public void setFilePath(String filePath) {
      this.filePath = filePath;
   }

   public String getFileName() {
      return fileName;
   }

   public void setFileName(String fileName) {
      this.fileName = fileName;
   }

   public String getFileOnlyName() {
      return fileOnlyName;
   }

   public void setFileOnlyName(String fileOnlyName) {
      this.fileOnlyName = fileOnlyName;
   }
}

struts2配置文件以下:編碼

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
 "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
 "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <package name="word" namespace="/" extends="struts-default">
        <action name="createWord" class="com.lun.action.WordAction" method="createWord">
            <result name="createWordSuccess" type="redirectAction">
                <param name="actionName">
                    dowloadWord
                </param>
                <param name="filePath">
                    ${filePath}
                </param>
                <param name="fileOnlyName">
                    ${fileOnlyName}
                </param>
                <param name="fileName">
                    ${fileName}
                </param>
                <param name="encode">
                    true
                </param>
            </result>
        </action>
        <action name="dowloadWord" class="com.lun.action.WordAction" method="dowloadWord">
            <result name="dowloadWord" type="stream">
                <param name="contentDisposition">
                    attachment;filename="${fileName}"
                </param>
                <param name="inputName">
                    wordFile
                </param>
                <param name="encode">
                    true
                </param>
            </result>
            <result name="error">
                /error.jsp
            </result>
        </action>
    </package>
</struts>

頁面調用以下:spa

<input type="button" onclick="javascript:window.location.href='createWord.action'" value="生成Word"/>

三、注意

一、編輯word模板時,${string} 標籤最好是手動一次性輸入完畢,或者使用記事本統一將整個${string}編輯好以後,粘貼至word裏邊。

也就是說,不要在word裏首先打完 ${ } 以後,又從其它地方把 string 字符串粘貼至 { } 之間,這樣在 word 轉化爲 xml時,解析會有問題,freemarker解析時,會報錯。

將${} 和 string 分開錄入word,另存爲xml後,後果將以下:

二、若是word裏有須要循環表格列,也就是橫向循環表格時,建議儘可能改成循環行,縱向循環,這樣能夠減小對 ftl 文件的 list標籤插入,縮減工做量。

本文轉自:http://blog.csdn.net/lun379292733/article/details/18673081

相關文章
相關標籤/搜索