天天看點

使用freemarker實作word導出

1,下載下傳freemarker架包。

2,使用word繪制一個導出後的模闆,其中${}寫入自己所對應的實體類字段或是自己取到的鍵值資料(對應下面的map)

使用freemarker實作word導出

3.将上面的word另存為.xml檔案,然後重命名将字尾.xml 改為 .ftl(右鍵重命名時沒字尾是電腦沒設定字尾顯示)

4.被控制層調用類DocumentHandler .class的代碼如下:

public class DocumentHandler {


private Configuration configuration = null;  

    public DocumentHandler() {  
        configuration = new Configuration();  
        configuration.setDefaultEncoding("utf-8");  
    }  

    /**
     * @desc  導出doc檔案 -- 到本地電腦
     * @author MrC
     * @param dataMap 要填入模本的資料檔案  
     * @param templatePath 模闆路徑 
     * 模闆路徑 如:String templatePath = request.getServletContext().getRealPath("/") + File.separator + "exportTemplate";
     * @param templateName 模闆名 如:freeMarkTemplate.ftl
     * @throws Exception
     */
    public void createDoc(Writer out,Map<String,Object> dataMap,String templatePath,String templateName) throws Exception {  
    //設定模本裝置方法和路徑,FreeMarker支援多種模闆裝載方法。可以重servlet,classpath,資料庫裝載,  
    configuration.setDirectoryForTemplateLoading(new File(templatePath));  
        Template t=null;  
        try {  
            //test.ftl為要裝載的模闆  + File.separator + "freeMarkTemplate.ftl"
            t = configuration.getTemplate(templateName);  
        } catch (IOException e) {  
            e.printStackTrace();  
        } 

        try {  
            t.process(dataMap, out);  
            out.close();  
        } catch (TemplateException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    } 

    /**
     * @desc  導出doc檔案 --至指定路徑下
     * @author MrC
     * @param dataMap 要填入模本的資料檔案  
     * @param templatePath 模闆路徑 
     * 模闆路徑 如:String templatePath = request.getServletContext().getRealPath("/") + File.separator + "exportTemplate";
     * @param templateName 模闆名 如:freeMarkTemplate.ftl 
     * @param fileName 下載下傳路徑 
     * 下載下傳路徑 如:String templatePath = request.getServletContext().getRealPath("/") + File.separator + "outFile.doc";
     */
    public void createDoc2(Map<String,Object> dataMap,String templatePath,String templateName,
    String filePath,String fileName) throws Exception {  
    //設定模本裝置方法和路徑,FreeMarker支援多種模闆裝載方法。可以重servlet,classpath,資料庫裝載,  
        configuration.setDirectoryForTemplateLoading(new File(templatePath)); 
        Template t=null;  
        try {  
            //test.ftl為要裝載的模闆  + File.separator + "freeMarkTemplate.ftl"
            t = configuration.getTemplate(templateName);  
        } catch (IOException e) {  
            e.printStackTrace();  
        } 

        File file = new File(filePath);
if (!file.exists()) { //判斷檔案夾是否存在,如果不存在則建立檔案夾
file.mkdirs();
}

        //輸出文檔路徑及名稱  
        File outFile = new File(filePath + File.separator + fileName);  
        Writer out = null;  
        FileOutputStream fos=null;  
        try {  
            fos = new FileOutputStream(outFile);  
            OutputStreamWriter oWriter = new OutputStreamWriter(fos,"GBK");  
            //這個地方對流的編碼不可或缺,使用main()單獨調用時,應該可以,但是如果是web請求導出時導出後word文檔就會打不開,并且包XML檔案錯誤。主要是編碼格式不正确,無法解析。  
            //out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));  
             out = new BufferedWriter(oWriter);   
        } catch (FileNotFoundException e1) {  
            e1.printStackTrace();  
        }  

        try {  
            t.process(dataMap, out);  
            out.close();  
            fos.close();  
        } catch (TemplateException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}
           

5.控制層代碼:

//dataMap用來存儲你将要導出的資料
  Map<String,Object>  dataMap = new HashMap<String,Object>;

  //這裡的volunteerId對應上面word中的${volunteerId},volunteerDto是我自己的實體類,以下為事例代碼
  dataMap.put("volunteerId",volunteerDto.getVolunteerId);

  DocumentHandler mdoc = new DocumentHandler();
        //擷取模闆路徑
String templatePath = request.getSession().getServletContext().getRealPath("")+"/wordTemplate";
//模闆名字
String templateName="volunteer.ftl";
//取得請求頭
response.setContentType("application/x-msdownload");
response.setCharacterEncoding("utf-8");
String fileName="資料加載錯誤";
//設定導出名字
if(volunteerDto.getUserName()!=null&&volunteerDto.getCertifNo()!=null){
fileName = volunteerDto.getUserName()+"+"+volunteerDto.getCertifNo()+".doc";
}
response.setHeader("content-disposition", "attachment;filename="+new String(fileName.getBytes("gb2312"), "ISO8859-1"));
//調用導出方法
mdoc.createDoc(response.getWriter(),dataMap,templatePath,templateName);
           

6.以上代碼可實作頁面下點選導出按鈕,如果導出出現word文檔内容錯誤而打不開,很可能是編碼不統一