I am trying to create a .docx file from a word template (.dotx
), using OpenXML
2.5 library. More exactly, I'm trying to follow this , but I want to open the document using a MemoryStream
and not the path to the file.
So in the link above, the approach is this: Copy the template file in a new file on disk. Open the new file as a WordProcessingDocument
, change its type to Document and add a reference to the template (I'm not sure of why is this necessary ...)
What I need is. Get my template from the DB as byte array. Copy the array to a stream and open it as a WordProcessingDocument
. Then do the same thing as above.
I don't want to use temporary files on disk and so on. What I don;t understand is why should I reference the template file in the new document (Actually, inspecting the xml files in the docx archive, it just adds a xml node containing the name of the template... why?)
Now, my problem is that if I use a MemoryStream
and not a physical path to the file, the resulting docx is corrupted. I'm getting "Microsoft office cannot open this file because some parts are missing or invalid".
If I use temporary disk files, it works.
Why is this happening?
Simplified, my code looks like this:
byte[] result = null;
byte[] templateBytes = System.IO.File.ReadAllBytes("template.dotx");
using (MemoryStream templateStream = new MemoryStream())
{
templateStream.Write(templateBytes, 0, (int)templateBytes.Length);
using (WordprocessingDocument doc = WordprocessingDocument.Open(templateStream, true))
{
doc.ChangeDocumentType(WordprocessingDocumentType.Document);
var mainPart = doc.MainDocumentPart;
//Here I should create an AttachedTemplate object and assign a relationship id to it, which also implies
//setting a "reference" to the template ? I'm not using files so there's nothing to "reference" anyway
// If it's doing more than just putting a visual reference to the template file, then why limit the way of referencing the template
// only by using the Uri to the file? Please take a look at the above link to see what I'm referring to.
//Write some text in the file ....
mainPart.Document.Save();
File.WriteAllBytes("Result.docx", templateStream.ToArray());
}
}
This gets me a corrupted docx file. If I switch from MemoryStream
to opening the new docx file from disk (using the other constructor of the WordProcessingDocument
class), it works.
I'm not doing something wrong (like trying to write the result to the file after disposing the memory stream), so it should give me the same result.
What is wrong with my code?
Thanks
If you take the last line of your code File.WriteAllBytes out of the inner using block, it should work correctly. Just put that line right before the closing brace of the outer using block.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With