Jacob如何获得word文档各级标题项内容

        要处理的目标文档中包含大量表格及各级标题,在解析表格内容前要求先将文档结构提取出来,也就是要将各级标题及标题编号读出来

找到了以下三种方法。

一.逐段扫描判断

 1  /**
 2        * 预处理Word文档
 3        * @param  存储标题的容器
 4        * @return
 5        */
 6       public ArrayList<Heading> pretreatWord(ArrayList<Heading>headings){
 7 word=new ActiveXComponent("Word.Application");
 8           word.setProperty("Visible", new Variant(false));
 9           documents=word.getProperty("Documents").toDispatch();
10           wordFile=Dispatch.invoke(documents, "Open", Dispatch.Method, new Object[]{filePath,new Variant(true),new Variant(true)}, new int[1]).toDispatch();
11           paragraphs=Dispatch.get(wordFile, "Paragraphs").toDispatch();
12           //段落总数
13           int paraCount=Dispatch.get(paragraphs, "Count").getInt();
14           //表格总数
15           int tableCount=Dispatch.get(tables, "Count").getInt();
16           int tableNum=1;
17           //是否能进行跳过表格操作
18           boolean canSkip=false;
19           int flag=0;
20           try{
21             for(int i=0;i<paraCount;++i){
22               Dispatch paragraph=Dispatch.call(paragraphs, "Item",new Variant(i+1)).toDispatch();
23               int outline=Dispatch.get(paragraph, "OutlineLevel").getInt();
24               //如果大纲等级为正文
25              // System.out.println("第"+(i+1)+"段");
26                          //该文档中标题最大到4级,大于4级为正文部分
27                          //当遇到正文部分,判断是否可进行跳跃
28               if(outline>4){
29                   if(canSkip){
30                      i=skipTable(tableNum,i);
31                      canSkip=false;
32                      tableNum++;
33                      continue;
34                      }
35                    else{continue;}
36                   }
37               System.out.println("******************");
38               //如果大纲等级为标题
39               Dispatch paraRange=Dispatch.get(paragraph, "Range").toDispatch();
40               //存入不同的集合
41               switch(outline){
42                 case 1: headings.add(new Heading(1,Dispatch.get(paraRange, "Text").toString()));break;
43                 case 2: headings.add(new Heading(2,Dispatch.get(paraRange, "Text").toString()));flag++;break;
44                 case 4: headings.add(new Heading(4,Dispatch.get(paraRange, "Text").toString()));break;
45                 case 5: headings.add(new Heading(5,Dispatch.get(paraRange, "Text").toString()));break;
46                 case 6: headings.add(new Heading(6,Dispatch.get(paraRange, "Text").toString()));break;
47                 default: break; 
48                 }
49               if(flag!=1){
50               canSkip=true;}
51             }
52           }catch(Exception e){
53               e.printStackTrace();
54           }finally{
55              Dispatch.call(wordFile, "Close",saveOnExit);
56               //关闭word程序
57               word.invoke("Quit",new Variant[]{});
58               System.out.println("--end--");
59           }
60           return headings;
61       }

由于word中每个表格的单元格都占用一个段落,因此如果真的逐段扫描速度会很慢(我操作的文档算上表格4000多段...)。因此当扫描到表格部分时可进行跳跃。

程序开始可获得所有表格的集合tables,当遇到大纲等级>4时,可取出一个表格,得到它占用的总段落数,进行跳跃。

二.切换大纲等级

 

 1      Dispatch aw=Dispatch.get(wordFile, "ActiveWindow").toDispatch();
 2               Dispatch view=Dispatch.get(aw, "View").toDispatch();
 3               view.put(view, "Type", 2);
 4               //由于一级标题可能被分为2行显示,因此需判断
 5               //变量extra作为偏移量。若一级标题分为两行,则偏移量为2(含"目录"项的一行);
 6               //若一级标题为一行,则偏移量为1(表示"目录"项的一行)
 7               Dispatch.call(view, "ShowHeading",1);
 8               paragraphs=Dispatch.get(wordFile, "Paragraphs").toDispatch();
 9               int extra=Dispatch.get(paragraphs, "Count").getInt();
10               view.put(view, "Type", 3);
11               view.put(view, "Type", 2);
12               //显示4级及以上的标题
13               Dispatch.call(view, "ShowHeading",4);
14               paragraphs=Dispatch.get(wordFile, "Paragraphs").toDispatch();

 

1 wdMasterView 5 主控视图。 
2 wdNormalView 1 普通视图。 
3 wdOutlineView 2 大纲视图。 
4 wdPrintPreview 4 打印预览视图。 
5 wdPrintView 3 页面视图。 
6 wdReadingView 7 阅读视图。 
7 wdWebView 6 Web 视图。

这种方法能获得标题的文字内容,但标题编号无法获得。

三.读取套用编号格式的段落

 1 Dispatch listParagraphs=Dispatch.get(wordFile, "ListParagraphs").toDispatch();
 2               int lpCount=Dispatch.get(listParagraphs, "Count").getInt();
 3 for(int i=1;i<=lpCount;++i){
 4                   Dispatch listParagraph=Dispatch.call(listParagraphs, "Item",i).toDispatch();
 5                   Dispatch listRange=Dispatch.get(listParagraph, "Range").toDispatch();
 6                   Dispatch listFormat=Dispatch.get(listRange, "ListFormat").toDispatch();
 7                   //标题编号
 8                   String listString=Dispatch.get(listFormat, "ListString").toString();
 9                   //标题文字
10                   String text=Dispatch.get(listRange, "Text").toString();
11                   text=text.replaceAll("\r", "");
12                   //大纲等级
13                   int level=Dispatch.get(listParagraph, "OutlineLevel").getInt();
14 }

这种方法能将标题内容全部取出,速度最快。缺点是如果标题编号没有套用编号格式自动生成,而是手动添加的,这样的标题段会被漏掉。

 

posted @ 2013-03-21 20:57  艾布拉布斯  阅读(5363)  评论(0编辑  收藏  举报