最近項目中需要一個word導出的功能,上網查了下相關資料,基本上都是基於Jacob或者POI等組件來實現,需要相關jar以及環境配置,如果不好好研究下,不是那麼好實現,這裏介紹一種單純利用javaScript就可以實現Word導出的方法。
在項目中,我需要在流程結束時,把評審表導出成word。但在導出前用戶可以先預覽一下評審表,如下爲評審表Web頁面(到時候要導出的即爲這個頁面內容)
因爲評審表有word的模版,所以我把word模版另存爲一個html格式(主要是保留樣式),再改成jsp,然後拿這個jsp文件作爲預覽頁面的開發基礎,在此頁面進行數據獲取之後就可以通過“導出word”按鈕來進行導出了。
導出後的效果如下圖。(基本上一模一樣)
下面說說具體的代碼以及實現方式
2個主要文件:WordExporter.js和word_out.jsp(都很小,js有500行,jsp有200行)
按鈕的代碼:
<input id="export" type="button" style="position: absolute; right: 20px; top: 23px;" value="導出Word"></input>//(有個id就行了,後面爲他綁定個事件而已)
WordExporter.js:主要是構造函數、導出事件以及基本的過濾器等等。引用此插件之後,只要在業務邏輯js文件裏進行初始化構造函數即可,上代碼:
var wordputter = new $WordExporter("export",{//用於觸發事件的元素id action : "../exportWord/word_out.jsp", //必須 提交地址
wordName :question_title,//必須 導出word的名稱 默認名稱:未定義.doc
outDiv : "body", //必須 要導出代碼塊父容器對象或ID 要導出DIV
cssLinkId : "" , //非必須 有默認css 要導出word格式LinkId;
cssString :"",//非必須 有默認css,同時設置該屬性和cssLinkId,此屬性優先 顯式傳入的css內容
data:[], //非必須附帶提交到後臺處理變量列表.格式:[{name:param,value:value}...]
filter:function(dataStr){return dataStr;} //過濾器擴展接口 ,同時 必須有返回值
});
通過上面的初始化基本上就可以把web導出爲word了。如果有模版的,可以像我上面說的導出爲html 再開發,這樣會保留基本樣式。如果樣式比較少可以直接寫在cssString參數後面,如果樣式比較多的話,爲了不造成混亂,可以把那些樣式剪切到一個css文件裏,然後在word_out.jsp裏面進行通過讀寫css文件裏面的內容來實現樣式。上代碼:
//獲取部屬應用系統的絕對路徑
EnvironmentUtil environmentUtil = EnvironmentUtil.getInstance();
String storePath = environmentUtil.getAppPath()+"inms/exportWord/wordCss.css";
//實例化字符串緩衝類,大部分情況比StringBuffer快,比String拼接更快
StringBuilder builder = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(storePath)));
char[] chars = new char[4096];
int length = 0;
while (0 < (length = reader.read(chars))) {
builder.append(chars, 0, length);
}
} finally {
try {
if (reader != null) reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
這裏還有一個比較重點的就是過濾器,WordExporter.js裏面已經有一些基本的過濾了,像我在開發預覽頁面的時候遇到一些隱藏域或者一些不是隱藏域但是是一些和文檔不相關的按鈕,比如我上面說的觸發事件的按鈕,如果沒有進行過濾,在導出word之後,有值的隱藏域會把值也導出來(但這可能不是我們想要的)而遇到按鈕什麼的,就會導出爲undefined,這時候正則表達式就派上用場了,正則表達式很強大,效率也高,但是要想學好卻很難(本人菜鳥一隻,勿噴!)
舉個很簡單例子:
<input id=”test” type=”hidden” style=”left:10px;display:none;right:10px”><input>
str = str.replace(/<INPUT[^>]*type=\”hidden\”[^>]*>/ig,””)。
str = str.replace(/<INPUT[^>]*style=\”[^>]*display:none[^>]*\”[^>]*>/ig,"");
解釋:前後2個/爲正則定界符,即表達式開始與結束。[^>]:非“>”的任意字符。*:匹配前面字符0次或者多次。\”:匹配雙引號。i:忽略大小寫。g:全局匹配。
這2句就可以把隱藏類型的input元素替換成””,這樣在導出時就不會出現上面的情況了。大家也可以下載正則測試工具,挺好用的。
當然也可以用js或者就jquery來過濾,方法很多,看個人選擇了。
最後一步就是執行下載的代碼:
response.setHeader("Content-disposition","attachment;filename=\""+new String((wordName+".doc").getBytes("gb2312"),"ISO8859-1") + "\"");
作爲附件下載,文件名爲初始化時傳進來的名稱,並進行編碼設置。