Изменение документа OpenXML Word через API И манипулирование текстом

Я работаю над прототипами, чтобы заменить существующую систему, основанную на автоматизации слов для рендеринга шаблонов, и в настоящее время оцениваю OpenXML SDK. Библиотека шаблонов довольно обширна (150-200 шаблонов, поддерживаемых нетехническими ресурсами), поэтому я надеюсь избежать каких-либо изменений шаблонов, кроме обновления формата слова 1997-2003 годов.

Теги, встроенные в настоящее время, необходимо иногда заменять текстом, а иногда изображениями/диаграммами/и т. д. (сейчас предположим, что все диаграммы будут преобразованы в изображения перед вставкой).

Я могу выполнить прямую замену текста, используя метод, аналогичный описанному в этом статья MSDN. Мой сценарий немного сложнее, но выглядит примерно так:

    public void ReplaceFirstOccurrenceWithText(string tagBody, string replacement)
    {
        var modifiedText = GetCurrentText();
        modifiedText = modifiedText.ReplaceFirst(tagBody, XmlEncoder.Encode(replacement));
        using (var sw = new StreamWriter(document.MainDocumentPart.GetStream(FileMode.Create)))
        {
            sw.Write(modifiedText);
        }
    }

    public string GetCurrentText()
    {
        using(var reader = new StreamReader(document.MainDocumentPart.GetStream()))
        {
            return reader.ReadToEnd();
        }
    }

Причина, по которой я не сохраняю строку, заключается в том, что я хочу, чтобы базовый документ оставался актуальным, чтобы я мог добавлять изображения через обычный API. Используя метод, описанный в другой статье MSDN:

    public void ReplaceFirstOccurrenceWithImage(string tagBody, byte[] replacement)
    {
        ReplaceFirstOccurrenceWithText(tagBody, "IMAGE TAG WAS HERE!");
        var main = document.MainDocumentPart;
        var imagePart = main.AddImagePart(ImagePartType.Gif);//sniff this by loading bytes into a bitmap
        using(var imageStream = new MemoryStream(replacement))
        {
            imagePart.FeedData(imageStream);
        }

        ImageInserter.AddImageToBody(document, main.GetIdOfPart(imagePart));
    }

Где ImageInserter буквально копирует/вставляет код из этой статьи (я понимаю, что эти абстракции не самые лучшие, но я просто пытаюсь заставить что-нибудь работать на данный момент).

Вот тут-то и становится не по себе — документ ПОКАЗЫВАЕТСЯ синхронизированным. Изображение — это первый тег, который заменяется, и замена текста для тега работает, как и добавление изображения в нижней части документа. Моя проблема в том, что после этого момента последующая замена текста вообще не работает - все остальные теги остаются в документе. Однако, если я устанавливаю точку останова в функции замены текста, каждый вызов .GetCurrentText() возвращает правильный результат (текст с замененными тегами до этой точки). Но когда я сохраняю документ, он сохраняется только с первой заменой.

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


person AlexCuse    schedule 20.07.2012    source источник


Ответы (1)


Если бы я был с тобой, я бы посмотрел

http://docx.codeplex.com

это намного проще для общих вещей.. может быть, вы делаете что-то более сложное, чем может обработать библиотека, но я бы определенно взглянул на это.

person Micah Armantrout    schedule 20.07.2012
comment
Спасибо - я подозреваю, что он может не справиться с некоторыми из более сложных сценариев (я еще даже не пытался вставить изображение в правильное место в документе), но это определенно стоит изучить. По крайней мере, это избавит меня от необходимости ломать голову над OpenXML API. - person AlexCuse; 20.07.2012
comment
Да, я заметил - мне удалось заставить работать замену текста в DocX, так как я прочитал ваш комментарий, и кажется имеет неплохую поддержку для работы с изображениями, поэтому я скрещиваю пальцы, что это будет Работа. Из-за проблем с контролем качества я все еще предпочитаю aspose (позволяет нам обновлять шаблоны с течением времени), но я рад, что есть приличная оболочка, подобная этой! - person AlexCuse; 20.07.2012
comment