天天看點

JACOB 完整讀取文檔大綱(目錄)(各級标題項内容)并跳過表格 提高效率

為了精準的擷取目錄的頁碼、内容、以及前置标題列,我才去的是逐段讀取的方式,但由于word中每個表格的單元格都占用一個段落,是以如果真的逐段掃描速度會很慢。是以可以在讀取之前把表格給幹掉。

  • 擷取所有表格
//所有表格
Dispatch tables = Dispatch.get(doc, "Tables").toDispatch(); 
//擷取表格總數
int tableCount = Dispatch.get(tables, "Count").getInt();
           
  • 删除所有表格

    在這裡我做的是打開文檔和讀取大綱操作,不會對其進行儲存·操作,是以結束後對文檔内容本身是不會有影響。

for (int i =  ; i < tableCount ; i++) {
    table = Dispatch.call(tables, "Item", new Variant()).toDispatch();
    Dispatch.call(table, "Delete");
}
           
完整代碼如下
  • 在這裡要解釋一下為什麼要從後往前讀。
  • 因為我這裡需求是需要讀取文檔目錄并有相應的目錄結構(層次關系,比如說1 下面有1.1 和1.2 ,1.1下面有1.1.1),并轉換成json字元串發送到移動端,移動端通過json字元串展示目錄,并能通過頁碼索引到對應的位置。
  • 是以這裡我就沒改動讀取方向了,有問題可以多多交流,JACOB坑太多了,可以多交流交流。
public class ReadWordOrWPSBookMarks {
    /**
     * 讀取word/wps文檔的大綱
     * @param filename  要打開的文檔的目錄(帶檔案名)
     * @param strChoose 打開方式  Microsoft Word: 2   WPS: 3
     */
    public static void readBookMarksByWordOrWps(String filename, String strChoose) {
        ActiveXComponent app = null;
        Dispatch doc = null;
        try {
            //microsoft Office 方式
            if ( "2".equals(strChoose) ) {
                app = new ActiveXComponent("Word.Application");
            }
            //WPS 方式
            if ( "3".equals(strChoose) ) {
                app = new ActiveXComponent("KWPS.Application");
            }
            app.setProperty("Visible", new Variant(false));
            Dispatch docs = app.getProperty("Documents").toDispatch();
            doc = Dispatch.call(docs, "Open", filename).toDispatch();

            //所有表格
            Dispatch tables = Dispatch.get(doc, "Tables").toDispatch(); 
            //擷取表格總數
            int tableCount = Dispatch.get(tables, "Count").getInt();
            System.out.println("表格數" + tableCount);
            Dispatch table = null;
            //删除所有表格(删除第一個表格後,第二個表格會變成第一表格)
            for (int i =  ; i < tableCount ; i++) {
                table = Dispatch.call(tables, "Item", new Variant()).toDispatch();
                Dispatch.call(table, "Delete");
            }

            // 擷取大綱清單
            Dispatch paragraphs = Dispatch.get(doc, "Paragraphs").toDispatch();
            int count = Dispatch.get(paragraphs, "Count").getInt();//大綱數量
            //目前大綱等級層次
            int tempLevel = ;
            //從後往前擷取大綱
            for (int i = count -  ; i >= ; i--) {
                //目前大綱項
                Dispatch paragraph = Dispatch.call(paragraphs, "Item", new Variant(i+)).toDispatch();
                //大綱等級
                int level = Dispatch.get(paragraph, "OutlineLevel").getInt();
                Dispatch paragraphRange  = Dispatch.get(paragraph, "Range").toDispatch();
                //一般目錄不會超過4級,4級往後是内容,可以跳過
                if ( level <=  ) {
                    if ( tempLevel ==  ) {
                        tempLevel = level ;
                    }
                    //标題編号
                    Dispatch listFormat = Dispatch.get(paragraphRange, "ListFormat").toDispatch();
                    String listString = "";
                    try {
                        listString = Dispatch.get(listFormat, "ListString").toString();
                    } catch (Exception e) {
                        System.out.println("沒有ListForat屬性的标題:" + Dispatch.get(paragraphRange, "Text").toString().replaceAll("\\\r|\\\f", ""));
                    }
                    //标題
                    String text = Dispatch.get(paragraphRange, "Text").toString().replaceAll("\\\r|\\\f", "") ;
                    //可能會存在一些為空的隐藏的大綱,text是為空的
                    if (text == null || ("").equals(text)) {
                        continue;
                    }
                    text = listString + text;
                    //索引的頁碼
                    int page = Dispatch.call(paragraphRange, "information", ).getInt() ;

                    System.out.println("text:"+text + "   page:"+page + "   level:"+level);
                }
            }
        } catch (Exception e) {
            System.out.println(" 大綱擷取失敗" , e);
        } finally {
            try {
                Dispatch.call(doc, "Close", false);
                if (app != null){
                    app.invoke("Quit", new Variant[] {});
                    app = null;
                }   
            } catch (Exception e2) {
                System.out.println("關閉ActiveXComponent異常");
            }
        }
    }
           

繼續閱讀