2011-11-23 11 views
5

Ho bisogno di confrontare due documenti dell'ufficio, in questo caso due documenti word e fornire una differenza, che è in qualche modo simile a ciò che è mostrato in SVN. Non fino a quel punto, ma almeno in grado di evidenziare le differenze.confrontando a livello di codice i documenti word

Ho provato ad utilizzare la dll ufficio COM ed ho ottenuto fino a questo punto ..

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

Eventuali suggerimenti su come procedere ulteriormente? Questa sarà un'applicazione web che ha molti successi. Sta usando l'oggetto office com la strada giusta da percorrere, o ci sono altre cose che posso guardare?

+0

Proprio di interesse, come SVN mostra difefrence tra due file binari? (AFAIK 'docx' è un formato di archivio zip) – sll

+0

seleziona i due file in questione, di solito nella stessa cartella sul lato client. Hai installato tortoiseSVN. Fai clic con il pulsante destro del mouse e vai al menu TortoiseSVN e seleziona Diff ... – user20358

+0

Sì, lo so come farlo, ma quale differenza vedrai? Ha senso? – sll

risposta

1

Sono d'accordo con Joseph a diff'ing la stringa. Vorrei anche raccomandare un motore diffuso appositamente costruito (alcuni trovati qui: Any decent text diff/merge engine for .NET?) che possono aiutarti a evitare alcuni dei problemi più comuni nella diffusione.

0

Dovresti davvero estrarre il documento in una stringa e differire quello.

Ti interessano solo le modifiche testuali e non la formattazione giusta?

+1

tutto, anche se l'immagine è diversa. Ma ho intenzione di provare a rilassare quel requisito. – user20358

3

È necessario utilizzare la classe Documento per confrontare i file e aprire in un documento Word il risultato.

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

Ciao @ anderson-rissardi! Cosa fa in realtà il metodo Compare? Apre qualche file da qualche parte? Perché non vedo nulla quando corro questo nel mio test unitario. Come dovrei ottenere il risultato dal momento che il metodo restituisce il nulla? – ditoslav

+1

Ciao @ditoslav. Apre un nuovo file. È il pulsante "Copare" all'interno della Parola. Apri MS Word -> Scheda 'Revisione' -> Pulsante 'Confronta'. È la stessa funzionalità, un nuovo documento che viene generato. Devi fare un salvataggio di questo nuovo documento. –

0

Per fare un confronto tra i documenti di Word, è necessario

  1. Una libreria per manipolare documenti di Word, per esempio leggi paragrafi, testo, tabelle ecc. da un file Word. Puoi provare Office Interop, OpenXML o Aspose.Words for .NET.
  2. Un algoritmo/libreria per eseguire il confronto effettivo, sul testo recuperato da entrambi i documenti di Word. Puoi scrivere da solo o utilizzare una libreria come DiffMatchPatch o simile.

Questa domanda è vecchia, ora ci sono più soluzioni come GroupDocs Compare disponibili.

Document Comparison by Aspose.Words for .NET è un progetto di open source vetrina che utilizza Aspose.Words e DiffMatchPatch per il confronto.

Lavoro presso Aspose come Evangelista sviluppatore.

1

Quindi i miei requisiti erano che dovevo usare una lib di .Net e volevo evitare di lavorare sui file reali ma lavorare con i flussi.

ZipArchive è in System.IO.Compressed

Quello che ho fatto e ha funzionato abbastanza bene stava usando lo ZipArchive da .Net e confrontando il contenuto mentre sono assenti il ​​file .rels perché sembra la si è generato in modo casuale su ogni creazione di file. Ecco il mio frammento:

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; 
     } 
    } 
0

Per una soluzione su un server, o in esecuzione, senza l'installazione di Word e utilizzando gli strumenti COM, è possibile utilizzare il componente WmlComparer di XmlPowerTools.

Il documentation è un po 'limitato, ma ecco un esempio di utilizzo:

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

che vi mostrerà le differenze tra i due documenti.

Problemi correlati