SDK Openxml. Как искать, читать и заменять текст в абзаце изображением

Я создаю документ Word (.docx) и сталкиваюсь с проблемой вставки диаграмм, изображений вместо пользовательских тегов в уже существующий документ. Но изначально я создаю документ из нескольких файлов .RTF, используя подход «Altchunk», вставляя файлы .RTF в элементы управления содержимым в шаблоне документа. Эти файлы .RTF содержат наши пользовательские теги, они выглядят как «‹ElementType="Diagram" Name="Somename"›" и появляются в документе только с новой строкой, как показано ниже. (И мы не знаем заранее, сколько этих тегов будет в документе) .......

‹ElementType="Diagram" Name="Название диаграммы"›

....... Погуглил, но не нашел хорошего подхода к замене тегов изображениями. Потому что сначала мне нужно прочитать тег, чтобы распознать имя изображения, поэтому я знаю, какое изображение будет идти вместо тега, затем удалите тег (просто текст) из документа и на его место поместите изображение, которое я только что получил, зная имя изображения. Так что это довольно сложно, но я надеюсь, что у кого-то есть хорошие идеи, чтобы поделиться. Спасибо

Я хотел бы описать эту проблему немного более конкретно:

1) Что касается метода altchunk, я просто нахожу элементы управления содержимым, которые я помещаю в документ Word, который я использую в качестве шаблона, и когда у меня есть строка rtf, я вставляю altchunk после этого CC.
мой метод выглядит так: как следующее:

    private void ReplaceContentControlWithRTF(MainDocumentPart mainPart, string tagName,     string rtfString) 
{
                SdtBlock sb = mainPart.Document.Body.Descendants<SdtBlock>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == tagName).Single();
                string altChunkId = "altChunkId" + altChunkIdNumber++;
                AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.Rtf, altChunkId);
                MemoryStream s = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(rtfString));
                chunk.FeedData(s);
                AltChunk altChunk = new AltChunk();
                altChunk.Id = altChunkId;
                DocumentFormat.OpenXml.OpenXmlElement parent = sb.Parent;
                parent.InsertAfter(altChunk, sb);
                sb.Remove();
                mainPart.Document.Save();

}

person Sergio    schedule 27.12.2011    source источник


Ответы (1)


Мой ответ получился довольно длинным, поэтому я разделю содержание некоторыми заголовками, чтобы его было легче читать :). Вы должны рассмотреть каждый из них, если вы уже не нашли лучший подход.

Объединение документов

Я предполагаю, что когда вы используете метод altchunk, у вас есть xml первого документа (исходного), и все добавленные документы закодированы. Лучшим подходом было бы объединение содержимого документов, потому что тогда у вас будет легкий доступ к дереву xml всего документа. Это довольно просто, если вы не используете изображения, гиперссылки и т. д. в объединенных документах, потому что с ними нужно обращаться особым образом, и это может усложнить задачу.

В качестве альтернативы вы можете попробовать вставить изображения в каждый документ ДО их объединения.

Использовать элементы управления контентом в качестве заполнителей в документе

Теперь, предположим, что вы уже можете получить доступ к документу, вы должны разместить элементы управления содержимым в документах Word, в местах, где вы хотите, чтобы ваши изображения отображались, и установить для Tag каждого из них значение, которое вы затем должны искать в своем коде. для того, чтобы найти правильное место для вставки изображения. Основные сведения об элементах управления содержимым можно найти здесь: http://office.microsoft.com/en-us/help/content-controls-HA010030750.aspx.

Вставить теги XML и байты изображения

Чтобы вставить изображение в документ, вам нужно не только вставить некоторые теги XML в то место, где вы хотите, чтобы изображение отображалось, но и добавить байты, содержащие изображение, как ImagePart. Я нашел руководство, объясняющее, как это сделать здесь (хотя сам я не следил за ним): http://msdn.microsoft.com/en-us/library/ee342530%28v=office.12%29.aspx.

Рассмотрите возможность использования инструмента повышения производительности OpenXML SDK 2.0

Чтобы упростить работу с OpenXML SDK, я рекомендую вам использовать SDK Productivity Tool от Microsoft. Его можно загрузить как часть OpenXML SDK, и он позволяет открывать любой документ MS Office OpenXML, отображать его содержимое в формате XML и даже отображать код C#, необходимый для его воссоздания. Его можно загрузить отсюда: http://www.microsoft.com/download/en/details.aspx?id=5124.

Если у вас есть другие вопросы, не стесняйтесь спрашивать :).

person Lukasz M    schedule 27.12.2011
comment
Используйте элементы управления содержимым в качестве заполнителей в документе, да, было бы неплохо знать, где будут отображаться мои изображения, но этот документ предполагается генерировать много раз с разными входными данными (файлы rtf), поэтому я не могу знать, сколько и где будут размещены изображения. Но когда я вставил все файлы rtf, у меня есть файл .docx с пользовательскими тегами, которые выглядят как просто текст в новом абзаце ‹ElementType=Diagram Name=SomeName›. Поэтому я должен найти их, прочитать и заменить соответствующим изображением (я прочитал его имя). - person Sergio; 29.12.2011
comment
Так что я не уверен, в чем твоя проблема. Вы должны сделать это, как вы описали в вопросе;). Прочтите руководство на msdn.microsoft.com/en -us/library/ee342530%28v=office.12%29.aspx. В нем объясняется, как вставить изображение в документ. В основном, когда вы найдете свой собственный тег, удалите его, получите родительский узел pagargaph и вставьте туда тег изображения, а также вставьте часть изображения в документ. Я полагаю, что ссылка содержит довольно подробные инструкции, объясняющие, как вставлять изображения. - person Lukasz M; 30.12.2011
comment
С этим почти покончено, но не могли бы вы дать последнюю подсказку относительно того, как получить ширину полезного пространства страницы? Я предполагаю, что это будет в некоторых единицах, а не в пикселях. - person Sergio; 12.01.2012
comment
Было бы полезно, если бы вы предоставили дополнительную информацию об этом. Если вы хотите определить постоянный размер, я бы порекомендовал вам использовать Open XML SDK Productivity Tool. Если вы хотите поместить изображение в это пространство, сделайте это с помощью Word, сохраните документ, а затем откройте его в инструменте и проверьте, какой размер там используется :). - person Lukasz M; 13.01.2012
comment
Теперь с шириной страницы все в порядке. Но когда я вставил в шаблонный документ все файлы .rtf, используя метод altchunk, описанный выше. Мне нужно пройти все абзацы. И здесь происходят странные вещи. p в mainPart.Document.Body.Descendants‹Paragraph›()), но на самом деле это работает только в том случае, если я обновляю оглавление раньше, если нет, я фактически не получаю все абзацы, кажется, нет абзацев с текстом, вставленным из .RTF. . Когда я открываю целевой документ в Word (не полностью завершенный), я вижу весь текст из RTF. Странно. Я забыл что-то вызвать перед циклом foreach? - person Sergio; 25.01.2012
comment
Кажется, в подходе altchunk есть ошибка, которая вернется, когда будет устранена. - person Sergio; 25.01.2012
comment
Нет, это скорее не баг. Как я уже писал в ответе, если вы используете метод altchunk, вы, вероятно, получите структуру xml только вашего первого документа (того, к которому вы добавили остальные). Приложенные документы сохраняются в результирующем файле в закодированном виде (я полагаю, это строка base64). Чтобы решить эту проблему, вы можете объединить их вручную ИЛИ попытаться использовать обходной путь: отредактируйте каждый из файлов ПЕРЕД их объединением и объедините их после изменения всех абзацев. - person Lukasz M; 25.01.2012