#c# #xml #ms-word #openxml
#c# #xml #ms-word #openxml
Вопрос:
Я должен использовать OpenXML SDK 2.5 с C #, чтобы копировать формулы из одного документа Word, а затем добавлять их в другой документ word. Я попробовал приведенный ниже код, он успешно запустился, но когда я попытался открыть файл, он сказал, что с содержимым что-то не так. Я открыл его, игнорируя предупреждение, но эти формулы не отображались. Это просто пустые блоки.
Мой код:
private void CreateNewWordDocument(string document, Exercise[] exercices)
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Create(document, WordprocessingDocumentType.Document))
{
// Set the content of the document so that Word can open it.
MainDocumentPart mainPart = wordDoc.AddMainDocumentPart();
SetMainDocumentContent(mainPart);
foreach (Exercise ex in exercices)
{
wordDoc.MainDocumentPart.Document.Body.AppendChild(ex.toParagraph().CloneNode(true));
}
wordDoc.MainDocumentPart.Document.Save();
}
}
// Set content of MainDocumentPart.
private void SetMainDocumentContent(MainDocumentPart part)
{
string docXml =
@"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>
<w:document xmlns:w=""http://schemas.openxmlformats.org/wordprocessingml/2006/main"">
<w:body><w:p><w:r><w:t>Exercise list!</w:t></w:r></w:p></w:body>
</w:document>";
using (Stream stream = part.GetStream())
{
byte[] buf = (new UTF8Encoding()).GetBytes(docXml);
stream.Write(buf, 0, buf.Length);
}
}
Комментарии:
1. Немного сложно ответить, не зная, каково содержание вашего упражнения []-array .
2. Объект Exercise содержит абзац, на этом пока все. В приведенном выше коде единственным использованием объекта exercise является «ex.toParagraph()», который возвращает этот абзац. Я надеюсь, что кто-нибудь может показать мне решение. Я застрял с этой проблемой.
Ответ №1:
Это происходит потому, что не все, на что можно ссылаться в абзаце, копируется при клонировании абзаца. Формат Word XML состоит из нескольких файлов, некоторые из которых ссылаются друг на друга. Если вы копируете абзац из одного документа в другой, вам также необходимо скопировать любые связи, которые могут существовать.
Инструмент повышения производительности OpenXML полезен для диагностики подобных ошибок. Вы можете открыть документ с помощью инструмента и попросить его проверить документ.
Я создал тестовый документ, который просто содержал гиперссылку, и запустил ваш код для копирования содержимого в другой документ. Я тоже получил сообщение об ошибке, когда попытался загрузить его с помощью Word, поэтому я открыл его в инструменте повышения производительности и увидел следующий вывод:
Это показывает, что гиперссылка хранится как связь, а не встроена в абзац, и мой новый файл ссылается на связь, которая не существует. Распаковка исходного файла и нового файла и сравнение двух показывает, что происходит: document.xml
из оригинала:
.rels
оригинала
document.xml
сгенерированного файла
.rels
сгенерированного файла
Обратите внимание, что в сгенерированном файле гиперссылка ссылается на отношение rId5, но оно не существует в сгенерированном файле отношений documents.
Стоит отметить, что для простых исходных документов код работал без проблем, поскольку нет связей, требующих копирования.
Есть два способа, которыми вы можете решить эту проблему. Самый простой способ — скопировать только текст абзаца (вы потеряете все стили, изображения, гиперссылки и т.д.), Но это очень просто. Все, что вам нужно сделать, это изменить
wordDoc.MainDocumentPart.Document.Body.AppendChild(ex.toParagraph().CloneNode(true));
для
Paragraph para = wordDoc.MainDocumentPart.Document.Body.AppendChild(new Paragraph());
Run run = para.AppendChild(new Run());
run.AppendChild(new Text(ex.toParagraph().InnerText));
Более сложный (и, возможно, правильный) способ добиться этого — найти взаимосвязи и скопировать их также в новый документ. Код для этого, вероятно, выходит за рамки того, что я могу написать здесь, но здесь есть интересная статья на эту тему http://blogs.msdn.com/b/ericwhite/archive/2009/02/05/move-insert-delete-paragraphs-in-word-processing-documents-using-the-open-xml-sdk.aspx.
По сути, автор этого сообщения в блоге использует Powertools для OpenXML для поиска взаимосвязей и копирования их из одного документа в другой.
Комментарии:
1. Спасибо, петелиды, вы только что открыли для меня ворота. Однако совпадают ли уравнение и изображение с гиперссылкой? Есть ли что-нибудь, на что вы бы посоветовали мне обратить внимание?
2. @vutran — Я думаю, что проблема с уравнениями может быть в шрифте. Я создал небольшой тестовый файл, который создал связь с fontTable.xml досье. Изображения хранятся в отдельной папке мультимедиа.