Текст закладки замены в использовании файла Word Открывает XML SDK

Я предполагаю, что v2.0 лучше..., у них есть некоторые хорошие, "как to:..." примеры, но закладки, кажется, не действуют так, очевидно, как говорят, что Таблица... закладка определяется двумя элементами XML BookmarkStart & BookmarkEnd. У нас есть некоторые шаблоны с текстом в как закладки, и мы просто хотим заменить закладки некоторым другим текстом... никакое странное форматирование не продолжается, но как я выбираю/заменяю текст закладки?

19
задан Mr. Boy 22 July 2010 в 11:27
поделиться

3 ответа

Вот мой подход после того, как вы, ребята, вдохновились:

  IDictionary<String, BookmarkStart> bookmarkMap = 
      new Dictionary<String, BookmarkStart>();

  foreach (BookmarkStart bookmarkStart in file.MainDocumentPart.RootElement.Descendants<BookmarkStart>())
  {
      bookmarkMap[bookmarkStart.Name] = bookmarkStart;
  }

  foreach (BookmarkStart bookmarkStart in bookmarkMap.Values)
  {
      Run bookmarkText = bookmarkStart.NextSibling<Run>();
      if (bookmarkText != null)
      {
          bookmarkText.GetFirstChild<Text>().Text = "blah";
      }
  }
16
ответ дан 30 November 2019 в 03:43
поделиться

Я разобрался в этом 10 минут назад, так что простите за халтурный характер кода.

Сначала я написал вспомогательную рекурсивную функцию для поиска всех закладок:

private static Dictionary<string, BookmarkEnd> FindBookmarks(OpenXmlElement documentPart, Dictionary<string, BookmarkEnd> results = null, Dictionary<string, string> unmatched = null )
{
    results = results ?? new Dictionary<string, BookmarkEnd>();
    unmatched = unmatched ?? new Dictionary<string,string>();

    foreach (var child in documentPart.Elements())
    {
        if (child is BookmarkStart)
        {
            var bStart = child as BookmarkStart;
            unmatched.Add(bStart.Id, bStart.Name);
        }

        if (child is BookmarkEnd)
        {
            var bEnd = child as BookmarkEnd;
            foreach (var orphanName in unmatched)
            {
                if (bEnd.Id == orphanName.Key)
                    results.Add(orphanName.Value, bEnd);
            }
        }

        FindBookmarks(child, results, unmatched);
    }

    return results;
}

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

var bookMarks = FindBookmarks(doc.MainDocumentPart.Document);

foreach( var end in bookMarks )
{
    var textElement = new Text("asdfasdf");
    var runElement = new Run(textElement);

    end.Value.InsertAfterSelf(runElement);
}

Насколько я могу судить, вставка и замена закладок выглядит сложнее. Когда я использовал InsertAt вместо InsertIntoSelf, я получил: "Некомпозитные элементы не имеют дочерних элементов". YMMV

4
ответ дан 30 November 2019 в 03:43
поделиться

Вот как я делаю это в VB.NET:

For Each curBookMark In contractBookMarkStarts

      ''# Get the "Run" immediately following the bookmark and then
      ''# get the Run's "Text" field
      runAfterBookmark = curBookMark.NextSibling(Of Wordprocessing.Run)()
      textInRun = runAfterBookmark.LastChild

      ''# Decode the bookmark to a contract attribute
      lines = DecodeContractDataToContractDocFields(curBookMark.Name, curContract).Split(vbCrLf)

      ''# If there are multiple lines returned then some work needs to be done to create
      ''# the necessary Run/Text fields to hold lines 2 thru n.  If just one line then set the
      ''# Text field to the attribute from the contract
      For ptr = 0 To lines.Count - 1
          line = lines(ptr)
          If ptr = 0 Then
              textInRun.Text = line.Trim()
          Else
              ''# Add a <br> run/text component then add next line
              newRunForLf = New Run(runAfterBookmark.OuterXml)
              newRunForLf.LastChild.Remove()
              newBreak = New Break()
              newRunForLf.Append(newBreak)

              newRunForText = New Run(runAfterBookmark.OuterXml)
              DirectCast(newRunForText.LastChild, Text).Text = line.Trim

              curBookMark.Parent.Append(newRunForLf)
              curBookMark.Parent.Append(newRunForText)
          End If
      Next
Next
0
ответ дан 30 November 2019 в 03:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: