Weblogic讀不到Word文件
之前遇到一導出word文件的需求,我的做法是把對應導出內容放到一個word文件中,把其中變化的內容作爲變量,然後把該word文件放在WEB-INF目錄下用來作爲模板。在導出時通過ServletContext的getRealPath()方法獲取到作爲模板的word文件的真實路徑,然後針對該路徑new一個FileInputStream。之後通過該word的InputStream構造一個HWPFDocument,再對裏面的變量進行替換後輸出到response的輸出流中。大概代碼如下所示:
@WebServlet("/servlet/word/export.do")
public class WordExportorServlet extends HttpServlet {
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String wordName = "中國人"; //假設這是我們word文檔導出的文件名
//假設這裏獲取到了word模板文件的相對於ServletContext根的路徑
String path = "/template.doc";
ServletContext context = getServletContext();
//獲取word模板文件的絕對路徑
String realPath = context.getRealPath(path);
//獲取到作爲模板的word文件的輸入流
InputStream is = new FileInputStream(realPath);
HWPFDocument doc = new HWPFDocument(is);
Range range = doc.getRange();
//替換變量
range.replaceText("${xx}", "xxx");
response.setHeader("Content-Disposition", "attachment;filename=" + this.getFileName(wordName) + "");
OutputStream output = response.getOutputStream();
doc.write(output);
output.close();
is.close();
}
/**
* 把wordName以ISO-8859-1編碼,同時加上“.doc”後綴進行返回。
* @param wordName 要導出的word文件的名稱
* @return
*/
private String getFileName(String wordName) {
try {
wordName = new String(wordName.getBytes("UTF-8"), "ISO-8859-1"); //防中文亂碼
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return wordName + ".doc";
}
}
這種方式放在tomcat或runJetty上都是沒有問題的,但是一旦打包放到weblogic上就不行了。原因是weblogic上訪問的是未解壓的包裏面的內容,這個時候通過ServletContext的getRealPath()方法是獲取不到模板文件基於硬盤的真實路徑的,從而導致獲取不到模板文件的輸入流,也就不能利用它來生成新的Word文檔進行導出了。解決方法是在獲取模板文件對應的輸入流時不要通過ServletContext獲取到文件的真實路徑後再通過FileInputStream去取對應的輸入流,而是直接通過ServletContext的getResourceAsStream()方法來獲取到ServletContext環境下的資源作爲輸入流。建議以後需要在Web環境下獲取資源文件時都通過getResourceAsStream()來獲取。
@WebServlet("/servlet/word/export.do")
public class WordExportorServlet extends HttpServlet {
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String wordName = "中國人"; //假設這是我們word文檔導出的文件名
//假設這裏獲取到了word模板文件的相對於ServletContext根的路徑
String path = "/template.doc";
ServletContext context = getServletContext();
//獲取到作爲模板的word文件的輸入流
InputStream is = context.getResourceAsStream(path);
HWPFDocument doc = new HWPFDocument(is);
Range range = doc.getRange();
//替換變量
range.replaceText("${xx}", "xxx");
response.setHeader("Content-Disposition", "attachment;filename=" + this.getFileName(wordName) + "");
OutputStream output = response.getOutputStream();
doc.write(output);
output.close();
is.close();
}
/**
* 把wordName以ISO-8859-1編碼,同時加上“.doc”後綴進行返回。
* @param wordName 要導出的word文件的名稱
* @return
*/
private String getFileName(String wordName) {
try {
wordName = new String(wordName.getBytes("UTF-8"), "ISO-8859-1"); //防中文亂碼
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return wordName + ".doc";
}
}
(注:本文是基於poi3.9所寫)