0
votes

I am trying to generate the word document using open XML plugin in Dot net core by writing code in action result method inside controller like this below

    public IActionResult CreateDocument()
    {
        using (MemoryStream mem = new MemoryStream())
        {
            using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(mem, WordprocessingDocumentType.Document, true))
            {
                wordDoc.AddMainDocumentPart();
                Document doc = new Document();

                //Body body = new Body();

                /// Add header
                MainDocumentPart mainDocPart = wordDoc.MainDocumentPart;

                HeaderPart headerPart1 = mainDocPart.AddNewPart<HeaderPart>("r97");

                Header header1 = new Header();

                Paragraph paragraph1 = new Paragraph() { };
                Run run1 = new Run();
                Text text1 = new Text();
                text1.Text = "This is Header Part";

                run1.Append(text1);
                paragraph1.Append(run1);
                header1.Append(paragraph1);

                headerPart1.Header = header1;

                // getting an error here in this line
                SectionProperties sectionProperties1 = mainDocPart.Document.Body.Descendants<SectionProperties>().FirstOrDefault();  
                if (sectionProperties1 == null)
                {
                    sectionProperties1 = new SectionProperties() { };
                    mainDocPart.Document.Body.Append(sectionProperties1);
                }
                HeaderReference headerReference1 = new HeaderReference() { Type = HeaderFooterValues.Default, Id = "r97" };
                sectionProperties1.InsertAt(headerReference1, 0);
             .......
            ........
            .........
           }
        }
     }

but some how getting an error at this line SectionProperties sectionProperties1 = mainDocPart.Document.Body.Descendants<SectionProperties>().FirstOrDefault();

**Error:** DocumentFormat.OpenXml.Packaging.MainDocumentPart.Document.get returned null.

i am not sure where i am doing wrong with this code, Could any one please suggest any idea on this one

many thanks in advance

2
would any one please let me know where i am doing wrong with thisEnigma State
Well it says that MainDocumentPart.Document == null, so maybe you must add you doc to the mainDocPart?Frank Nielsen
@EnigmaState, have a look at my answer for some hints on how you can improve your code in this specific case and in general when it comes to Open XML.Thomas Barnekow
@ThomasBarnekow thanks for pointing me in right direction i have solved that problemEnigma State

2 Answers

1
votes

You instantiate the mainDocPart variable at this line:
MainDocumentPart mainDocPart = wordDoc.MainDocumentPart;

Then you did not add any document in it. That's why you are got the error: DocumentFormat.OpenXml.Packaging.MainDocumentPart.Document.get returned null.

How to solve it:

mainDocPart.Document = doc; //you define earlier but do not used.
doc.Body = new Body();
SectionProperties sectionProperties1 = 
mainDocPart.Document.Body.Descendants<SectionProperties>()?.FirstOrDefault();  
if (sectionProperties1 == null)
{
    sectionProperties1 = new SectionProperties() { };
    mainDocPart.Document.Body.Append(sectionProperties1);
}

You can get more information about it in this doc page: https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.document?redirectedfrom=MSDN&view=openxml-2.8.1

1
votes

To add to Lutti's answer, you need to understand that the minimum WordprocessingDocument consists of a MainDocumentPart the content of which is at least the following:

<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
  <w:body />
</w:document>

Thus, when you create an "empty" document, you should have at least the following code:

using (var stream = new MemoryStream())
using (WordprocessingDocument wordDocument = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document))
{
    MainDocumentPart mainDocumentPart = wordDocument.AddMainDocumentPart();
    mainDocumentPart.Document = new Document(new Body());
}

Note the correspondence of the w:document and w:body elements with the Document and Body instances.

Using the creation of the header as an example, you can generally streamline your code by combining the constructors and, thus, creating XML markup-like structures as follows:

var headerPart = mainDocumentPart.AddNewPart<HeaderPart>();
headerPart.Header =
    new Header(
        new Paragraph(
            new Run(
                new Text("This is the Header Part"))));

In the above code example, I've laid out the code like you would format the corresponding Open XML markup:

<w:hdr xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
  <w:p>
    <w:r>
      <w:t>This is the Header Part</w:t>
    </w:r>
  </w:p>
</w:hdr>

In my mind, this is much easier to read and, if you understand the Open XML markup required to create the desired outcomes, helps avoid errors.