1. 程式人生 > >Java Web 生成Word文件(freemarker方式)

Java Web 生成Word文件(freemarker方式)

首先在pom檔案中加入下面這個依賴(不是Maven專案的話,把jar包匯入專案即可)

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.23</version>
</dependency>

1.建立帶有格式的word文件,將該需要動態展示的資料使用變數符替換。如下:

2.將上述1所建立的文件另存為.xml格式。

3.編輯上述2的.xml檔案去掉多餘的xml標記,如下圖(紅圈是正確的格式,應該由${變數符}包裹著)

 4.將上述3的文件另存為.ftl格式,然後複製到Web專案(下圖目錄)。

 5.JSP頁面提供生成word文件的按鈕。

<a href="javascript:;" onclick="exportWord('${rightId}')" class="btn btn-success radius"><i class="Hui-iconfont">&#xe644;</i>匯出Word</a> 

JS程式碼:
//生成word文件
function exportWord(rightId){
    layer.confirm('確認要生成word文件嗎?',function(index){
        //關閉視窗
        layer.close(index);
        window.location.href ="<%= basePath%>/biz/SysRight_exportWord.action?rightId="+rightId+""
	});
}

效果如下:

 

6.Action中的exportWord()方法。

/**
	 * 生成word文件(測試使用)
	 * @Description: TODO
	 * @param @return
	 * @param @throws Exception   
	 * @return String  
	 * @throws
	 * @author uug
	 * @date 2018年12月9日
	 */
	public String exportWord() throws Exception {
        //需要顯示的資料
		sysRight = sysRightService.exportWord(sysRight.getRightId());
		HttpServletResponse response = ServletActionContext.getResponse();
		HttpServletRequest request = ServletActionContext.getRequest();
		//建立Map
        Map<String, Object> map = new HashMap<String, Object>();
        //將資料put到Map中,第一個引數為.ftl檔案中對應的${}名稱,第二個引數為需要顯示的內容
        map.put("rightId",sysRight.getRightId());
        map.put("rightName",sysRight.getRightName());
        map.put("resourcePath",sysRight.getResourcePath());
        map.put("rightPid",sysRight.getRightPid());
        //需要呼叫的模板名稱
        String downloadType = "test";
        //匯出時的名稱
        String fileName = "許可權列表";
        WordUtils.exportMillCertificateWord(request,response,map,downloadType , fileName);
		return null;
	}

 6.WordUtils工具類。

@SuppressWarnings("deprecation")
public class WordUtils {
	//配置資訊
    private static Configuration configuration = null;
  //這裡注意的是利用WordUtils的類載入器動態獲得模板檔案的位置
    private static final String templateFolder = WordUtils.class.getClassLoader().getResource("../../").getPath() + "WEB-INF/asserts/templete/";
    //用於存放所有的.ftl檔案
    private static Map<String, Template> allTemplates = null;
	
	static {
		configuration = new Configuration();
		configuration.setDefaultEncoding("utf-8");
		allTemplates = new HashMap<String, Template>();
		try {
			configuration.setDirectoryForTemplateLoading(new File(templateFolder));
			//將test.ftl檔案存入Map
			allTemplates.put("test", configuration.getTemplate("test.ftl"));
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	
	private WordUtils() {  
        throw new AssertionError();  
    }
 
	/**
	 * 
	 * @Description: TODO
	 * @param @param request
	 * @param @param response
	 * @param @param map 寫入檔案的資料
	 * @param @param downloadType  需要呼叫Map allTemplates對應的那個.ftl檔案
	 * @param @param fileName0  設定瀏覽器以下載的方式處理該檔名
	 * @param @throws IOException   
	 * @return void  
	 * @throws
	 * @author uug
	 * @date 2018年12月9日
	 */
    public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map, String downloadType, String fileName0) throws IOException {
        //定義Template物件,注意模板型別名字與downloadType要一致
    	Template template= allTemplates.get(downloadType);
        File file = null;
        InputStream fin = null;
        ServletOutputStream out = null;
        try {
            // 呼叫工具類的createDoc方法生成Word文件
            file = createDoc(map,template);
            fin = new FileInputStream(file);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            // 設定瀏覽器以下載的方式處理該檔名
            String fileName = fileName0 + ".doc";
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
 
            out = response.getOutputStream();
            byte[] buffer = new byte[512];  // 緩衝區
            int bytesToRead = -1;
            // 通過迴圈將讀入的Word檔案的內容輸出到瀏覽器中
            while((bytesToRead = fin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        } finally {
            if(fin != null) fin.close();
            if(out != null) out.close();
            if(file != null) file.delete(); // 刪除臨時檔案
        }
    }
 
    /**
     * 建立doc文件
     * @Description: TODO
     * @param @param dataMap
     * @param @param template
     * @param @return   
     * @return File  
     * @throws
     * @author uug
     * @date 2018年12月9日
     */
    private static File createDoc(Map<?, ?> dataMap, Template template) {
        String name = "temp" + (int) (Math.random() * 100000) + ".doc"; 
        File f = new File(name);
        Template t = template;
        try {
            // 這個地方不能使用FileWriter因為需要指定編碼型別否則生成的Word文件會因為有無法識別的編碼而無法開啟
            Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
            t.process(dataMap, w);
            w.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
        return f;
    }
}

 7.效果如下: