簡體   English   中英

以編程方式比較word文檔

[英]programmatically comparing word documents

我需要比較兩個office文件,在這個例子中是兩個word文檔,並提供一個差異,這有點類似於SVN中顯示的內容。不是那種程度,但至少能夠突出差異。

我嘗試使用辦公室 COM dll 並得到了這么遠..

object fileToOpen = (object)@"D:\doc1.docx";
string fileToCompare = @"D:\doc2.docx";

WRD.Application WA = new WRD.Application();

Document wordDoc = null;

wordDoc = WA.Documents.Open(ref fileToOpen, Type.Missing, Type.Missing, Type.Missing, Type.Missing,      Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
wordDoc.Compare(fileToCompare, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

關於如何進一步進行的任何提示? 這將是一個具有很多點擊率的 web 應用程序。 使用辦公室 com object 到 go 的方式是否正確,或者還有其他我可以看的東西嗎?

您應該使用Document類來比較文件,並在Word文檔中打開結果。

using OfficeWord = Microsoft.Office.Interop.Word;

object fileToOpen = (object)@"D:\doc1.docx";
string fileToCompare = @"D:\doc2.docx";

var app = Global.OfficeFile.WordApp;

object readOnly = false;
object AddToRecent = false;
object Visible = false;

OfficeWord.Document docZero = app.Documents.Open(fileToOpen, ref missing, ref readOnly, ref AddToRecent, Visible: ref Visible);

docZero.Final = false;
docZero.TrackRevisions = true;
docZero.ShowRevisions = true;
docZero.PrintRevisions = true;

//the OfficeWord.WdCompareTargetNew defines a new file, you can change this valid value to change how word will open the document
docZero.Compare(fileToCompare, missing, OfficeWord.WdCompareTarget.wdCompareTargetNew, true, false, false, false, false);

所以我的要求是我必須使用.Net lib並且我想避免處理實際文件但是使用流。

ZipArchive在System.IO.Compressed中

我做了很多,並且很好地使用了來自.Net的ZipArchive並在跳過.rels文件時比較內容,因為它似乎是在每個文件創建時隨機生成的。 這是我的片段:

    private static bool AreWordFilesSame(byte[] wordA, byte[] wordB)
    {
        using (var streamA = new MemoryStream(wordA))
        using (var streamB = new MemoryStream(wordB))
        using (var zipA = new ZipArchive(streamA))
        using (var zipB = new ZipArchive(streamB))
        {
            streamA.Seek(0, SeekOrigin.Begin);
            streamB.Seek(0, SeekOrigin.Begin);

            for(int i = 0; i < zipA.Entries.Count; ++i)
            {
                Assert.AreEqual(zipA.Entries[i].Name, zipB.Entries[i].Name);

                if (zipA.Entries[i].Name.EndsWith(".rels")) //These are some weird word files with autogenerated hashes
                {
                    continue;
                }

                var streamFromA = zipA.Entries[i].Open();
                var streamFromB = zipB.Entries[i].Open();

                using (var readerA = new StreamReader(streamFromA))
                using (var readerB = new StreamReader(streamFromB))
                {
                    var bytesA = readerA.ReadToEnd();
                    var bytesB = readerB.ReadToEnd();
                    if (bytesA != bytesB || bytesA.Length == 0)
                    {
                        return false;
                    }
                }
            }

            return true;
        }
    }

我同意約瑟夫關於差異的字符串。 我還推薦一個專用的diffing引擎(這里有幾個: .NET的任何不錯的文本差異/合並引擎? ),它可以幫助你避免一些正常的差異陷阱。

對於服務器上的解決方案,或者沒有Word的安裝運行和使用COM的工具,你可以使用的WmlComparer組件XmlPowerTools

文檔有點受限,但這是一個示例用法:

var expected = File.ReadAllBytes(@"c:\expected.docx");
var actual = File.ReadAllBytes(@"c:\result.docx");
var expectedresult = new WmlDocument("expected.docx", expected);
var actualDocument = new WmlDocument("result.docx", actual);
var comparisonSettings = new WmlComparerSettings();

var comparisonResults = WmlComparer.Compare(expectedresult, actualDocument, comparisonSettings);
var revisions = WmlComparer.GetRevisions(comparisonResults, comparisonSettings);

這將顯示兩個文件之間的差異。

這個 function 讓您可以比較兩個文檔以及 C# 中文檔的兩個版本。

public async Task<object> compare()
        {
            Word.Application wordApp = new Word.Application();
            wordApp.Visible = false;
            object wordTrue = (object)true;
            object wordFalse = (object)false;
            object fileToOpen = @"Give your file path here";
            object missing = Type.Missing;
            Word.Document doc1 = wordApp.Documents.Open(ref fileToOpen,
                   ref missing, ref wordFalse, ref wordFalse, ref missing,
                   ref missing, ref missing, ref missing, ref missing,
                   ref missing, ref missing, ref wordTrue, ref missing,
                   ref missing, ref missing, ref missing);

            object fileToOpen1 = @"Give your file path here";
            Word.Document doc2 = wordApp.Documents.Open(ref fileToOpen1,
                   ref missing, ref wordFalse, ref wordFalse, ref missing,
                   ref missing, ref missing, ref missing, ref missing,
                   ref missing, ref missing, ref missing, ref missing,
            ref missing, ref missing, ref missing);

            Word.Document doc = wordApp.CompareDocuments(doc1, doc2, Word.WdCompareDestination.wdCompareDestinationNew,
                                Word.WdGranularity.wdGranularityWordLevel,
                                true, true, true, true, true, true, true, true, true, true, "", true);

            doc1.Close(ref missing, ref missing, ref missing);
            doc2.Close(ref missing, ref missing, ref missing);

            // This Hides both original and revised documents you can change it according to your use case.
            wordApp.ActiveWindow.ShowSourceDocuments = WdShowSourceDocuments.wdShowSourceDocumentsNone;

            wordApp.Visible = true;
            doc.Activate();

            return Ok("Compared Successfully");
        }

你應該把文檔解壓縮成字符串然后區分它。

你只關心文本的變化,而不是格式化嗎?

要進行Word文檔之間的比較,您需要

  1. 用於操作Word文檔的庫,例如從Word文件中讀取段落,文本,表格等。 您可以嘗試使用Office Interop,OpenXML或Aspose.Words for .NET
  2. 對從兩個Word文檔中檢索到的文本進行實際比較的算法/庫。 您可以自己編寫或使用像DiffMatchPatch或類似的庫。

這個問題很老,現在有更多的解決方案,如GroupDocs Compare可用。

Aspose.Words for .NET的文檔比較是一個開源展示項目,它使用Aspose.Words和DiffMatchPatch進行比較。

我在Aspose擔任開發者布道者。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM