daneejela
daneejela

Reputation: 14233

Creating a word document (docx) with OpenXml

Let me start by saying that I have read other similar questions, but the solution (copied below) just doesn't work for me.

I am trying to create a word document (docx) with .net core and OpenXMl (using DocumentFormat.OpenXml 2.7.2 nuget package) . Looks trivial, but somehow it doesn't work. When I try to open the document, I get the error that file is corrupted, truncated or in incorrect format.

Here is my code (I found it in the numerous tutorials):

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.IO;

public Stream GetDocument()
        {
            var stream = new MemoryStream();

            using (WordprocessingDocument doc = WordprocessingDocument.Create(stream, WordprocessingDocumentType.Document, true))
            {
                MainDocumentPart mainPart = doc.AddMainDocumentPart();

                new Document(new Body()).Save(mainPart);

                Body body = mainPart.Document.Body;
                body.Append(new Paragraph(
                            new Run(
                                new Text("Hello World!"))));

                mainPart.Document.Save();

            }
            stream.Seek(0, SeekOrigin.Begin);

            return stream;

        }

Ad save it like this:

 public static void Test()
        {
            DocxWriter writer = new DocxWriter();

            string filepath = Directory.GetCurrentDirectory() + @"/test.docx";

            var stream = writer.GetDocument();

            using (var fileStream = new FileStream(filepath, FileMode.Create, FileAccess.Write))
            {
                stream.CopyTo(fileStream);
            }

            stream.Dispose();
        }

EDIT: After I extract the docx I can find an underlying xml looking like this:

<?xml version="1.0" encoding="utf-8"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
    <w:body>
        <w:p>
            <w:r>
                <w:t>Hello World!</w:t>
            </w:r>
        </w:p>
    </w:body>
</w:document>

Upvotes: 3

Views: 14053

Answers (2)

VDN
VDN

Reputation: 737

So my solution looks like this. I have few global variables:

private MemoryStream _Ms;
private WordprocessingDocument _Wpd;

Then the creation method looks like this:

public Doc()
{
    _Ms = new MemoryStream();
    _Wpd = WordprocessingDocument.Create(_Ms, WordprocessingDocumentType.Document, true);
    _Wpd.AddMainDocumentPart();
    _Wpd.MainDocumentPart.Document = new DocumentFormat.OpenXml.Wordprocessing.Document();
    _Wpd.MainDocumentPart.Document.Body = new Body();
    _Wpd.MainDocumentPart.Document.Save();
    _Wpd.Package.Flush(); // _Wpd.Dispose();
}

And the save method looks like this:

public void SaveToFile(string fullFileName)
{
    _Wpd.MainDocumentPart.Document.Save();

    _Wpd.Package.Flush();

    _Ms.Position = 0;
    var buf = new byte[_Ms.Length];
    _Ms.Read(buf, 0, buf.Length);

    using (FileStream fs = new System.IO.FileStream(fullFileName, System.IO.FileMode.Create))
    {
        fs.Write(buf, 0, buf.Length);
    }
}

And it works fine. Try this.

Upvotes: 3

daneejela
daneejela

Reputation: 14233

For anyone else having this issue - it's a bug in open-xml-sdk, reported here: https://github.com/OfficeDev/Open-XML-SDK/issues/249

Looks like there was a problem in the _rels/.rels hidden file with the paths, putting an extra backslash that caused problems on the mac.

My current fix/hack was to use an existing empty doc as a template.

Upvotes: 2

Related Questions