Я пытаюсь создать файл .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
), он работает. Я не делаю что-то неправильно (например, пытаюсь записать результат в файл после удаления потока памяти), поэтому он должен дать мне тот же результат.
Что не так с моим кодом?
Благодаря
Спасибо за ответ, Майкл. Было уже поздно, и я не вижу этого. Вы правы, выйдя из блока использования документа, Open XML сохраняет изменения, а также закрывает/удаляет неуправляемые ресурсы. Поэтому я в основном пытался открыть что-то, что не было полностью спасено. – darkdante