1. 程式人生 > >使用Velocity匯出Word文件

使用Velocity匯出Word文件

前言

  基於上一篇的velocity的簡單介紹,本篇部落格主要是利用velocity進行word文件的匯出。【迫不得已用MarkDown編輯器,不是特別喜歡】
  在開發過程中,我們經常遇到匯出各種各樣格式的檔案,如Excel、Txt、Word等,如果僅僅是將資料匯出沒有什麼特別要求的話,很多技術都可以很簡單的完成。不過有時候會遇到一些根據指定的模板來匯出,而且這個模板裡面有各種各樣的樣式限制,這個時候通過一般的工具可能就會比較麻煩一點了。下面就介紹下使用velocity進行word模板匯出。

模板的建立

  首先,我們需要自己建立一個word文件,把我們需要的格式自定義好。如下圖Word文件,我們有一個居中標題,和一個帶顏色和一定樣式的表格。
Word模板


  然後右鍵另存為xml格式,如圖所示:
這裡寫圖片描述
這個時候開啟我們的xml文件,最好通過工具格式化一下,xml線上格式工具,內容會比較多,我們直接將文件拉到最後,找到我們寫的文字,將重複的文字內容進行模板替換,這裡我們用了foreach方法【具體見介紹】,因為表格內容是可以迴圈新增的。上面的文件名稱由於截圖限制看不到,我是用${wordName}進行替換。如圖所示:
這裡寫圖片描述

Velocity匯出Word

  完成了模板建立之後,我們就可以從後臺進行賦值替換了。先看下我寫的一個Demo案例。

public class VelocityUtil {
    static{
        Properties p = new
Properties(); // 設定輸入輸出編碼型別。和這次說的解決的問題無關 p.setProperty(Velocity.INPUT_ENCODING, "UTF-8"); p.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8"); //檔案快取 p.setProperty(Velocity.FILE_RESOURCE_LOADER_CACHE, "false"); // 這裡載入類路徑裡的模板而不是檔案系統路徑裡的模板 p.setProperty("file.resource.loader.class"
, "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); Velocity.init(p); } public static Template getTemplateInstance(String templtePath){ Template template = Velocity.getTemplate(templtePath); return template; } public static void main(String[] args){ List<Phone> phoneList = new ArrayList<Phone>(); for(int i=0;i<4;i++){ Phone phone = new Phone(); phone.setId(i+""); phone.setName("手機"+i); phone.setDesc("描述"+i); phoneList.add(phone); } Template template = getTemplateInstance("template/wordModel.xml"); try { Writer writer = new FileWriter(new File("c://test.doc")); Context con = new VelocityContext(); con.put("phones", phoneList); con.put("wordName", "我傳過去的文件名稱"); template.merge(con, writer); writer.flush(); writer.close(); System.out.println("over"); } catch (IOException e) { e.printStackTrace(); } } }

看下效果圖,可以看到內容已經是我們從後臺傳過去的內容,樣式和內容都是我們自定義的。
這裡寫圖片描述

  這裡我是把該類寫成了工具類,所以在我們web專案中可以直接呼叫該類進行相應的模板匯出。給大家一個Action中匯出的Demo,這裡用的POI。基本就是這個步驟:

        //1查詢相關資料

        //2建立模板
        Template template = VelocityUtil.getTemplateInstance("/template/xxx.vm");
        Context context= new VelocityContext();
        context.put("xxx", list);
        context.put("encoder", ESAPI.encoder());

        Writer writer = new StringWriter();

        //3模板替換
        template.merge(context, writer);

        try {
            //4完成匯出
            HttpServletResponse response = ServletActionContext.getResponse();
            response.setHeader("Content-disposition",
                    "attachment; filename=\"" + URLEncoder.encode("xxx.doc", "utf-8") + "\"");

            OutputStream os = null;
            os = response.getOutputStream();

            ByteArrayInputStream bais = new ByteArrayInputStream(writer.toString().getBytes());
            POIFSFileSystem poifs = new POIFSFileSystem();
            DirectoryEntry directory = poifs.getRoot();

            directory.createDocument("WordDocument", bais); 
            poifs.writeFilesystem(os );

        }  catch (IOException e) {
            e.printStackTrace();
        }