Java獲取Word文檔中修訂記錄的實(shí)現(xiàn)方法
在文檔協(xié)作與審閱場景中,Word 的“修訂”功能是一個(gè)常用工具。啟用該功能后,文檔中的所有編輯操作——包括插入、刪除、替換、格式更改——都會(huì)被記錄為修訂,并顯示修改者、修改時(shí)間等信息。本文將介紹如何使用 Java 語言,借助 Spire.Doc for Java 庫,從 Word 文檔中提取所有的修訂記錄。
一、環(huán)境準(zhǔn)備
在開始編碼之前,需要在 Java 項(xiàng)目中引入 Spire.Doc for Java 庫。
如果項(xiàng)目使用 Maven 管理依賴,可以在 pom.xml 中配置以下內(nèi)容:
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc</artifactId>
<version>14.4.9</version>
</dependency>
</dependencies>對(duì)于非 Maven 項(xiàng)目,可以手動(dòng)下載 JAR 文件并將其添加到項(xiàng)目的 classpath 中。
二、修訂獲取的基本思路
Word 文檔啟用修訂功能后,文檔中的修改會(huì)以特定格式存儲(chǔ)。獲取修訂信息的基本流程如下:
- 加載包含修訂記錄的 Word 文檔
- 遍歷文檔中的所有節(jié)(Section)
- 遍歷每個(gè)節(jié)中的文檔對(duì)象,識(shí)別段落級(jí)別的修訂
- 進(jìn)一步遍歷段落內(nèi)部的文本區(qū)域,獲取更細(xì)粒度的修訂
- 提取修訂的類型、作者等信息,并輸出或存儲(chǔ)
修訂主要分為插入修訂和刪除修訂兩種類型,需要分別進(jìn)行獲取。格式更改類修訂的獲取方式略有不同。
三、段落與文本區(qū)域級(jí)別的修訂獲取
以下代碼演示了如何從 Word 文檔中獲取段落級(jí)別和文本區(qū)域級(jí)別的插入修訂與刪除修訂。
import com.spire.doc.Document;
import com.spire.doc.DocumentObject;
import com.spire.doc.Section;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.fields.TextRange;
import com.spire.doc.formatting.revisions.EditRevision;
import java.io.FileWriter;
public class GetInsertAndDeleteRevisions {
public static void main(String[] args) throws Exception {
// 加載包含修訂記錄的 Word 文檔
Document document = new Document();
document.loadFromFile("RevisedDocument.docx");
// 存儲(chǔ)插入修訂信息的 StringBuilder
StringBuilder insertRevision = new StringBuilder();
insertRevision.append("插入修訂記錄:\n");
int insertIndex = 0;
// 存儲(chǔ)刪除修訂信息的 StringBuilder
StringBuilder deleteRevision = new StringBuilder();
deleteRevision.append("刪除修訂記錄:\n");
int deleteIndex = 0;
// 遍歷所有節(jié)
for (Section section : (Iterable<Section>) document.getSections()) {
// 遍歷節(jié)中 Body 下的所有子對(duì)象
for (DocumentObject docItem : (Iterable<DocumentObject>) section.getBody().getChildObjects()) {
if (docItem instanceof Paragraph) {
Paragraph para = (Paragraph) docItem;
// 判斷段落是否為插入修訂
if (para.isInsertRevision()) {
insertIndex++;
insertRevision.append("索引: ").append(insertIndex).append("\n");
EditRevision insertRev = para.getInsertRevision();
insertRevision.append("類型: ").append(insertRev.getType()).append("\n");
insertRevision.append("作者: ").append(insertRev.getAuthor()).append("\n");
insertRevision.append("內(nèi)容: ").append(para.getText()).append("\n\n");
}
// 判斷段落是否為刪除修訂(整個(gè)段落被刪除的情況)
if (para.isDeleteRevision()) {
deleteIndex++;
deleteRevision.append("索引: ").append(deleteIndex).append("\n");
EditRevision deleteRev = para.getDeleteRevision();
deleteRevision.append("類型: ").append(deleteRev.getType()).append("\n");
deleteRevision.append("作者: ").append(deleteRev.getAuthor()).append("\n\n");
}
// 遍歷段落內(nèi)部的子對(duì)象(TextRange 級(jí)別)
for (DocumentObject obj : (Iterable<DocumentObject>) para.getChildObjects()) {
if (obj instanceof TextRange) {
TextRange textRange = (TextRange) obj;
// 判斷文本區(qū)域是否為插入修訂
if (textRange.isInsertRevision()) {
insertIndex++;
insertRevision.append("索引: ").append(insertIndex).append("\n");
EditRevision insertRev = textRange.getInsertRevision();
insertRevision.append("類型: ").append(insertRev.getType()).append("\n");
insertRevision.append("作者: ").append(insertRev.getAuthor()).append("\n");
insertRevision.append("內(nèi)容: ").append(textRange.getText()).append("\n\n");
}
// 判斷文本區(qū)域是否為刪除修訂
if (textRange.isDeleteRevision()) {
deleteIndex++;
deleteRevision.append("索引: ").append(deleteIndex).append("\n");
EditRevision deleteRev = textRange.getDeleteRevision();
deleteRevision.append("類型: ").append(deleteRev.getType()).append("\n");
deleteRevision.append("作者: ").append(deleteRev.getAuthor()).append("\n");
deleteRevision.append("刪除內(nèi)容: ").append(textRange.getText()).append("\n\n");
}
}
}
}
}
}
// 將結(jié)果保存到文本文件
try (FileWriter writer1 = new FileWriter("InsertRevisions.txt")) {
writer1.write(insertRevision.toString());
}
try (FileWriter writer2 = new FileWriter("DeleteRevisions.txt")) {
writer2.write(deleteRevision.toString());
}
System.out.println("修訂記錄已導(dǎo)出完成");
System.out.println("插入修訂數(shù)量: " + insertIndex);
System.out.println("刪除修訂數(shù)量: " + deleteIndex);
document.close();
}
}
四、代碼邏輯說明
上述代碼的核心邏輯分為三個(gè)層次:
段落級(jí)別檢測:通過 Paragraph.isInsertRevision() 和 Paragraph.isDeleteRevision() 方法判斷整個(gè)段落是否為修訂內(nèi)容。如果是,則使用 getInsertRevision() 或 getDeleteRevision() 獲取修訂對(duì)象,進(jìn)而得到修訂類型(getType())和作者(getAuthor())。
文本區(qū)域檢測:段落內(nèi)部的文本區(qū)域也需要單獨(dú)遍歷,因?yàn)樾抻喛赡馨l(fā)生在段落內(nèi)部的局部區(qū)域(而非整段)。通過 TextRange.isInsertRevision() 和 TextRange.isDeleteRevision() 方法進(jìn)行判斷。
修訂類型區(qū)分:插入修訂類型的枚舉值為 Insertion,刪除修訂類型的枚舉值為 Deletion。
五、獲取格式更改修訂
對(duì)于格式更改類的修訂(如字體、字號(hào)、顏色的修改),上述基礎(chǔ)代碼無法直接獲取。較新版本的 API 提供了 RevisionInfoCollection 來獲取更全面的修訂信息:
import com.spire.doc.Document;
import com.spire.doc.revision.RevisionInfo;
import com.spire.doc.revision.RevisionType;
public class GetAllRevisionsWithFormat {
public static void main(String[] args) {
Document document = new Document();
document.loadFromFile("RevisedDocument.docx");
com.spire.doc.revision.RevisionInfoCollection revisions = document.getRevisionInfos();
for (RevisionInfo revision : (Iterable<RevisionInfo>) revisions) {
System.out.println("修訂類型: " + revision.getRevisionType());
System.out.println("作者: " + revision.getAuthor());
System.out.println("時(shí)間: " + revision.getDateTime());
if (revision.getRevisionType() == RevisionType.Format_Change) {
System.out.println("該條修訂為格式更改類型");
}
}
document.close();
}
}
六、注意事項(xiàng)
- 修訂與批注的區(qū)別:修訂記錄的是對(duì)文檔內(nèi)容的實(shí)際修改(插入、刪除、格式更改),而批注是附加的注釋信息。兩者是不同的概念,獲取方式也有所不同。
- 版本兼容性:獲取格式更改修訂的功能在較新版本中才得到支持。如果使用的是較早版本,格式更改可能無法被正確識(shí)別。建議查閱所使用的版本對(duì)應(yīng)的 API 文檔。
- 性能考慮:對(duì)于包含大量修訂的長文檔,遍歷全部修訂可能需要一定時(shí)間。建議在需要完整修訂記錄時(shí)使用完整遍歷,若僅需特定類型的修訂,可以在遍歷過程中增加篩選條件。
- 文檔格式:上述方法主要適用于
.docx格式的文檔。對(duì)于舊版.doc格式,修訂信息的讀取可能存在兼容性問題,建議提前轉(zhuǎn)換格式。
總結(jié)
通過上述示例可以看出,使用 Java 獲取 Word 文檔中的修訂記錄,主要涉及文檔加載、遍歷段落和文本區(qū)域、判斷修訂類型并提取信息等步驟。根據(jù)需求的不同,可以選擇獲取段落級(jí)別的修訂,也可以進(jìn)一步獲取文本區(qū)域級(jí)別的細(xì)粒度修訂。對(duì)于格式更改類的修訂,則需要使用較新版本的 API 通過 RevisionInfoCollection 進(jìn)行獲取。這些方法可以應(yīng)用于文檔審閱、版本對(duì)比、修改追蹤等業(yè)務(wù)場景。在實(shí)際項(xiàng)目開發(fā)中,建議根據(jù)文檔的復(fù)雜程度和修訂類型需求,選擇合適的遍歷粒度和 API 版本,以確保獲取到的修訂信息完整且準(zhǔn)確。此外,對(duì)于需要批量處理多個(gè)文檔或生成修訂報(bào)告的情況,可以在現(xiàn)有代碼基礎(chǔ)上進(jìn)一步封裝,形成可復(fù)用的工具方法。
以上就是Java獲取Word文檔中修訂記錄的實(shí)現(xiàn)方法的詳細(xì)內(nèi)容,更多關(guān)于Java獲取Word文檔的修訂記錄的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
RocketMQ的消費(fèi)者類型與最佳實(shí)踐詳解
這篇文章主要介紹了RocketMQ的消費(fèi)者類型與最佳實(shí)踐詳解,在?RocketMQ?5.0?中,更加強(qiáng)調(diào)了客戶端類型的概念,尤其是消費(fèi)者類型,為了滿足多樣的?RocketMQ?中一共有三種不同的消費(fèi)者類型,分別是?PushConsumer、SimpleConsumer?和?PullConsumer,需要的朋友可以參考下2023-10-10
關(guān)于使用swagger整合springMVC的方法
在平時(shí)開發(fā)寫接口文檔的工作時(shí),一般都是word文檔,帶來書寫麻煩、維護(hù)麻煩的問題,比如改了源代碼忘了更新文檔、解釋不明確帶來歧義、無法在線嘗試等等,swagger可以有效解決這類問題,需要的朋友可以參考下2023-04-04
Java實(shí)現(xiàn)微信登錄并獲取用戶信息功能(開發(fā)流程)
這篇文章主要介紹了Java實(shí)現(xiàn)微信登錄并獲取用戶信息功能(開發(fā)流程),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07
關(guān)于weblogic部署Java項(xiàng)目的包沖突問題的解決
這篇文章主要介紹了關(guān)于weblogic部署Java項(xiàng)目的包沖突問題的解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01
Spring?MVC文件請(qǐng)求處理MultipartResolver詳解
這篇文章主要介紹了Spring?MVC文件請(qǐng)求處理詳解:MultipartResolver,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11
java實(shí)現(xiàn)網(wǎng)頁驗(yàn)證碼功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)網(wǎng)頁驗(yàn)證碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10

