Hello,
i have a WordGeneratorService. Here I get a Template from my Database, load the template to a MemoryStream and replace the bookmarks with text or objects(DataTables). For strings it's working fine. But a soon as i want to replace a bookmark with a Datatable i get the error message stream is not expandable.
Can anybody give me some advice?
Thanks
What I have tried:
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;
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;
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)))
{
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");
}
}
}