java-web中生成文檔(一)
基於Java的解決方案也是很多的,包括使用Jacob、Apache POI、Java2Word、iText等各種方式,其實在從Office 2003開始,就可以將Office文檔轉換成XML文件,這樣只要將需要填入的內容放上${}占位符,就可以使用像Freemarker這樣的模板引擎將出現占位符的地方替換成真實數據,這種方式較之其他的方案要更為簡單。
舉個項目中實際的例子,先編輯一個word文擋
1:將文檔另存為成xml格式:
2:另存之後建議用 Editplus、Notepad++、Sublime等工具打開查看一下,因為有的時候你寫的占位符可能會被拆開,這樣Freemarker就無法處理 了。處理成如下圖所示:
3:然後另存為.ftl格式(選擇支持所有的格式),好了非代碼的部分完成,開始搭建自己的項目,我使用的服務器是Tomcat 7.0.52,myelcipse2014;如果是eclipse需要配置web.xml支持servlet3的註解,在搭建項目之前需要向項目中加入freemarker的JAR文件,可以通過下面的鏈接獲得Freemarker的最新版本:http://freemarker.org/freemarkerdownload.html
我搭建的是一個maven 的項目,進入當中找到pom文件所需有的配置文件http://mvnrepository.com/artifact/org.freemarker/freemarker
4.完成jsp的網頁代碼,當中要明白name的命名一定是與ftl文件中的值是對應的,這樣才能取到值。上傳jsp代碼
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <[email protected]
(註意param這個el表達式對象不能用到word文檔取值,保證name的值一致就行)
我在把spring-mvc中的控制器代碼,給一份;如果你用servlet去寫也可以,但是要支持webservice註解的需要用到servlet3.0,這是就需要去web.xml容器中寫配置文件
如果不支持就麻煩了,所以我使用springmvc的核心控制器寫的,不多說了給代碼
package com.controller.zy; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.lovo.util.WordGenerator; @Controller public class MyServlet extends HttpServlet { private static final long serialVersionUID = 1L; @RequestMapping("/saveDocServlet.s") protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); Map<String, Object> map = new HashMap<String, Object>(); Enumeration<String> paramNames = req.getParameterNames(); // 通過循環將表單參數放入鍵值對映射中 while(paramNames.hasMoreElements()) { String key = paramNames.nextElement(); String value = req.getParameter(key); map.put(key, value); } // 提示:在調用工具類生成Word文檔之前應當檢查所有字段是否完整 // 否則Freemarker的模板殷勤在處理時可能會因為找不到值而報錯 這裏暫時忽略這個步驟了 File file = null; InputStream fin = null; ServletOutputStream out = null; try { // 調用工具類WordGenerator的createDoc方法生成Word文檔 file = WordGenerator.createDoc(map, "zhy"); fin = new FileInputStream(file); resp.setCharacterEncoding("utf-8"); resp.setContentType("application/msword"); // 設置瀏覽器以下載的方式處理該文件默認名為zhy.doc resp.addHeader("Content-Disposition", "attachment;filename=zhy.doc"); out = resp.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(); // 刪除臨時文件 } } }
5,還要有個工具類作為中間調用的方法使用,不用多想,代碼是固定的,拿著改文件名就可以
package com.lovo.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.HashMap; import java.util.Map; import freemarker.template.Configuration; import freemarker.template.Template; public class WordGenerator { private static Configuration configuration = null; private static Map<String, Template> allTemplates = null; static { configuration = new Configuration(); configuration.setDefaultEncoding("utf-8"); configuration.setClassForTemplateLoading(WordGenerator.class, "/com/lovo/ftl"); allTemplates = new HashMap<>(); // Java 7 鉆石語法 try { allTemplates.put("zhy", configuration.getTemplate("zhy.ftl")); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } } private WordGenerator() { throw new AssertionError(); } public static File createDoc(Map<?, ?> dataMap, String type) { String name = "temp" + (int) (Math.random() * 100000) + ".doc"; File f = new File(name); Template t = allTemplates.get(type); 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; } }
到這裏已經完成了代碼,部署到服務器就可以使用了,希望能夠幫到你。
java-web中生成文檔(一)