Итерация по документу Word в OpenXml, ввод текста в закладки (потеря форматирования) - PullRequest
3 голосов
/ 16 марта 2012

У меня есть текстовый документ с установленными закладками. Закладки очень просты и не охватывают таблицы или абзацы. Следующий код работает, но я теряю форматирование из документа, и вставка использует шрифт и размер по умолчанию для слова и т. Д. Как я могу просто ввести текст в закладку, сохраняя форматирование документов?

using (var wordDoc = WordprocessingDocument.Open(targetFileName, true))
{
    MainDocumentPart mainPart = wordDoc.MainDocumentPart;

    var bookmarkStarts = mainPart.Document.Descendants<BookmarkStart>().ToList();

    foreach (BookmarkStart bookmarkStart in bookmarkStarts)
    {
      InsertIntoBookmark(bookmarkStart, "Hello");
    }
}

private static void InsertIntoBookmark(BookmarkStart bookmarkStart, string text)
{
    OpenXmlElement elem = bookmarkStart.NextSibling();

    while (elem != null && !(elem is BookmarkEnd))
    {
        OpenXmlElement nextElem = elem.NextSibling();
        elem.Remove();
        elem = nextElem;
    }
    Run run = new Run();
    run.Append(new Text(text));
    bookmarkStart.Parent.InsertAfter<Run>(run, bookmarkStart);
}

Ответы [ 2 ]

0 голосов
/ 03 февраля 2016

Один из вариантов заключается в том, чтобы на самом деле заменить текст в прогоне вместо удаления всего и вставить неформатированный прогон. Однако в Word есть неприятная вещь: у него есть привычка вставлять несколько прогонов для того, что должно быть одним, а иногда даже разбивать одно слово на два или более прогонов.

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

Ваш пример переработан для замены вместо удаления и вставки:

private static void InsertIntoBookmark(BookmarkStart bookmarkStart, string text)
        {
            OpenXmlElement elem = bookmarkStart.NextSibling();
            bool firstRunReplaced = false;
            while (elem != null && !(elem is BookmarkEnd))
            {
                OpenXmlElement nextElem = elem.NextSibling();
                if (elem is Run && !firstRunReplaced)
                {
                    ((Run)elem).Elements<Text>().First().Text = text;
                    firstRunReplaced = true;
                }
                else
                {
                    elem.Remove();
                }
                elem = nextElem;
            }
        }
0 голосов
/ 16 марта 2012

Невозможно напрямую выполнить то, что вы пытаетесь достичь в вашем случае. Закладки не будут содержать никакой информации о форматировании, поэтому при копировании не сохранит никакого форматирования.

Практическое решение заключается в том, чтобы вручную получить форматирование документа по умолчанию и попытаться применить его к абзацу, в который вставляется ваш прогон.

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

...