Search code examples
c#uwpopenxml-sdkwordprocessingml

Generate Doc file using OPEN-XML SDK in UWP


I want to Create a Microsoft Word Document in my UWP App and I've successfully created doc file in APP Local folder. But i want to create this doc file in a specific folder location chosen by user.

I mean user browse a location and then create doc file into that location.

Here is my code to create Doc file in App local Path:

  string docFileName = "TestDoc.docx";
  Windows.Storage.StorageFolder localFolder = Windows.Storage.ApplicationData.Current.LocalFolder;

  string Filepath = localFolder.Path + "\\" + docFileName;

  using (var wordprocessingDocument = WordprocessingDocument.Create(file.Path, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
  {
      MainDocumentPart mainPart = wordprocessingDocument.AddMainDocumentPart();
      mainPart.Document = new DocumentFormat.OpenXml.Wordprocessing.Document();
      Body body = mainPart.Document.AppendChild(new Body());
      DocumentFormat.OpenXml.Wordprocessing.Paragraph para = body.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Paragraph());
      DocumentFormat.OpenXml.Wordprocessing.Run run = para.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Run());
      run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text("Hello !!! ."));
      wordprocessingDocument.MainDocumentPart.Document.Save();
  }

I've got below error while trying to create doc file in a specific location like below:

Error

Message=The media is write protected : 'D:\Training\TestDoc.docx'

Code

string path = @"D:\Training\TestDoc.docx";

using (var wordprocessingDocument = WordprocessingDocument.Create(path, DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
{
    MainDocumentPart mainPart = wordprocessingDocument.AddMainDocumentPart();
    mainPart.Document = new DocumentFormat.OpenXml.Wordprocessing.Document();
    Body body = mainPart.Document.AppendChild(new Body());
    DocumentFormat.OpenXml.Wordprocessing.Paragraph para = body.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Paragraph());
    DocumentFormat.OpenXml.Wordprocessing.Run run = para.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Run());
    run.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Text("Hello !!! ."));
    wordprocessingDocument.MainDocumentPart.Document.Save();
}

Solution

  • Because UWP apps run in a sandbox, you cannot directly access filesystem paths using classic APIs. However, you can use Windows.Storage APIs to do so.

    Let user choose the save file

    If you want to let the user choose the save file, you can use the FileSavePicker API. This Docs page describes this in detail. Once done, the API will give you a StorageFile instance, which you can use.

    Write in the file

    As you cannot use the Create method which takes a file path as an argument, you need to use the Stream based one instead.

    To get a Stream instance from the file, add using System.IO; to the top of your code file and then do:

    using(var stream = await file.OpenStreamForWriteAsync())
    

    With this stream you can then do:

    using (var wordprocessingDocument =
                   WordprocessingDocument.Create(
                      stream, WordprocessingDocumentType.Document))
    {
          //... your code
    }
    

    Note: Broad filesystem access

    If you really need to create the file at an arbitrary (not user selected) location, you can use the broadFileSystemAccess capability. This is however only for apps that really require it. Note, that even with this capability, you still need to perform all file operations using the StorageFile and StorageFolder APIs.