private static void ExtractAllTemplateFields(WordprocessingDocument wordDoc, FieldAccumulator fieldAccumulator, bool removeCustomProperties = true, IEnumerable <string> keepPropertyNames = null) { if (RevisionAccepter.HasTrackedRevisions(wordDoc)) { throw new FieldParseException("Invalid template - contains tracked revisions"); } // extract fields from each part of the document foreach (var part in wordDoc.ContentParts()) { ExtractFieldsFromPart(part, fieldAccumulator); if (removeCustomProperties) { // remove document variables and custom properties // (in case they have any sensitive information that should not carry over to assembled documents!) MainDocumentPart main = part as MainDocumentPart; if (main != null) { var docVariables = main.DocumentSettingsPart.Settings.Descendants <DocumentVariables>(); foreach (DocumentVariables docVars in docVariables.ToList()) { foreach (DocumentVariable docVar in docVars.ToList()) { if (keepPropertyNames == null || !Enumerable.Contains <string>(keepPropertyNames, docVar.Name)) { docVar.Remove(); //docVar.Name = "Id"; //docVar.Val.Value = "123"; } } } } } } if (removeCustomProperties) { // remove custom properties if there are any (custom properties are the new/non-legacy version of document variables) var custom = wordDoc.CustomFilePropertiesPart; if (custom != null) { foreach (CustomDocumentProperty prop in custom.Properties.ToList()) { if (keepPropertyNames == null || !Enumerable.Contains <string>(keepPropertyNames, prop.Name)) { prop.Remove(); // string propName = prop.Name; // string value = prop.VTLPWSTR.InnerText; } } } } }
public static void TransformToSingleCharacterRuns(WordprocessingDocument doc) { if (RevisionAccepter.HasTrackedRevisions(doc)) { throw new OpenXmlPowerToolsException( "Transforming a document to single character runs is not supported for " + "a document with tracked revisions."); } foreach (var part in doc.ContentParts()) { TransformPartToSingleCharacterRuns(part); } }
private static void PrepareTemplate(WordprocessingDocument wordDoc) { if (RevisionAccepter.HasTrackedRevisions(wordDoc)) { throw new FieldParseException("Invalid template - contains tracked revisions"); } SimplifyTemplateMarkup(wordDoc); foreach (var part in wordDoc.ContentParts()) { PrepareTemplatePart(part); } }
private static TemplateErrorList PrepareTemplate(WordprocessingDocument wordDoc, FieldTransformIndex xm) { if (RevisionAccepter.HasTrackedRevisions(wordDoc)) { throw new FieldParseException("Invalid template - contains tracked revisions"); } SimplifyTemplateMarkup(wordDoc); var te = new TemplateErrorList(); foreach (var part in wordDoc.ContentParts()) { PrepareTemplatePart(part, xm, te); } return(te); }
public static WmlDocument AssembleDocument(WmlDocument templateDoc, XElement data, out bool templateError) { byte[] byteArray = templateDoc.DocumentByteArray; using (MemoryStream mem = new MemoryStream()) { mem.Write(byteArray, 0, (int)byteArray.Length); using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(mem, true)) { if (RevisionAccepter.HasTrackedRevisions(wordDoc)) { throw new OpenXmlPowerToolsException("Invalid DocumentAssembler template - contains tracked revisions"); } var te = new TemplateError(); foreach (var part in wordDoc.ContentParts()) { ProcessTemplatePart(data, te, part); } templateError = te.HasError; } WmlDocument assembledDocument = new WmlDocument("TempFileName.docx", mem.ToArray()); return(assembledDocument); } }
public static void ReplaceBookmarkText(WordprocessingDocument doc, string bookmarkName, string replacementText) { XDocument xDoc = doc.MainDocumentPart.GetXDocument(); XElement bookmark = xDoc.Descendants(W.bookmarkStart) .FirstOrDefault(d => (string)d.Attribute(W.name) == bookmarkName); if (bookmark == null) { throw new BookmarkReplacerException( "Document doesn't contain bookmark."); } if (bookmark.Parent.Name.Namespace == M.m) { throw new BookmarkReplacerException( "Replacing text in math formulas is not supported."); } if (RevisionAccepter.HasTrackedRevisions(doc)) { throw new BookmarkReplacerException( "Replacing bookmark text in documents that have tracked revisions is not supported."); } if (xDoc.Descendants(W.sdt).Any()) { throw new BookmarkReplacerException( "Replacing bookmark text in documents that have content controls is not supported."); } XElement newRoot = (XElement)FlattenParagraphsTransform(xDoc.Root); XElement startBookmarkElement = newRoot.Descendants(W.bookmarkStart) .Where(d => (string)d.Attribute(W.name) == bookmarkName) .FirstOrDefault(); int bookmarkId = (int)startBookmarkElement.Attribute(W.id); XElement endBookmarkElement = newRoot.Descendants(W.bookmarkEnd) .Where(d => (int)d.Attribute(W.id) == bookmarkId) .FirstOrDefault(); if (startBookmarkElement.Ancestors(W.hyperlink).Any() || endBookmarkElement.Ancestors(W.hyperlink).Any()) { throw new BookmarkReplacerException( "Bookmark is within a hyperlink. Can't replace text."); } if (startBookmarkElement.Ancestors(W.fldSimple).Any() || endBookmarkElement.Ancestors(W.fldSimple).Any()) { throw new BookmarkReplacerException( "Bookmark is within a simple field. Can't replace text."); } if (startBookmarkElement.Ancestors(W.smartTag).Any() || endBookmarkElement.Ancestors(W.smartTag).Any()) { throw new BookmarkReplacerException( "Bookmark is within a smart tag. Can't replace text."); } if (startBookmarkElement.Parent != endBookmarkElement.Parent) { throw new BookmarkReplacerException( "Bookmark start and end not at same levels. Can't replace text."); } XElement parentElement = startBookmarkElement.Parent; var elementsBetweenBookmarks = startBookmarkElement .ElementsAfterSelf() .TakeWhile(e => e != endBookmarkElement); var newElements = parentElement .Elements() .TakeWhile(e => e != startBookmarkElement) .Concat(new[] { startBookmarkElement, new XElement(BookmarkReplacerCustomNamespace + "Insert", elementsBetweenBookmarks .Where(e => e.Name == W.r) .Take(1) .Elements(W.rPr) .FirstOrDefault()), }) .Concat(elementsBetweenBookmarks.Where(e => e.Name != W.p && e.Name != W.r && e.Name != W.tbl)) .Concat(new[] { endBookmarkElement }) .Concat(endBookmarkElement.ElementsAfterSelf()); parentElement.ReplaceNodes(newElements); newRoot = (XElement)UnflattenParagraphsTransform(newRoot); newRoot = (XElement)ReplaceInsertElement(newRoot, replacementText); newRoot = (XElement)DemoteRunChildrenOfBodyTransform(newRoot); xDoc.Elements().First().ReplaceWith(newRoot); doc.MainDocumentPart.PutXDocument(); }