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