public TemplateProcessor FillContent(Content content) { var processor = new ContentProcessor( new ProcessContext(_wordDocument)) .SetRemoveContentControls(_isNeedToRemoveContentControls); var processResult = processor.FillContent(Document.Root.Element(W.body), content); if (_wordDocument.HasFooters) { foreach (var footer in _wordDocument.FooterParts.Values) { var footerProcessResult = processor.FillContent(footer.Element(W.footer), content); processResult.Merge(footerProcessResult); } } if (_wordDocument.HasHeaders) { foreach (var header in _wordDocument.HeaderParts.Values) { var headerProcessResult = processor.FillContent(header.Element(W.header), content); processResult.Merge(headerProcessResult); } } if (_isNeedToNoticeAboutErrors) AddErrors(processResult.Errors); return this; }
private PropagationProcessResult PropagatePrototype(Prototype prototype, IEnumerable <Content> content) { var processResult = new PropagationProcessResult(); var newRows = new List <XElement>(); foreach (var contentItem in content) { // Create new item from the prototype. var newItemEntry = prototype.Clone(); foreach (var xElement in newItemEntry.PrototypeItems) { var newElement = new XElement(xElement); if (!newElement.DescendantsAndSelf(W.sdt).Any()) { newRows.Add(newElement); continue; } foreach (var sdt in newElement.FirstLevelDescendantsAndSelf(W.sdt).ToList()) { var fieldContent = contentItem.GetContentItem(sdt.SdtTagName()); if (fieldContent == null) { processResult.AddError(new CustomError( string.Format("Field content for field '{0}' not found", sdt.SdtTagName()))); continue; } var contentProcessResult = new ContentProcessor(this.context) .SetRemoveContentControls(this.isNeedToRemoveContentControls) .FillContent(sdt, fieldContent); processResult.Merge(contentProcessResult); } newRows.Add(newElement); } } processResult.Result = newRows; return(processResult); }
// Fills prototype with values recursive. private PropagationProcessResult PropagatePrototype(Prototype prototype, IEnumerable <ListItemContent> content) { var processResult = new PropagationProcessResult(); var newRows = new List <XElement>(); foreach (var contentItem in content) { var currentLevelPrototype = prototype.CurrentLevelPrototype(contentItem.FieldNames); if (currentLevelPrototype == null || !currentLevelPrototype.IsValid) { processResult.AddError(new CustomError( string.Format("Prototype for list item '{0}' not found", string.Join(", ", contentItem.FieldNames)))); continue; } // Create new item from the prototype. var newItemEntry = currentLevelPrototype.Clone(); foreach (var xElement in newItemEntry.PrototypeItems) { var newElement = new XElement(xElement); if (!newElement.DescendantsAndSelf(W.sdt).Any()) { newRows.Add(newElement); continue; } foreach (var sdt in newElement.FirstLevelDescendantsAndSelf(W.sdt).ToList()) { var fieldContent = contentItem.GetContentItem(sdt.SdtTagName()); if (fieldContent == null) { processResult.AddError(new CustomError( string.Format("Field content for field '{0}' not found", sdt.SdtTagName()))); continue; } var contentProcessResult = new ContentProcessor(_context) .SetRemoveContentControls(_isNeedToRemoveContentControls) .FillContent(sdt, fieldContent); processResult.Merge(contentProcessResult); } newRows.Add(newElement); } // If there are nested items fill prototype for them. if (contentItem.NestedFields != null) { var filledNestedFields = PropagatePrototype( prototype.Exclude(currentLevelPrototype), contentItem.NestedFields); newRows.AddRange(filledNestedFields.Result); } } processResult.Result = newRows; return(processResult); }
// Fills prototype with values recursive. private PropagationProcessResult PropagatePrototype(Prototype prototype, IEnumerable<ListItemContent> content) { var processResult = new PropagationProcessResult(); var newRows = new List<XElement>(); foreach (var contentItem in content) { var currentLevelPrototype = prototype.CurrentLevelPrototype(contentItem.FieldNames); if (currentLevelPrototype == null || !currentLevelPrototype.IsValid) { processResult.Errors.Add( string.Format("Prototype for list item '{0}' not found", string.Join(", ", contentItem.FieldNames))); continue; } // Create new item from the prototype. var newItemEntry = currentLevelPrototype.Clone(); foreach (var xElement in newItemEntry.PrototypeItems) { var newElement = new XElement(xElement); if (!newElement.DescendantsAndSelf(W.sdt).Any()) { newRows.Add(newElement); continue; } foreach (var sdt in newElement.FirstLevelDescendantsAndSelf(W.sdt).ToList()) { var fieldContent = contentItem.GetContentItem(sdt.SdtTagName()); if (fieldContent == null) { processResult.Errors.Add(string.Format("Field content for field '{0}' not found", sdt.SdtTagName())); continue; } var contentProcessResult = new ContentProcessor(_context) .SetRemoveContentControls(_isNeedToRemoveContentControls) .FillContent(sdt, fieldContent); if (!contentProcessResult.Success) processResult.Errors.AddRange(processResult.Errors); } newRows.Add(newElement); } // If there are nested items fill prototype for them. if (contentItem.NestedFields != null) { var filledNestedFields = PropagatePrototype( prototype.Exclude(currentLevelPrototype), contentItem.NestedFields); newRows.AddRange(filledNestedFields.Result); } } processResult.Result = newRows; return processResult; }
/// <summary> /// Fills content with one content item /// </summary> /// <param name="contentControl">Content control</param> /// <param name="item">Content item</param> private ProcessResult FillContent(XContainer contentControl, IContentItem item) { if (!(item is TableContent)) { return(ProcessResult.NotHandledResult); } var processResult = new ProcessResult(); var table = item as TableContent; // Find the content control with Table Name var tableName = table.Name; // If there isn't a table with that name, add an error to the error string, // and continue with next table. if (contentControl == null) { processResult.Errors.Add(String.Format("Table Content Control '{0}' not found.", tableName)); return(processResult); } // If the table doesn't contain content controls in cells, then error and continue with next table. var cellContentControl = contentControl .Descendants(W.sdt) .FirstOrDefault(); if (cellContentControl == null) { processResult.Errors.Add(String.Format( "Table Content Control '{0}' doesn't contain content controls in cells.", tableName)); return(processResult); } var fieldNames = table.FieldNames.ToList(); var prototypeRows = GetPrototype(contentControl, fieldNames); //Select content controls tag names var contentControlTagNames = prototypeRows .Descendants(W.sdt) .Select(sdt => sdt.SdtTagName()) .Where(fieldNames.Contains) .ToList(); //If there are not content controls with the one of specified field name we need to add the warning if (contentControlTagNames.Intersect(fieldNames).Count() != fieldNames.Count()) { var invalidFileNames = fieldNames .Where(fn => !contentControlTagNames.Contains(fn)) .ToList(); processResult.Errors.Add(String.Format( "Table Content Control '{0}' doesn't contain rows with cell content {1} {2}.", tableName, invalidFileNames.Count > 1 ? "controls" : "control", string.Join(", ", invalidFileNames.Select(fn => string.Format("'{0}'", fn))))); } // Create a list of new rows to be inserted into the document. Because this // is a document centric transform, this is written in a non-functional // style, using tree modification. var newRows = new List <List <XElement> >(); foreach (var row in table.Rows) { // Clone the prototypeRows into newRowsEntry. var newRowsEntry = prototypeRows.Select(prototypeRow => new XElement(prototypeRow)).ToList(); // Create new rows that will contain the data that was passed in to this // method in the XML tree. foreach (var sdt in newRowsEntry.FirstLevelDescendantsAndSelf(W.sdt).ToList()) { // Get fieldName from the content control tag. var fieldName = sdt.SdtTagName(); var content = row.GetContentItem(fieldName); if (content != null) { var contentProcessResult = new ContentProcessor(_context) .SetRemoveContentControls(_isNeedToRemoveContentControls) .FillContent(sdt, content); if (!contentProcessResult.Success) { processResult.Errors.AddRange(processResult.Errors); } } } // Add the newRow to the list of rows that will be placed in the newly // generated table. newRows.Add(newRowsEntry); } prototypeRows.Last().AddAfterSelf(newRows); // Remove the prototype rows prototypeRows.Remove(); return(processResult); }
public TemplateProcessor FillContentEverywhere(Content content) { var processResult = new ContentProcessor( new ProcessContext(_wordDocument, Document, NumberingPart, StylesPart, HeaderPart, FooterPart)) .SetRemoveContentControls(_isNeedToRemoveContentControls) .FillContentEverywhere(content); if (_isNeedToNoticeAboutErrors) AddErrors(processResult.Errors); return this; }
/// <summary> /// Fills content with one content item /// </summary> /// <param name="contentControl">Content control</param> /// <param name="item">Content item</param> private ProcessResult FillContent(XContainer contentControl, IContentItem item) { if (!(item is TableContent)) return ProcessResult.NotHandledResult; var processResult = new ProcessResult(); var table = item as TableContent; // Find the content control with Table Name var tableName = table.Name; // If there isn't a table with that name, add an error to the error string, // and continue with next table. if (contentControl == null) { processResult.Errors.Add(String.Format("Table Content Control '{0}' not found.", tableName)); return processResult; } // If the table doesn't contain content controls in cells, then error and continue with next table. var cellContentControl = contentControl .Descendants(W.sdt) .FirstOrDefault(); if (cellContentControl == null) { processResult.Errors.Add(String.Format( "Table Content Control '{0}' doesn't contain content controls in cells.", tableName)); return processResult; } var fieldNames = table.FieldNames.ToList(); var prototypeRows = GetPrototype(contentControl, fieldNames); //Select content controls tag names var contentControlTagNames = prototypeRows .Descendants(W.sdt) .Select(sdt => sdt.SdtTagName()) .Where(fieldNames.Contains); //If there are not content controls with the one of specified field name we need to add the warning if (contentControlTagNames.Intersect(fieldNames).Count() != fieldNames.Count()) { processResult.Errors.Add(String.Format( "Table Content Control '{0}' doesn't contain rows with cell content controls {1}.", tableName, string.Join(", ", fieldNames.Select(fn => string.Format("'{0}'", fn))))); //return processResult; } // Create a list of new rows to be inserted into the document. Because this // is a document centric transform, this is written in a non-functional // style, using tree modification. var newRows = new List<List<XElement>>(); foreach (var row in table.Rows) { // Clone the prototypeRows into newRowsEntry. var newRowsEntry = prototypeRows.Select(prototypeRow => new XElement(prototypeRow)).ToList(); // Create new rows that will contain the data that was passed in to this // method in the XML tree. foreach (var sdt in newRowsEntry.FirstLevelDescendantsAndSelf(W.sdt).ToList()) { // Get fieldName from the content control tag. var fieldName = sdt.SdtTagName(); var content = row.GetContentItem(fieldName); if (content != null) { var contentProcessResult = new ContentProcessor(_context) .SetRemoveContentControls(_isNeedToRemoveContentControls) .FillContent(sdt, content); if (!contentProcessResult.Success) processResult.Errors.AddRange(processResult.Errors); } } // Add the newRow to the list of rows that will be placed in the newly // generated table. newRows.Add(newRowsEntry); } prototypeRows.Last().AddAfterSelf(newRows); // Remove the prototype rows prototypeRows.Remove(); return processResult; }
public TemplateProcessor FillContent(Content content) { var processResult = new ContentProcessor( new ProcessContext(Document, NumberingPart, StylesPart)) .SetRemoveContentControls(_isNeedToRemoveContentControls) .FillContent(Document.Root.Element(W.body), content); if (_isNeedToNoticeAboutErrors) AddErrors(processResult.Errors); return this; }
/// <summary> /// Fills content with one content item /// </summary> /// <param name="contentControl">Content control</param> /// <param name="item">Content item</param> private ProcessResult FillContent(XContainer contentControl, IContentItem item) { if (!(item is TableContent)) { return(ProcessResult.NotHandledResult); } var processResult = ProcessResult.NotHandledResult; var table = item as TableContent; // If there isn't a table with that name, add an error to the error string, // and continue with next table. if (contentControl == null) { processResult.AddError(new ContentControlNotFoundError(table)); return(processResult); } // If the table doesn't contain content controls in cells, then error and continue with next table. var cellContentControl = contentControl .Descendants(W.sdt) .FirstOrDefault(); if (cellContentControl == null) { processResult.AddError(new CustomContentItemError(table, string.Format("doesn't contain content controls in cells"))); return(processResult); } if (table.IsHidden || table.Rows == null) { contentControl.Descendants(W.tbl).Remove(); } else { var fieldNames = table.FieldNames.ToList(); var prototypeRows = GetPrototype(contentControl, fieldNames); //Select content controls tag names var contentControlTagNames = prototypeRows .Descendants(W.sdt) .Select(sdt => sdt.SdtTagName()) .Where(fieldNames.Contains) .ToList(); //If there are not content controls with the one of specified field name we need to add the warning if (contentControlTagNames.Intersect(fieldNames).Count() != fieldNames.Count()) { var invalidFileNames = fieldNames .Where(fn => !contentControlTagNames.Contains(fn)) .ToList(); processResult.AddError( new CustomContentItemError(table, string.Format("doesn't contain rows with cell content {0} {1}", invalidFileNames.Count > 1 ? "controls" : "control", string.Join(", ", invalidFileNames.Select(fn => string.Format("'{0}'", fn)).ToArray())))); } // Create a list of new rows to be inserted into the document. Because this // is a document centric transform, this is written in a non-functional // style, using tree modification. var newRows = new List <List <XElement> >(); bool vMerge = false; foreach (var row in table.Rows) { // Clone the prototypeRows into newRowsEntry. var newRowsEntry = prototypeRows.Select(prototypeRow => new XElement(prototypeRow)).ToList(); // Create new rows that will contain the data that was passed in to this // method in the XML tree. foreach (var sdt in newRowsEntry.FirstLevelDescendantsAndSelf(W.sdt).ToList()) { // Get fieldName from the content control tag. var fieldName = sdt.SdtTagName(); var content = row.GetContentItem(fieldName); if (content == null) { continue; } var contentProcessResult = new ContentProcessor(_context) .SetRemoveContentControls(_isNeedToRemoveContentControls) .FillContent(sdt, content); processResult.Merge(contentProcessResult); } // If first row contains more cells, need vMerge if (table.Rows.First() != null && newRowsEntry.Count == 1) { foreach (var extraCell in table.Rows.First().Where(x => !row.Any(y => y.Name == x.Name))) { var newRow = newRowsEntry.First(); var cell = newRow.Descendants(W.tc) .FirstOrDefault(x => x.Descendants(W.sdt).Any(s => s.SdtTagName() == extraCell.Name)); if (cell != null) { // In previous rows find cell and set vMerge with value "restart" var firstRowEntry = newRows.FirstOrDefault(); if (firstRowEntry != null) { var prevCell = firstRowEntry.Descendants(W.tc) .FirstOrDefault(x => x.Descendants(W.sdt).Any(s => s.SdtTagName() == extraCell.Name)); var tcPr = prevCell.Descendants(W.tcPr).FirstOrDefault(); if (tcPr != null && tcPr.Descendants(W.vMerge).Count() == 0) { tcPr.Add(new XElement(W.vMerge, new XAttribute(W.val, "restart"))); vMerge = true; } } // In current cell need set vMerge without value // But after set vMerge flag so that data is not damaged if (vMerge) { var tcPr = cell.Descendants(W.tcPr).FirstOrDefault(); if (tcPr != null) { tcPr.Add(new XElement(W.vMerge)); } } } } } // Add the newRow to the list of rows that will be placed in the newly // generated table. newRows.Add(newRowsEntry); } prototypeRows.Last().AddAfterSelf(newRows); // Remove the prototype rows prototypeRows.Remove(); } processResult.AddItemToHandled(table); return(processResult); }