zoukankan      html  css  js  c++  java
  • Weblogic读不到Word文件

    之前遇到一导出word文件的需求,我的做法是把对应导出内容放到一个word文件中,把其中变化的内容作为变量,然后把该word文件放在WEB-INF目录下用来作为模板。在导出时通过ServletContext的getRealPath()方法获取到作为模板的word文件的真实路径,然后针对该路径new一个FileInputStream。之后通过该word的InputStream构造一个HWPFDocument,再对里面的变量进行替换后输出到response的输出流中。大概代码如下所示:

    Java代码  
    1.    
    2. @WebServlet("/servlet/word/export.do")  
    3. public class WordExportorServlet extends HttpServlet {  
    4.    
    5.    /** 
    6.     * serialVersionUID 
    7.     */  
    8.    private static final long serialVersionUID = 1L;  
    9.    
    10.    @Override  
    11.    protected void doGet(HttpServletRequest request, HttpServletResponse response)  
    12.          throws ServletException, IOException {  
    13.       this.doPost(request, response);  
    14.    }  
    15.    
    16.    @Override  
    17.    protected void doPost(HttpServletRequest request, HttpServletResponse response)  
    18.          throws ServletException, IOException {  
    19.       String wordName = "中国人";  //假设这是我们word文档导出的文件名  
    20.       //假设这里获取到了word模板文件的相对于ServletContext根的路径  
    21.       String path = "/template.doc";  
    22.       ServletContext context = getServletContext();  
    23.       //获取word模板文件的绝对路径  
    24.       String realPath = context.getRealPath(path);  
    25.       //获取到作为模板的word文件的输入流  
    26.       InputStream is = new FileInputStream(realPath);  
    27.       HWPFDocument doc = new HWPFDocument(is);  
    28.       Range range = doc.getRange();  
    29.       //替换变量  
    30.       range.replaceText("${xx}", "xxx");  
    31.       response.setHeader("Content-Disposition", "attachment;filename=" + this.getFileName(wordName) + "");  
    32.        OutputStream output = response.getOutputStream();  
    33.        doc.write(output);  
    34.        output.close();  
    35.        is.close();  
    36.    }  
    37.     
    38.    /** 
    39.     * 把wordName以ISO-8859-1编码,同时加上“.doc”后缀进行返回。 
    40.     * @param wordName 要导出的word文件的名称 
    41.     * @return 
    42.     */  
    43.    private String getFileName(String wordName) {  
    44.       try {  
    45.          wordName = new String(wordName.getBytes("UTF-8"), "ISO-8859-1"); //防中文乱码  
    46.       } catch (UnsupportedEncodingException e) {  
    47.          e.printStackTrace();  
    48.       }  
    49.       return wordName + ".doc";  
    50.    }  
    51.    
    52. }  

           这种方式放在tomcat或runJetty上都是没有问题的,但是一旦打包放到weblogic上就不行了。原因是weblogic上访问的是未解压的包里面的内容,这个时候通过ServletContext的getRealPath()方法是获取不到模板文件基于硬盘的真实路径的,从而导致获取不到模板文件的输入流,也就不能利用它来生成新的Word文档进行导出了。解决方法是在获取模板文件对应的输入流时不要通过ServletContext获取到文件的真实路径后再通过FileInputStream去取对应的输入流,而是直接通过ServletContext的getResourceAsStream()方法来获取到ServletContext环境下的资源作为输入流。建议以后需要在Web环境下获取资源文件时都通过getResourceAsStream()来获取。

    Java代码  
    1. @WebServlet("/servlet/word/export.do")  
    2. public class WordExportorServlet extends HttpServlet {  
    3.    
    4.    /** 
    5.     * serialVersionUID 
    6.     */  
    7.    private static final long serialVersionUID = 1L;  
    8.    
    9.    @Override  
    10.    protected void doGet(HttpServletRequest request, HttpServletResponse response)  
    11.          throws ServletException, IOException {  
    12.       this.doPost(request, response);  
    13.    }  
    14.    
    15.    @Override  
    16.    protected void doPost(HttpServletRequest request, HttpServletResponse response)  
    17.          throws ServletException, IOException {  
    18.       String wordName = "中国人";  //假设这是我们word文档导出的文件名  
    19.       //假设这里获取到了word模板文件的相对于ServletContext根的路径  
    20.       String path = "/template.doc";  
    21.       ServletContext context = getServletContext();  
    22.       //获取到作为模板的word文件的输入流  
    23.       InputStream is = context.getResourceAsStream(path);  
    24.       HWPFDocument doc = new HWPFDocument(is);  
    25.       Range range = doc.getRange();  
    26.       //替换变量  
    27.       range.replaceText("${xx}", "xxx");  
    28.       response.setHeader("Content-Disposition", "attachment;filename=" + this.getFileName(wordName) + "");  
    29.         OutputStream output = response.getOutputStream();  
    30.         doc.write(output);  
    31.         output.close();  
    32.         is.close();  
    33.    }  
    34.     
    35.    /** 
    36.     * 把wordName以ISO-8859-1编码,同时加上“.doc”后缀进行返回。 
    37.     * @param wordName 要导出的word文件的名称 
    38.     * @return 
    39.     */  
    40.    private String getFileName(String wordName) {  
    41.       try {  
    42.          wordName = new String(wordName.getBytes("UTF-8"), "ISO-8859-1"); //防中文乱码  
    43.       } catch (UnsupportedEncodingException e) {  
    44.          e.printStackTrace();  
    45.       }  
    46.       return wordName + ".doc";  
    47.    }  
    48.    
    49. }  

    (注:本文是基于poi3.9所写)

  • 相关阅读:
    poj2386 Lake Counting
    poj 1852 Ants
    Luogu P2419 [USACO08JAN]牛大赛Cow Contest
    Luogu P2336 [SCOI2012]喵星球上的点名
    Luogu P2463 [SDOI2008]Sandy的卡片
    Luogu P2852 [USACO06DEC]牛奶模式Milk Patterns
    Luogu P4248 [AHOI2013]差异
    【NOI2008】志愿者招募
    Luogu P2743 [USACO5.1]乐曲主题Musical Themes
    P3723 [AH2017/HNOI2017]礼物
  • 原文地址:https://www.cnblogs.com/telwanggs/p/4933072.html
Copyright © 2011-2022 走看看