Click here to Skip to main content
14,358,698 members
Rate this:
Please Sign up or sign in to vote.
See more:
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;
            //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");
                    }
                }
            }
Posted
Updated 10-Aug-17 3:58am

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

The "stream is not expandable" message means something is trying to increase the size of the MemoryStream. The only way to get a MemoryStream instance that supports this is to use the constructor which takes the initial capacity[^], or the parameterless constructor. Every other constructor creates a non-resizable stream.
MemoryStream stream = new MemoryStream(template.Length);
stream.Write(template, 0, template.Length);
stream.Seek(0L, SeekOrigin.Begin);

using (var doc = WordprocessingDocument.Open(stream, true))
{
    ...
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100