Saving an OpenXML Document (Word) generated from a template

26,089

Solution 1

Are you referring to the OpenXml SDK? Unfortunately, as of OpenXml SDK 2.0, there's no SaveAs method. You'll need to:

  1. Make a temporary copy of your template file, naming it whatever you want.
  2. Perform your OpenXml changes on the above file.
  3. Save the appropriate sections (ie. using the .myWordDocument.MainDocumentPart.Document.Save() method for the main content or someHeaderPart.Header.Save() method for a particular header).

Solution 2

Indeed you can, at least, in OpenXml SDK 2.5. However, watchout to work with a copy of the original file, because changes in the XML will be actually reflected in the file. Here you have the methods Load and Save of my custom class (after removing some validation code,...):

    public void Load(string pathToDocx)
    {
        _tempFilePath = CloneFileInTemp(pathToDocx);
        _document = WordprocessingDocument.Open(_tempFilePath, true);
        _documentElement = _document.MainDocumentPart.Document;
    }    

    public void Save(string pathToDocx)
    {
        using(FileStream fileStream = new FileStream(pathToDocx, FileMode.Create))
        {
            _document.MainDocumentPart.Document.Save(fileStream);
        }
    }

Having "_document" as a WordprocessingDocument instance.

Solution 3

You can use a MemoryStream to write the changes, rather than in the original file. Consequently, you can save that MemoryStream to a new file:

byte[] byteArray = File.ReadAllBytes("c:\\temp\\mytemplate.docx");
using (var stream = new MemoryStream())
{
    stream.Write(byteArray, 0, byteArray.Length);
    using (var wordDoc = WordprocessingDocument.Open(stream, true))
    {
       // Do work here
       // ...
       wordDoc.MainDocumentPart.Document.Save(); // won't update the original file 
    }
    // Save the file with the new name
    stream.Position = 0;
    File.WriteAllBytes("C:\\temp\\newFile.docx", stream.ToArray()); 
}
Share:
26,089
DilbertDave
Author by

DilbertDave

Just a regular programmer trying to keep afloat in the seas of technology. There are 10 types of people in the world, those who understand binary and those who don't!

Updated on May 29, 2020

Comments

  • DilbertDave
    DilbertDave almost 4 years

    I have a bit of code that will open a Word 2007 (docx) document and update the appropriate CustomXmlPart (thus updating the Content Controls in the document itself as they are mapped to the CustomXmlPart) but can't work out how to save this as a new file.! Surely it can't be that hard!

    My current thinking is that I need to open the template and copy the content into a new, blank document - file by file, updating the CustomXmlPart when I encounter it. Call me old fashioned but that sounds a little bit clunky to me!

    Why can't I just do a WordprocessingDocument.SaveAs(filename); ...?

    Please tell me I am missing something simple here.

    Thanks in advance

  • DilbertDave
    DilbertDave over 14 years
    That's pretty much what I ended up doing - seems a bit of an omission to me. If you open a document and modify it then it stands to reason that you might want to save the updated version with a different name.
  • Pablo Romeo
    Pablo Romeo almost 11 years
    The same can be accomplished if you read the file into MemoryStreams correct? I mean to avoid making copies of the file.
  • Ahmad Mageed
    Ahmad Mageed almost 11 years
    @PabloRomeo I think that might be possible, but it's not an approach I tried back when I was working with OpenXml. You can probably work with the MemoryStream then save it to a desired file name in the end, if that's the goal. These links might help: Working with In-Memory Open XML Documents and Trouble with OpenXML and MemoryStreams?