2009-07-17 3 views
6

Ich verwende Word und OpenXml Seriendruck-Funktionalität in einer C# ASP.NET Web-Anwendung zur Verfügung zu stellen:Duplicating Word-Dokument mit OpenXml und C#

1) Ein Dokument mit einer Anzahl von vordefinierten Zeichenkette für die Substitution hochgeladen .

2) Mit dem OpenXML SDK 2.0 öffne ich das Word-Dokument, erhalte das mainDocumentPart als String und führe die Ersetzung mit Regex durch.

3) Ich erstelle dann ein neues Dokument mit OpenXML, füge ein neues mainDocumentPart hinzu und füge die aus der Ersetzung resultierende Zeichenfolge in dieses mainDocumentPart ein.

Alle Formatierungen/Stile usw. gehen jedoch im neuen Dokument verloren.

Ich schätze, ich kann kopieren und fügen Sie die Stil, Definitionen, Kommentar Teile etc .. individuell das ursprüngliche Dokument nachzuahmen.

Gibt es jedoch eine Methode, die Open XML verwendet, um ein Dokument zu duplizieren, das es mir ermöglicht, die Ersetzungen auf der neuen Kopie durchzuführen?

Danke.

Antwort

-1

Wenn Sie ein openxml-Dokument betrachten, indem Sie die Erweiterung in zip ändern und öffnen, sehen Sie, dass dieser Wortunterordner einen _rels-Ordner enthält, in dem alle Beziehungen aufgeführt sind. Diese Beziehungen verweisen auf die Teile, die du erwähnt hast (Stil ...). Tatsächlich benötigen Sie diese Teile, weil sie die Definition der Formatierung enthalten. Wenn Sie sie nicht kopieren, wird das neue Dokument die in der normal.dot-Datei definierte Formatierung verwenden und nicht die im Originaldokument definierte. Ich denke, du musst sie kopieren.

+0

nicht wirklich die Frage zu beantworten. Lesen Sie, wie Sie vor der Beantwortung vorgehen. –

2

Ich habe einige sehr ähnliche Dinge getan, aber anstelle Textersetzungen verwenden, verwende ich Word Content Controls. Ich habe einige der Details im folgenden Blogpost, SharePoint and Open Xml dokumentiert. Die Technik ist nicht spezifisch für SharePoint. Sie können das Muster in reinem ASP.NET oder anderen Anwendungen wiederverwenden.

Auch würde ich Ihnen dringend empfehlen, Eric White's Blog für Tipps, Tricks und Techniken in Bezug auf Open Xml zu überprüfen. Insbesondere, überprüfen Sie die in-memory manipulation of Open Xml post und die Word content controls Beiträge. Ich denke, Sie werden diese auf lange Sicht viel hilfreicher finden.

Hoffe, das hilft.

4

Ich zweite die Verwendung von Content Controls Empfehlung. Mit ihnen die Bereiche Ihres Dokuments zu markieren, in denen Sie eine Substitution durchführen möchten, ist bei weitem der einfachste Weg, dies zu tun.

Wie zum Duplizieren des Dokuments (und zum Halten der gesamten Dokumentinhalte, Stile und alle), ist es relativ einfach:

string documentURL = "full URL to your document"; 
byte[] docAsArray = File.ReadAllBytes(documentURL); 

using (MemoryStream stream = new MemoryStream) 
{ 
    stream.Write(docAsArray, 0, docAsArray.Length); // THIS performs doc copy 
    using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true)) 
    { 
     // perform content control substitution here, making sure to call .Save() 
     // on any documents Part's changed. 
    } 
    File.WriteAllBytes("full URL of your new doc to save, including .docx", stream.ToArray()); 
} 

Eigentlich die Inhaltskontrollen zu finden, ist ein Stück des Kuchens mit LINQ. Das folgende Beispiel findet alle Simple Text Content Kontrollen (die als SdtRun eingegeben werden):

using (WordprocessingDocument doc = WordprocessingDocument.Open(stream, true)) 
{      
    var mainDocument = doc.MainDocumentPart.Document; 
    var contentControls = from sdt in mainDocument.Descendants<SdtRun>() select sdt; 

    foreach (var cc in contentControls) 
    { 
     // drill down through the containment hierarchy to get to 
     // the contained <Text> object 
     cc.SdtContentRun.GetFirstChild<Run>().GetFirstChild<Text>().Text = "my replacement string"; 
    } 
} 

Die <Run> und <Text> Elemente nicht bereits vorhanden können aber sie ist so einfach wie die Erstellung:

cc.SdtContentRun.Append(new Run(new Text("my replacement string"))); 

Hoffnung das hilft jemandem.: D

2

Als Ergänzung zu den oben genannten; Was vielleicht nützlicher ist, ist die Suche nach Content-Steuerelementen, die getaggt wurden (mit dem Wort GUI). Ich schrieb vor kurzem eine Software, die Dokumentvorlagen füllte, die Inhaltssteuerelemente mit angehängten Tags enthielten. Um sie zu finden ist nur eine Erweiterung der oben LINQ-Abfrage:

var mainDocument = doc.MainDocumentPart.Document; 
var taggedContentControls = from sdt in mainDocument.Descendants<SdtElement>() 
          let sdtPr = sdt.GetFirstChild<SdtProperties>() 
          let tag = (sdtPr == null ? null : sdtPr.GetFirstChild<Tag>()) 
          where (tag != null) 
          select new 
          { 
           SdtElem = sdt, 
           TagName = tag.GetAttribute("val", W).Value 
          }; 

ich diesen Code bekam von anderswo, aber kann mich nicht erinnern im Moment, wo; Der volle Kredit geht an sie.

Die Abfrage erstellt nur einen IEnumerable eines anonymen Typs, der das Inhaltssteuerelement und das zugehörige Tag als Eigenschaften enthält. Praktisch!

10

Dieses Codeelement sollte alle Teile aus einem vorhandenen Dokument in ein neues kopieren.

using (var mainDoc = WordprocessingDocument.Open(@"c:\sourcedoc.docx", false)) 
using (var resultDoc = WordprocessingDocument.Create(@"c:\newdoc.docx", 
    WordprocessingDocumentType.Document)) 
{ 
    // copy parts from source document to new document 
    foreach (var part in mainDoc.Parts) 
    resultDoc.AddPart(part.OpenXmlPart, part.RelationshipId); 
    // perform replacements in resultDoc.MainDocumentPart 
    // ... 
} 
+1

Ich habe stundenlang mit dem Kopf gegen die Wand geschlagen, mit dem MemoryStream-Geschäft. Das funktioniert großartig und ist viel prägnanter. Danke vielmals! – lukiffer

+0

Gibt es eine Möglichkeit, eine ähnliche Sache zu machen, mit dem einzigen Unterschied, dass der Inhalt im 'mainDoc' an das Ende eines bestehenden Dokuments angehängt werden muss? –

+0

Ja, obwohl viel schwieriger, da viele Daten aus Teilen beider Dokumente zusammengeführt werden müssen. Zum Glück hat [Eric White] (http://ericwhite.com/blog/) eine Reihe von [PowerTools für OpenXML] (http://ericwhite.com/blog/category/open-xml/powertools/) erstellt, die behandelt werden diese sonst entmutigende Aufgabe für Sie. Sehen Sie sich insbesondere den [DocumentBuilder] (http://openxmldeveloper.org/wiki/w/wiki/documentbuilder.aspx) an, mit dem ich in der Vergangenheit ein Dokument an ein anderes angehängt habe. Lief wie am Schnürchen! – bernhof