2017-02-06 6 views
1

Я пытаюсь создать файл .docx из шаблона слова (.dotx), используя библиотеку OpenXML 2.5. Точнее, я пытаюсь следовать this, но я хочу открыть документ, используя MemoryStream, а не путь к файлу.Open XML SDK - создание docx из шаблона (dotx) с использованием MemoryStream в качестве владельца docx

Итак, в приведенной выше ссылке используется подход: Скопируйте файл шаблона в новый файл на диске. Откройте новый файл как WordProcessingDocument, измените его тип на Документ и добавьте ссылку на шаблон (я не уверен, почему это необходимо ...)

Что мне нужно. Получите мой шаблон из БД в виде массива байтов. Скопируйте массив в поток и откройте его как WordProcessingDocument. Затем сделайте то же самое, что и выше. Я не хочу использовать временные файлы на диске и так далее. Я не понимаю, почему я должен ссылаться на файл шаблона в новом документе (Фактически, проверяя xml-файлы в архиве docx, он просто добавляет узел xml, содержащий имя шаблона ... почему?)

Теперь проблема заключается в том, что если я использую MemoryStream, а не физический путь к файлу, то полученный docx поврежден. Я получаю «Microsoft Office не может открыть этот файл, потому что некоторые части отсутствуют или недействительны». Если я использую временные файлы на диске, он работает. Почему это происходит?

упрощенный, мой код выглядит следующим образом:

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()); 
      } 
    } 

Это заставляет меня поврежденный файл DOCX. Если я переключусь с MemoryStream на открытие нового файла docx с диска (используя другой конструктор класса WordProcessingDocument), он работает. Я не делаю что-то неправильно (например, пытаюсь записать результат в файл после удаления потока памяти), поэтому он должен дать мне тот же результат.

Что не так с моим кодом?

Благодаря

ответ

1

Если взять последнюю строку вашего кода File.WriteAllBytes из внутреннего блока с использованием, она должна работать правильно. Просто поставьте эту строку прямо перед закрывающей скобкой внешнего блока.

+0

Спасибо за ответ, Майкл. Было уже поздно, и я не вижу этого. Вы правы, выйдя из блока использования документа, Open XML сохраняет изменения, а также закрывает/удаляет неуправляемые ресурсы. Поэтому я в основном пытался открыть что-то, что не было полностью спасено. – darkdante