通過freemarker生成一個word,解決生成的word用wps開啟有問題的問題,解決出word時中文檔名亂碼問題,解決打開出word時開啟的word出現問題的問題,出圖片,解決動態列表
通過freemarker製作word比較簡單
步驟:製作word模板。製作方式是:將模板word儲存成為xml----在xml的word模板中新增相應的標記----將xml的word檔案的字尾名改成ftl檔案(要注意的是生成xml格式要是2003格式的xml,也就是說拿到的word模板得是2003格式的,否則用wps開啟word將會出現問題)
詳細步驟如下:
模板製作(將要動態顯示的資料打上標記,這個標記是freemarker中的EL標記,要注意的是,要控制值為空的情況,下面${(site.wzmc)?default(“”)}標識當網站名稱為空的時候顯示空值,如果這裡如果不做控制,在實際專案中會顯示錯誤!)
另外要注意的是:
一、不要直接在word中替換掉文字的方式新增標記,這種會有問題。
二、不要使用Eclipse對xml檔案進行格式化,這種生成word的時候會提示文件有問題。解決這個的問題是通過firstobject對word的xml進行格式化,對xml進行編輯。(使用firstobject開啟帶有中文檔名的xml檔案的時候,會出現問題,建議使用英文word文件名稱),或者使用XMLViewer
三、firstobject下載地址:http://www.firstobject.com/dn_editor.htm
其中,要想軟體能夠格式化xml程式碼,需要進行設定,設定方式是:開啟firstobject----Tools-----Preferences------Format-----Tabs
點選Indent,結果xml變成了有格式化的,效果圖如下:
常見標籤:
行標記:
<w:p w:rsidR="00790C22"w:rsidRPr="00C07F75" w:rsidRDefault="00790C22"w:rsidP="004018B7">
標識是一個表格的標籤
<w:tbl></w:tb1>
表格行:
<w:trw:rsidR="00790C22" w:rsidRPr="00C07F75"w:rsidTr="004018B7"></w:tr>
表格中的單元格:
<w:tc></w:tc>
迴圈輸出資料的方式
<#list problemInfoInterview as problemInfo> <w:tbl> <w:tblPr> <w:tblW w:w="0" w:type="auto"/> <w:tblBorders> <w:top w:val="single" w:sz="4" w:space="0" w:color="auto"/> <w:left w:val="single" w:sz="4" w:space="0" w:color="auto"/> <w:bottom w:val="single" w:sz="4" w:space="0" w:color="auto"/> <w:right w:val="single" w:sz="4" w:space="0" w:color="auto"/> <w:insideH w:val="single" w:sz="4" w:space="0" w:color="auto"/> <w:insideV w:val="single" w:sz="4" w:space="0" w:color="auto"/> </w:tblBorders> <w:tblLook w:val="04A0" w:firstRow="1" w:lastRow="0" w:firstColumn="1" w:lastColumn="0" w:noHBand="0" w:noVBand="1"/> </w:tblPr> <w:tblGrid> <w:gridCol w:w="2235"/> <w:gridCol w:w="6287"/> </w:tblGrid> <w:tr w:rsidR="00790C22" w:rsidRPr="00C07F75" w:rsidTr="004018B7"> <w:tc> <w:tcPr> <w:tcW w:w="2235" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="auto"/> <w:vAlign w:val="center"/> </w:tcPr> <w:p w:rsidR="00790C22" w:rsidRPr="00C07F75" w:rsidRDefault="00790C22" w:rsidP="004018B7"> <w:pPr> <w:jc w:val="center"/> <w:rPr> <w:rFonts w:ascii="Times New Roman" w:eastAsia="黑體" w:hAnsi="Times New Roman"/> <w:sz w:val="24"/> <w:szCs w:val="24"/> </w:rPr> </w:pPr> <w:r> <w:rPr> <w:rFonts w:ascii="Times New Roman" w:eastAsia="黑體" w:hAnsi="Times New Roman" w:hint="eastAsia"/> <w:sz w:val="24"/> <w:szCs w:val="24"/> </w:rPr> <w:t>問題名稱</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="6287" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="auto"/> <w:vAlign w:val="center"/> </w:tcPr> <w:p w:rsidR="00790C22" w:rsidRPr="00C07F75" w:rsidRDefault="00790C22" w:rsidP="004018B7"> <w:pPr> <w:jc w:val="left"/> <w:rPr> <w:rFonts w:ascii="Times New Roman" w:eastAsia="宋體" w:hAnsi="Times New Roman"/> <w:sz w:val="24"/> <w:szCs w:val="24"/> </w:rPr> </w:pPr> <w:r> <w:rPr> <w:rFonts w:ascii="Times New Roman" w:eastAsia="宋體" w:hAnsi="Times New Roman" w:hint="eastAsia" /> <w:sz w:val="24" /> <w:szCs w:val="24" /> </w:rPr> <w:t>${(problemInfo.problemName)?default("")}</w:t> </w:r> </w:p> </w:tc> </w:tr> 這裡面的行刪除 </w:tbl> <w:p w:rsidR="007F35A8" w:rsidRPr="007F35A8" w:rsidRDefault="007F35A8" w:rsidP="007F35A8" /> </#list> |
另外,往文件中插入圖片的時候,在做模板的時候要往模板中插入一個圖片,然後開啟文件,然後替換掉base64轉碼的圖片部分。
將圖片資源變成base64加密後的圖片的程式碼
將圖片轉成base64串的方式:
publicstatic String getImageString(String fileName)throws IOException { InputStream in =null; byte[] data =null; try { in =new FileInputStream(fileName); data =newbyte[in.available()]; in.read(data); in.close(); }catch (Exception e) { e.printStackTrace(); }finally { if (in !=null){ in.close(); } } Base64Encoder encoder =new Base64Encoder(); return data !=null ? encoder.encode(data) :""; } |
下面是出word用的相關的類:
讀取路徑用的TemplateUtil工具類
package com.ucap.netcheck.utils; import java.io.File; import java.io.FileInputStream; import java.net.URL; import java.util.Properties; /** * @Title: TemplateUtil.java * @Package com.ucap.netcheck.utils * @Description: * @author * @date 2015-4-13下午9:07:58 * @version V1.0 */ public class TemplateUtil { //模板所在的位置 public static String reportTemplatePath; //模板的名稱 public static String templateFileName; static { URL resource = TemplateUtil.class.getClassLoader().getResource("template.properties"); System.out.println(resource.getPath()); File file = new File(resource.getPath()); //生成檔案輸入流 FileInputStream in = null; try { in = new FileInputStream(file); } catch (Exception e) { e.printStackTrace(); } //生成properties物件 Properties prop = new Properties(); try { prop.load(in); } catch (Exception e) { e.printStackTrace(); } reportTemplatePath = prop.getProperty("reportTemplatePath"); templateFileName = prop.getProperty("templateFileName"); } /*public static void main(String[] args) { System.out.println(TemplateUtil.reportTemplatePath); }*/ } |
配置檔案路徑截圖:
FreeMarkerUtil工具類
package com.ucap.netcheck.utils; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.HashMap; import java.util.Map; import com.thoughtworks.xstream.core.util.Base64Encoder; import freemarker.template.Configuration; import freemarker.template.Template; /** *@Title: FreeMarkerUtil.java *@Package com.ucap.netcheck.utils *@Description: FreeMarker工具類 *@authorZuoquan Tu *@date 2015-4-5下午6:02:11 *@version V1.0 */ publicclass FreeMarkerUtil { privatestatic Configurationconfiguration =null; privatestatic Map<String, Template>allTemplates =null; static { configuration =new Configuration(); configuration.setDefaultEncoding("utf-8"); //configuration.setClassForTemplateLoading(FreeMarkerUtil.class, //"../template"); try { configuration.setDirectoryForTemplateLoading( new File(TemplateUtil.reportTemplatePath)); }catch (IOException e1) { e1.printStackTrace(); } allTemplates =new HashMap<String, Template>(); try { allTemplates.put("word",configuration.getTemplate(TemplateUtil.templateFileName)); }catch (Exception e) { e.printStackTrace(); thrownew RuntimeException(e); } } public FreeMarkerUtil() { } publicstatic 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(); thrownew RuntimeException(); } return f; } publicstatic String getImageString(String fileName)throws IOException { InputStream in =null; byte[] data =null; try { in =new FileInputStream(fileName); data =newbyte[in.available()]; in.read(data); in.close(); }catch (Exception e) { e.printStackTrace(); }finally { if (in !=null){ in.close(); } } Base64Encoder encoder =new Base64Encoder(); return data !=null ? encoder.encode(data) :""; } } |
出Word的Controller層的程式碼,並解決出word時中文檔名亂碼的問題
package com.ucap.netcheck.controller; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import java.util.Map; import javax.servlet.ServletOutputStream;
|