最近用java開發一個科技項目信息管理系統,裏面有一個根據項目申請書的模板填寫項目申報信息的功能,有一個科技項目申請書word導出功能。html
已有的實現方式:採用標準的jsp模板輸出實現,簡單地說,就是把數據渲染進jsp頁面,而後將此頁面另存爲doc文檔,從而達到word導出效果。可是存在如下幾個問題:java
(1) 因爲導出的html網頁格式,打開word後,默認顯示的視圖模式爲WEB版式視圖;數據庫
(2) 修改word文檔後,會新增一個相關聯的文件夾,word的html中會引用這個文件夾中的資源,好比樣式、圖片、主題等;這樣若是隻轉移word文檔自己,會形成找不到相關聯的資源。服務器
(3) 因爲咱們有些字段內容是採用富文本編輯器(百度的UEditor)填寫的,裏面有附件的上傳(主要是圖片)。針對圖片,HTML的img標籤有一個src的屬性,這個src是服務器的圖片資源路徑。這個若是要顯示這個圖片的話,客戶的機器必需要保證聯網,這樣形成word不能離線存檔。jsp
(4) 這樣導出的word打印出來的效果也是一塌糊塗,無法接受。編輯器
正由於有這些問題,急需尋找另一種解決方案。編碼
在網上查找資料,總結出兩種比較可行的方案。3d
(1) 製做word模板,導出成mht文件(單頁面網頁格式),而後往模板裏渲染數據,最終生成word文檔。xml
(2) 製做word模板,導出成xml文件,而後往模板裏渲染數據,最終生成word文檔。htm
這兩種都是採用模板的思想,模板的製做比較加單,比用poi去組織word格式簡單的不少不少。惟一的不一樣點在於導出文件的格式不一樣,一個是mht文件,一個是xml文件。考慮到本項目中的項目申報書個別字段採用了富文本編輯器實現,保存進數據庫中是html格式的字符串,因此咱們採用第一種方案,即經過mht文件來實現。
1. mht文件的文件存儲結構分析
打開客戶提供的項目申報書模板文件,如,選擇「另存爲-》其餘格式」菜單,選擇「保存爲mht文件(單網頁文件)」,以下圖所示:
保存後,用文本編輯器(UltraEdit或Sublime等)打開。打開後,有一些規律可循,具體關鍵的要點以下:
(1) mht文件的內容採用3Dus-ascii編碼格式,裏面的中文字符串都被編碼成不可讀的內容;
(2) mht是單網頁文件,裏面內嵌了不少資源內容,特別要注意的是圖片資源。咱們查找「image」,會找到「image001」」image002」。。。。等相關的匹配值。針對每一個圖片(好比image002)有三個地方出現。
第一,在Html的<v:shape>標籤中,以下
第二,在內嵌資源塊中,對圖片的內容採用base64編碼。具體格式以下
第三,在文件的末尾部,有個<xml>標籤,裏面有個HRef屬性標識,具體內容以下:
2. 具體的實現思路
(1) 製做word模板,用特定的模板引擎(咱們用的freeMarker)的語法去生成佔位符,而後導出出mht文件;
(2) 組織、處理數據,而後利用模板引擎去渲染模板。
(3) 將渲染後的結果保存爲doc文件。
最重要的是第2個步驟中的處理數據。根據mht文件的格式要求,主要須要處理如下幾個地方。
(1) 將字符串類型的數據編碼成3Dus-ascii格式;
(2) 對富文本數據進行處理。主要是上述三個地方的處理,其一,對富文本的html中的img進行處理,轉換成<v:shape>標籤格式;其二,取出img的實際存儲位置,將圖片的內容按照base64進行編碼,並將編碼後內容添加進對應的位置;其三,在mht文件的末尾的xml標籤中加入相關資源引入字符串。
1. 根據模板引擎的語法規則填入佔位符製做word模板,保存爲mht文件。
另存爲mht文件後,需用文本編輯器打開,主要綁定語句不能斷,好比${projectSbInfo.xmnamecn}另存爲mht文件後,可能成了${projectSbInfo.=
xmnamecn}這個格式,需手動再修改一下。
另外還需在mht文件中插入圖片資源的base64及xml 的href引用的佔位。以下圖
2. 組織、處理數據
通常的屬性數據組織起來簡單,無非就是從數據庫中獲取,處理也簡單。這裏要特別注意如下數據的處理。
(1) html中image元素的處理。處理流程以下:
(2) 因爲mht文件是採用的是「us-ascii」編碼,屬性後面都必須帶有3D前綴。因此包含html內容的需進行一下替換操做。
3.渲染模板,而後另存了word格式便可。
相關源代碼:http://files.cnblogs.com/files/liaofeifight/word.rar