Как заменить закладку таблицей из словаря openxl ASP MVC C#
Привет,
у меня есть WordGeneratorService. Здесь я получаю шаблон из своей базы данных, загружаю его в поток памяти и заменяю закладки текстом или объектами(DataTables). Для струн это работает нормально. Но как только я хочу заменить закладку на Datatable, я получаю сообщение об ошибке поток не расширяется.
Кто - нибудь может дать мне совет?
Спасибо
Что я уже пробовал:
public byte[] GenerateDocumentTest(IDictionary<string, object> values, string settingsType, string settingsEntry) { SettingsEntry settings = this._unitOfWork.SettingsEntryRepository.FindByAlias(settingsType, settingsEntry); if (null != settings) { byte[] template = settings.File; if (template.Length > 0) { return this.GenerateDocumentTest(values, template); } } return null; }
public byte[] GenerateDocumentTest(IDictionary<string, object> values, byte[] template) { if (values == null) throw new ArgumentException("Fehlende Einträge!"); MemoryStream stream = new MemoryStream(template); using (var doc = WordprocessingDocument.Open(stream, true)) { if (doc.MainDocumentPart.HeaderParts != null) foreach (var header in doc.MainDocumentPart.HeaderParts) ProcessBookmarksPartTest(values, DocumentSection.Header, header); ProcessBookmarksPartTest(values, DocumentSection.Main, doc.MainDocumentPart); if (doc.MainDocumentPart.FooterParts != null) foreach (var footer in doc.MainDocumentPart.FooterParts) ProcessBookmarksPartTest(values, DocumentSection.Footer, footer); stream.Position = 0; byte[] result = stream.ToArray(); return result; } }
private void ProcessBookmarksPartTest(IDictionary<string, object> values, DocumentSection documentSection, object section) { IEnumerable<BookmarkStart> bookmarks = null; //Holen der einzelnen Bookmarks für jede Dokumentsektion switch (documentSection) { case DocumentSection.Main: { bookmarks = ((MainDocumentPart)section).Document.Body.Descendants<BookmarkStart>(); break; } case DocumentSection.Header: { bookmarks = ((HeaderPart)section).RootElement.Descendants<BookmarkStart>(); break; } case DocumentSection.Footer: { bookmarks = ((FooterPart)section).RootElement.Descendants<BookmarkStart>(); break; } } if (bookmarks == null) { return; } foreach (var bmStart in bookmarks) { if (!values.ContainsKey(bmStart.Name)) continue; BookmarkEnd bmEnd = null; switch (documentSection) { case DocumentSection.Main: { bmEnd = (((MainDocumentPart)section).Document.Body.Descendants<BookmarkEnd>().Where(b => b.Id == bmStart.Id.ToString())).FirstOrDefault(); break; } case DocumentSection.Header: { bmEnd = (((HeaderPart)section).RootElement.Descendants<BookmarkEnd>().Where(b => b.Id == bmStart.Id.ToString())).FirstOrDefault(); break; } case DocumentSection.Footer: { bmEnd = (((FooterPart)section).RootElement.Descendants<BookmarkEnd>().Where(b => b.Id == bmStart.Id.ToString())).FirstOrDefault(); break; } } if (bmEnd == null) continue; var rProp = bmStart.Parent.Descendants<Run>().Where(rp => rp.RunProperties != null).Select(rp => rp.RunProperties).FirstOrDefault(); if (bmStart.PreviousSibling<Run>() == null && bmEnd.ElementsAfter().Count(e => e.GetType() == typeof(Run)) == 0) { bmStart.Parent.RemoveAllChildren<Run>(); } else { var list = bmStart.ElementsAfter().Where(r => r.IsBefore(bmEnd)).ToList(); var trRun = list.Where(rp => rp.GetType() == typeof(Run) && ((Run)rp).RunProperties != null).Select(rp => ((Run)rp).RunProperties).FirstOrDefault(); if (trRun != null) rProp = (RunProperties)trRun.Clone(); for (var n = list.Count(); n > 0; n--) list[n - 1].Remove(); } var dictValue = values[bmStart.Name]; if (dictValue.GetType().Equals(typeof(DataTable))) { DataTable dictTable = dictValue as DataTable; //Elternelement des aktuellen Bookmarks OpenXmlElement bmParent = bmStart.Parent; DocumentFormat.OpenXml.Wordprocessing.Table wordTable = new DocumentFormat.OpenXml.Wordprocessing.Table(); TableProperties tblProp = new DocumentFormat.OpenXml.Wordprocessing.TableProperties( new TableBorders(new Border() { Val = new DocumentFormat.OpenXml.EnumValue<BorderValues>(BorderValues.DotDash), Size = 24 } ) ); wordTable.AppendChild<TableProperties>(tblProp); for (int i = 0; i < dictTable.Rows.Count; i++) { DocumentFormat.OpenXml.Wordprocessing.TableRow tr = new DocumentFormat.OpenXml.Wordprocessing.TableRow(); for (int j = 0; j < dictTable.Columns.Count; j++) { DocumentFormat.OpenXml.Wordprocessing.TableCell wordTableCell = new DocumentFormat.OpenXml.Wordprocessing.TableCell(); wordTableCell.Append(new TableCellProperties(new TableCellWidth() { Type = TableWidthUnitValues.Dxa, Width = "2880" })); wordTableCell.Append(new Paragraph(new Run(new Text(dictTable.Rows[i][j].ToString())))); tr.Append(wordTableCell); } wordTable.Append(tr); } bmParent.InsertAfterSelf(wordTable); } else if (dictValue.GetType().Equals(typeof(string))) { //Der Wert im Dict ist Text string bmText = dictValue as string; if (!string.IsNullOrEmpty(bmText) && bmText.Contains(Environment.NewLine)) { OpenXmlElement insertElement = bmStart.Parent.PreviousSibling(); string[] rows = bmText.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); foreach (string row in rows) { Paragraph np = new Paragraph(); Run nRun = new Run(); if (rProp != null) nRun.RunProperties = (RunProperties)rProp.Clone(); nRun.AppendChild(new Text(row)); np.AppendChild(nRun); if (insertElement.Parent != null) insertElement.InsertAfterSelf(np); else insertElement.Append(np); insertElement = np; } } else { var nRun = new Run(); if (rProp != null) nRun.RunProperties = (RunProperties)rProp.Clone(); nRun.Append(new Text(bmText)); bmStart.InsertAfterSelf(nRun); } } else { throw new Exception("Der Übergebenen Wert ist weder string noch Datatable"); } } }