POI生成Web版Word文件

 

POI生成WebWord文件

 

1       通过URL的输入流实现

2       直接把Html文本写入到Word文件 

       所谓的使用POI生成Web版Word文件是指利用POI将Html代码插入到Word文件中使之呈现出Html代码对应的Web样式。下面将介绍两种方法来实现这一功能。

 

1       通过URL的输入流实现

       通过URL实现的方式主要分为以下几步:

  1. 根据对应资源的Http路径构建一个URL。
  2. 获取URL对应的输入流。
  3. 构建一个默认的POIFSFileSystem。
  4. 通过构建的POIFSFileSystem和URL对应的输入流创建一个WordDocument。
  5. 把构建的POIFSFileSystem写入到对应的输出流。

       经过上述五步,我们就可以把一个Http路径对应的内容写入到一个Word输出流中了。下面是一个把百度主页写入到一个本地Word文件中的示例:

Java代码  
  1. /** 
  2.  * Html到Word 
  3.  * @throws Exception 
  4.  */  
  5. @org.junit.Test  
  6. public void htmlToWord() throws Exception {  
  7.    URL url = new URL("http://www.baidu.com");  
  8.    InputStream is = url.openStream();  
  9.    OutputStream os = new FileOutputStream("d:\\baidu.doc");  
  10.    this.inputStreamToWord(is, os);  
  11. }  
  12.   
  13. /** 
  14.  * 把is写入到对应的word输出流os中 
  15.  * 不考虑异常的捕获,直接抛出 
  16.  * @param is 
  17.  * @param os 
  18.  * @throws IOException 
  19.  */  
  20. private void inputStreamToWord(InputStream is, OutputStream os) throws IOException {  
  21.    POIFSFileSystem fs = new POIFSFileSystem();  
  22.    //对应于org.apache.poi.hdf.extractor.WordDocument  
  23.    fs.createDocument(is, "WordDocument");  
  24.    fs.writeFilesystem(os);  
  25.    os.close();  
  26.    is.close();  
  27. }  

 

       使用这种方式有一个不好的地方是你不一定有访问对应URL的权限,这个时候我们写入到Word文件的内容可能就是错误的。打个简单的比方,某一个URL需要进行登录了之后才能访问,这个时候你直接使用URL去对它进行访问可能会被系统引导到登录页面,如果这个时候把其对应的输入流写入到目标Word文件中,那么我们得到的Word文件的内容将是系统的登录页面,而不是目标URL原本应该对应的资源。有朋友可能会说了,这好办,我们可以使用对应用户信息来进行一次登录,之后再获取对应URL对应的资源。这样也可以实现。这里我要介绍第二种方式。

 

2       直接把Html文本写入到Word文件

       曾经遇到这么一个需求,在某一个文件的查看页面,有一个导出为Word文件的功能。相信这是一个比较常见的需求。我当时的一个想法是既然文件的内容都已经在页面上了,那么我直接拿着文件的内容写入到Word文件不就完了。我当时是这么做的:

  1. 获取查看页面的body内容和引用的css文件路径传入到后台。
  2. 把对应css文件的内容读取出来。
  3. 利用body内容和css文件的内容组成一个标准格式的Html文本。
  4. 根据组合后的Html文本生成对应的ByteArrayInputStream。
  5. 构建一个默认的POIFSFileSystem,并利用它和生成的ByteArrayInputStream创建一个WordDocument。
  6. 把构建的POIFSFileSystem写入到对应的输出流。

       经过上面这几步之后我们就可以把Html格式的文本写入到Word文件中,同时使生成的Word文件呈现出对应的Web样式。需要注意的是原本Html文件中引用到的css文件的内容需要放到生成的Word文件中,生成后的Word文件才会呈现出对应的Web样式。下面是一个针对于该方式的一个简单例子:

Java代码  
  1. @org.junit.Test  
  2. public void htmlToWord2() throws Exception {  
  3.    InputStream bodyIs = new FileInputStream("d:\\1.html");  
  4.    InputStream cssIs = new FileInputStream("d:\\1.css");  
  5.    String body = this.getContent(bodyIs);  
  6.    String css = this.getContent(cssIs);  
  7.    //拼一个标准的HTML格式文档  
  8.    String content = "<html><head><style>" + css + "</style></head><body>" + body + "</body></html>";  
  9.    InputStream is = new ByteArrayInputStream(content.getBytes("GBK"));  
  10.    OutputStream os = new FileOutputStream("d:\\1.doc");  
  11.    this.inputStreamToWord(is, os);  
  12. }  
  13.   
  14. /** 
  15.  * 把is写入到对应的word输出流os中 
  16.  * 不考虑异常的捕获,直接抛出 
  17.  * @param is 
  18.  * @param os 
  19.  * @throws IOException 
  20.  */  
  21. private void inputStreamToWord(InputStream is, OutputStream os) throws IOException {  
  22.    POIFSFileSystem fs = new POIFSFileSystem();  
  23.    //对应于org.apache.poi.hdf.extractor.WordDocument  
  24.    fs.createDocument(is, "WordDocument");  
  25.    fs.writeFilesystem(os);  
  26.    os.close();  
  27.    is.close();  
  28. }  
  29.   
  30. /** 
  31.  * 把输入流里面的内容以UTF-8编码当文本取出。 
  32.  * 不考虑异常,直接抛出 
  33.  * @param ises 
  34.  * @return 
  35.  * @throws IOException 
  36.  */  
  37. private String getContent(InputStream... ises) throws IOException {  
  38.    if (ises != null) {  
  39.       StringBuilder result = new StringBuilder();  
  40.       BufferedReader br;  
  41.       String line;  
  42.       for (InputStream is : ises) {  
  43.          br = new BufferedReader(new InputStreamReader(is, "UTF-8"));  
  44.          while ((line=br.readLine()) != null) {  
  45.              result.append(line);  
  46.          }  
  47.       }  
  48.       return result.toString();  
  49.    }  
  50.    returnnull;  
  51. }  

  

       其中,文件1.html对应的内容如下:

Html代码  
  1. <table cellpadding="5" style="border-collapse: collapse;">  
  2.        <tr>  
  3.               <td>中文</td>  
  4.               <td>中文</td>  
  5.               <td>中文</td>  
  6.               <td>中文</td>  
  7.        </tr>  
  8.        <tr>  
  9.               <td>中文</td>  
  10.               <td>中文</td>  
  11.               <td>中文</td>  
  12.               <td>中文</td>  
  13.        </tr>  
  14. </table>  

  

       文件1.css对应的内容如下:

Css代码  
  1. table {  
  2.        border: 1px solid blue;  
  3.        width: 800px;  
  4.        height: 500px;  
  5.        text-align: center;  
  6. }  
  7. td {  
  8.        width: 200px;  
  9.        border: 1px solid blue;  
  10. }  

  

       最后生成的Word文件效果如下:



 

附注

       上述例子是在Maven项目中做的,主要引用的依赖项有:

Xml代码  
  1. <dependency>  
  2.    <groupId>org.apache.poi</groupId>  
  3.    <artifactId>poi-scratchpad</artifactId>  
  4.    <version>3.9</version>  
  5. </dependency>  
  6. <dependency>  
  7.    <groupId>junit</groupId>  
  8.    <artifactId>junit</artifactId>  
  9.    <version>4.11</version>  
  10. </dependency>  
posted @ 2015-11-03 14:05  疯子110  阅读(1091)  评论(0编辑  收藏  举报