программно сравнивая текстовые документы - PullRequest
6 голосов
/ 23 ноября 2011

Мне нужно сравнить два офисных документа, в данном случае документы из двух слов, и представить разницу, которая чем-то похожа на ту, что показана в SVN. Не в такой степени, но, по крайней мере, сможет выделить различия.

Я попытался использовать офисную библиотеку COM и получил это далеко ..

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);

Какие-нибудь советы о том, как действовать дальше? Это будет веб-приложение с большим количеством просмотров. Является ли использование объекта office com правильным путем или есть другие вещи, на которые я могу посмотреть?

Ответы [ 6 ]

4 голосов
/ 10 ноября 2014

Вы должны использовать класс 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);
1 голос
/ 20 октября 2017

Итак, мои требования заключались в том, что мне пришлось использовать .Net lib, и я хотел избежать работы с реальными файлами, но работать с потоками.

ZipArchive находится в System.IO.Compressed

То, что я сделал и получилось довольно неплохо, - это использование ZipArchive из .Net и сравнение содержимого при пропуске файла .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;
        }
    }
1 голос
/ 23 ноября 2011

Я согласен с Джозефом в том, что касается определения нити. Я бы также порекомендовал специализированный механизм сравнения (некоторые из них найдены здесь: Любой приличный механизм преобразования текста / слияния для .NET? ), который может помочь вам избежать некоторых обычных ловушек в анализе.

0 голосов
/ 23 ноября 2017

Для решения на сервере или без установки 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);

, который покажет вам различия между двумя документами.

0 голосов
/ 09 марта 2015

Для сравнения документов Word вам нужно

  1. Библиотека для работы с документом Word, например, читать абзацы, текст, таблицы и т. д. из файла Word. Вы можете попробовать Office Interop, OpenXML или Aspose.Words для .NET .
  2. Алгоритм / библиотека для фактического сравнения текста, извлеченного из обоих документов Word. Вы можете написать свою собственную или использовать библиотеку, например DiffMatchPatch или аналогичную.

Этот вопрос старый, теперь есть и другие решения, например GroupDocs Compare доступны.

Сравнение документов по Aspose.Words для .NET - это демонстрационный проект с открытым исходным кодом, в котором для сравнения используются Aspose.Words и DiffMatchPatch.

Я работаю в Aspose как евангелист разработчика.

0 голосов
/ 23 ноября 2011

Вы действительно должны извлечь документ в строку и добавить его.

Вас интересуют только текстовые изменения, а не форматирование, верно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...