以编程方式比较word文档
我需要比较两个office文档,在这里是两个word文档,并提供一个区别,它与SVN中显示的有些类似。不是那样,但至少能够突出差异。以编程方式比较word文档
我试着用办公室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对象的正确方式,还是有任何其他的事情我可以看看?
我同意约瑟夫关于区分字符串。我还会推荐一个专用的差异引擎(在这里找到几个引擎:Any decent text diff/merge engine for .NET?),这可以帮助您避免差异中的一些常见缺陷。
您应该使用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);
Hi @ anderson-rissardi!比较方法实际上做了什么?它是否在某处打开某个文件?因为我在单元测试中运行时没有看到任何东西。我该如何得到结果,因为该方法返回无效? – ditoslav
Hi @ditoslav。它会打开一个新文件。这是Word中的'Copare'按钮。打开MS Word - > Tab'Review' - > Button'Compare'。是相同的功能,它生成的新文档。您必须保存这个新文档。 –
要做到Word文档之间的比较,你需要
- 库来操纵Word文档,例如从Word文件中读取段落,文本,表格等。您可以尝试Office Interop,OpenXML或Aspose.Words for .NET。
- 用于对从两个Word文档检索到的文本进行实际比较的算法/库。您可以自己编写或使用像DiffMatchPatch或类似的库。
这个问题很旧,现在有更多的解决方案,如GroupDocs Compare可用。
Document Comparison by Aspose.Words for .NET是一个开源展示项目,使用Aspose.Words和DiffMatchPatch进行比较。
我在Aspose作为开发者传播者工作。
所以我的要求是,我不得不使用.Net库,我想避免在实际文件上工作,但使用流。
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;
}
}
对于服务器上的解决方案,或者没有Word的安装运行和使用COM的工具,你可以使用的XmlPowerTools的WmlComparer组件。
的documentation是有点有限的,但这里有一个例子用法:
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);
它会告诉你这两个文件之间的差异。
感兴趣的是,SVN如何显示两个二进制文件之间的差异? (AFAIK'docx'是一个zip档案格式) – sll
选择有问题的两个文件,通常在客户端的同一文件夹中。你已经安装了tortoiseSVN。你右键点击并进入TortoiseSVN菜单并选择Diff ... – user20358
是的,我知道如何做到这一点,但你会看到哪些区别,它有什么意义吗? – sll