不显示删除回复显示所有回复显示星级回复显示得分回复 POI "读" word 图片、表格、纯文本

转帖:http://topic.csdn.net/u/20090925/10/77f2a756-eee5-4070-96cf-f8fbdf5ca456.html

 

 

最近使用到了poi库读word文件。前提是用poi读,所以建议使用别个类库的朋友,就不要回使用别的类库的建议了。

我也想了解下poi读word到底能读到什么程度...

我始终相信有高手没有出现,我想和大家交换下想法,或者是让大家指点下思路。


我这里使用的是poi3.2 final版本。

1、首先是读文本。
  这个例子网上很多,但是读出的文本段数对吗?还有警告A property claimed to start before zero, at -512! Resetting it to zero, and hoping for the best解决了吗?问题很多....
  现在我来说下我目前的情况:

  从一开始运行这个程序开始,就遇到这个问题A property claimed to start before zero, at -512! Resetting it to zero, and hoping for the best。上网搜,没有解决,或者说是没打看懂英文。最近在Javaeye上看到一篇文章http://www.javaeye.com/topic/24352 用他的方法来做,没有了提示,而且段数还正确了。我不仅想问那些都是什么意思,还想问他是从哪里找到相关的资料的。
  前几天看到了tm-extrator封装poi的类库,使用这个来读文本,段数问题也没了,而且没有了警告提示。打开WordExtractor类看下,呵呵,和javaeye上的那位仁兄写的东西差不多,不过我还是看不懂,但是估计....呵呵。
 
  到目前为止,警告信息可以搞定,段数读出没有问题了。

2、读出的是纯文本吗?图片是用小方块代替的,超链接是用另一个小方块代替的,表格是用另另一个小方块代替的。
 
先说下如何读图片,大家是如何学会使用poi读取word里的图片的。我的经验不多,我遇到新的api的时候,我会找类库自带的一些指南,例子看下,从这里入手,开始学习。但是下载的bin包里只有一个api和非常简短的qucik-guide。几乎是没有例子。于是下载了src包,那里可以找到很多的例子。路径poi-3.2-FINAL/src/scratchpad/testcases/org/apache/poi/hwpf里可以看到读图片的例子。
    HWPFDocument docB = new HWPFDocument(new FileInputStream(docBFile));
    PicturesTable picB = docB.getPicturesTable();
    List picturesB = picB.getAllPictures();
    List里边的每一个picture.getContent()就会得到图片的字节数组,写到文件或者发给客户就可以了。

图片是可以读了,但是 不是我想要的效果吗?我要把word文件读出来,在网页上给用户显示出来。遇到图的时候给一个链接就可以。
  我不知道有什么好的解决办法。我现在虽然是勉强的解决了这个问题,但是我自己不满意,也感觉很勉强。说下我的方式:
  我把word读到string里,挨个打出每一个(int)str.charAt(i);发现了string里代表图片的小方块使用1来代替的。
呵呵,于是我把所有的那个方块 用链接替换掉了,问题也算作是勉强的解决了。我能感觉出来,其实poi里可以有更直接当方法来解决这个问题,因为在把word转换为string的时候,可以看出类库开发人员已经将图片用特殊符号替换掉了,只是我不知道怎么罢了。
 
  到目前为止,我的这个想法“我要把word文件读出来,在网页上给用户显示出来。遇到图的时候给一个链接就可以”,也算是解决了。但是word里自己画的图,艺术字,都是有问题的。

3、下一步,要解决表格问题,虽说我还可以使用处理图片的手法尝试做一下表格。但,感觉仍然不是一条正确的路子。

 

表格出了合并单元格没有很好的处理之外,表格也搞定。
但是poi读word图片还是不过准确,而且有的图片读出来java无法识别出它是一个图片。

 

转帖:http://topic.csdn.net/u/20090925/10/77f2a756-eee5-4070-96cf-f8fbdf5ca456.html

 

以下转帖自:http://blog.csdn.net/InviteSun/archive/2009/10/19/4696630.aspx

 

 

 poi 读word 处理乱码

view plaincopy to clipboardprint?
package poi.hwpf;  
public class TestHandleLuanMa {  
    public static void main(String[] args) {  
        String str = "";  
        String handledStr = handleLuanMa(str);  
//      System.out.println(handledStr);  
//      System.out.println((int)'');//20 目录前部分特殊字符  
//      System.out.println((int)'');//19 目录后部分特殊字符  
//      System.out.println((char)20);  
//      System.out.println((char)19);  
//      System.out.println((int)'');//19 图片,超链接等,前部分特殊字符  
//      System.out.println((int)'');//20 图片,超链接等,后部分特殊字符  
//      System.out.println((int)'');//21 超链接后特殊字符。  
//      System.out.println((int)'');//21 图片后特殊字符。  
//      System.out.println((int)'');//8 图片后特殊字符。  
//      System.out.println((int)'');//1 代表图片的乱码。  
    }  
      
    /** 
     * 处理str里的乱码。 
     * @param str 
     * @return 
     */ 
    public static String handleLuanMa(String str) {  
        //行结束符会影响正则表达式.的判断。不知道为什么这里还有/r/n难道poi不是安装/r/n来区别段的吗?难啊...  
        str = str.replaceAll("/r", "").replaceAll("/n", "");  
        //去掉目录乱码。  
        while (str.indexOf("HYPERLINK //l /"_Toc") != -1) {  
            str = str.substring(str.indexOf((char)20) + 1);  
            str = str.replaceFirst((char)19 + " PAGEREF _Toc.*", "");  
        }  
          
        //这个可以去掉图片,超链接等,前部分乱码。  
        while(str.matches(".*"+ (char)19 +".*" + (char)20 + ".*")) {  
            //str[j] = str[j].replaceAll(".*", "");为什么不用这种方式,因为有的一行又多个超链接。  
            String temp = str;  
            str = temp.substring(0, temp.indexOf((char)19));  
            str = str + temp.substring(temp.indexOf((char)20) + 1);  
            temp = null;  
        }  
        // 去掉图片,超链接剩余乱码。  
        while (str.indexOf((char)21) != -1) {  
            str = str.replaceAll((char)21 + "", "");  
        }  
        //去掉图片剩余乱码。  
        while(str.indexOf((char)8) != -1) {  
            str = str.replaceAll((char)8 + "","");  
        }  
        return str;  
    }  

package poi.hwpf;
public class TestHandleLuanMa {
 public static void main(String[] args) {
  String str = "";
  String handledStr = handleLuanMa(str);
//  System.out.println(handledStr);
//  System.out.println((int)'');//20 目录前部分特殊字符
//  System.out.println((int)'');//19 目录后部分特殊字符
//  System.out.println((char)20);
//  System.out.println((char)19);
//  System.out.println((int)'');//19 图片,超链接等,前部分特殊字符
//  System.out.println((int)'');//20 图片,超链接等,后部分特殊字符
//  System.out.println((int)'');//21 超链接后特殊字符。
//  System.out.println((int)'');//21 图片后特殊字符。
//  System.out.println((int)'');//8 图片后特殊字符。
//  System.out.println((int)'');//1 代表图片的乱码。
 }
 
 /**
  * 处理str里的乱码。
  * @param str
  * @return
  */
 public static String handleLuanMa(String str) {
  //行结束符会影响正则表达式.的判断。不知道为什么这里还有/r/n难道poi不是安装/r/n来区别段的吗?难啊...
  str = str.replaceAll("/r", "").replaceAll("/n", "");
  //去掉目录乱码。
  while (str.indexOf("HYPERLINK //l /"_Toc") != -1) {
   str = str.substring(str.indexOf((char)20) + 1);
   str = str.replaceFirst((char)19 + " PAGEREF _Toc.*", "");
  }
  
  //这个可以去掉图片,超链接等,前部分乱码。
  while(str.matches(".*"+ (char)19 +".*" + (char)20 + ".*")) {
   //str[j] = str[j].replaceAll(".*", "");为什么不用这种方式,因为有的一行又多个超链接。
   String temp = str;
   str = temp.substring(0, temp.indexOf((char)19));
   str = str + temp.substring(temp.indexOf((char)20) + 1);
   temp = null;
  }
  // 去掉图片,超链接剩余乱码。
  while (str.indexOf((char)21) != -1) {
   str = str.replaceAll((char)21 + "", "");
  }
  //去掉图片剩余乱码。
  while(str.indexOf((char)8) != -1) {
   str = str.replaceAll((char)8 + "","");
  }
  return str;
 }
}
 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/InviteSun/archive/2009/10/19/4696578.aspx

 

 

经过好长时间的挣扎,终于用poi基本上解决了公司的需求---读word。

这里可以读word目录,word表格,word图片。当然不只是读出来,而是将word转成html。(我们的还要将word内容进行分页显示)

我在前两篇里已经写到如何读word的表格,word的图片。至于word的目录,我是读纯文本后去特殊字符(乱码)的。去纯文本中的乱码上一篇也写到。

这里边涉及两个定位问题,一是表格位置,另一个是图片位置。

图片位置。我解决图片位置是首先读出word中的图片放到list中去,然后采用文本方式读word,读出来替换(int)1 + ""。插入图片链接。

至于这种方式是否100%奏效,我不清楚。因为我也是读到有图片word后,输出unicode码观察才知道。

ps:昨天翻阅api,读PicturesTable类,那里也是这么说的,应该是没什么问题的。

表格位置。由于是先解决的图片,而且也可以通过简单的方法拿到所有的表格,所以顺着图片的思路就下来了,但是发现用那种方式无法解决。

呵呵,原本要放弃了,但是我一想既然可以从word里拿出表格,就一定有方式定位到表格的开头。于是断点跟入源码。发现了解决方式。就是paragraph.isInTable() && paragraph.getTableLevel() == 1。

考虑到表格开始的特殊判断方式,最终决定使用看似比较笨的方式来读取纯文本。

view plaincopy to clipboardprint?
HWPFDocument hwpfDoc = new HWPFDocument(inputStream);  
Range range= hwpfDoc.getRange();  
int paraNum = range.numParagraphs();  
List tempList = new ArrayList();  
boolean tableBegin = true;  
        String str = null;  
        for (int j = 0; j < paraNum; j++) {     
            Paragraph para = range.getParagraph(j);  
            if(para.isInTable()&& tableBegin) { //在表格里,且是表格开始。  
                str = "这是一个表格标志";  
                tableBegin = false;  
            } else if(!para.isInTable()) {//不在表格里  
                tableBegin = true;  
                str = para.text();  
            }else {                      //在表格里,但不是表格开始。  
                continue;  
            }  
            str = doLuanMa(str);  
            //替换图片连接。  
            while (str.indexOf((int)1 + "") != -1) {  
                str = str.replaceFirst((int)1 + "", "<a href="/" mce_href="/""WordPicture?pic="  
                        + i + "/">图片</a>");  
                i++;  
            }  
            tempList.add(str); 
HWPFDocument hwpfDoc = new HWPFDocument(inputStream);
Range range= hwpfDoc.getRange();
int paraNum = range.numParagraphs();
List tempList = new ArrayList();
boolean tableBegin = true;
        String str = null;
        for (int j = 0; j < paraNum; j++) {  
            Paragraph para = range.getParagraph(j);
            if(para.isInTable()&& tableBegin) { //在表格里,且是表格开始。
                str = "这是一个表格标志";
                tableBegin = false;
            } else if(!para.isInTable()) {//不在表格里
                tableBegin = true;
                str = para.text();
            }else {                      //在表格里,但不是表格开始。
                continue;
            }
            str = doLuanMa(str);
            //替换图片连接。
            while (str.indexOf((int)1 + "") != -1) {
                str = str.replaceFirst((int)1 + "", "<a href="/" mce_href="/""WordPicture?pic="
                        + i + "/">图片</a>");
                i++;
            }
            tempList.add(str);


表格处理余下的思路就和图片一样了。

最后在唠叨两句,由于处理过程消耗的内存不小,没有修改Jre内存很可能出现内存溢出,这并不是程序有什么死循环。

消耗内存我也愁啊。并发访问岂不是很容易挂掉...~_~

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/InviteSun/archive/2009/10/19/4696630.aspx

阅读更多
个人分类: J2SE日志
上一篇Apache POI 解析 microsoft word 图片文字都不放过
下一篇不显示删除回复显示所有回复显示星级回复显示得分回复 POI "读" word 图片、表格、纯文本
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭