為了精準的擷取目錄的頁碼、内容、以及前置标題列,我才去的是逐段讀取的方式,但由于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異常");
}
}
}