Сопоставить абзац в OpenXML SDK для взаимодействия абзаца в документе Word - PullRequest
0 голосов
/ 08 ноября 2018

Взаимодействие Word происходит безумно медленно, когда я пытаюсь проанализировать текст в документе с более чем 100 страницами. Я переписал свой код для использования OpenXML SDK, который намного быстрее. Моя проблема в том, что, как только я нашел информацию в документе OpenXML, мне нужно найти ее, затем в документе Word и прокрутить к ней главное окно. Для этого мне нужно как-то сопоставить абзац OpenXML с абзацем взаимодействия. Я думал, что абзацы взаимодействия идеально совпадают с абзацами openxml, но я ошибся. На самом деле взаимодействие обычно имеет больше абзацев, чем в OpenXML. Есть ли какая-то хитрость или какая-то информация, которая может помочь мне сопоставить их? Например, я выяснил, что обычно у взаимодействия есть еще 1 пустой абзац после каждой строки в таблице. Поэтому я, вероятно, мог бы использовать эту информацию и помнить об этом, однако я боюсь, что я нашел гораздо больше, чем один случай.

UPDATE

Ниже приведены скриншоты простой надстройки, которую я создал, чтобы продемонстрировать разницу между абзацами interop и openxml в документе Word с простым содержимым, подобным этому:

MS Word Document Sample Затем надстройка извлекает список абзацев взаимодействия и список абзацев OpenXML и показывает их рядом:

Side-by-side comparison

Вот код, который я использовал:

var document = Globals.ThisAddIn.Application.ActiveDocument;

if (document == null)
    return;

var interopParagraphs = document
    .StoryRanges
    .Cast<Range>()
    .SingleOrDefault(r => r.StoryType == WdStoryType.wdMainTextStory)
    .Paragraphs
    .Cast<Paragraph>()
    .Select(p => p.Range.Text);

var openXmlDocument = WordprocessingDocument.FromFlatOpcString(document.Content.WordOpenXML);

if (openXmlDocument == null)
    return;

var openXmlParagraphs = openXmlDocument
    .MainDocumentPart
    .Document
    .Body
    .Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>()
    .Select(p => p.InnerText);

var compareDialog = new CompareForm(interopParagraphs, openXmlParagraphs);
compareDialog.ShowDialog();

1 Ответ

0 голосов
/ 13 марта 2019

Превращаю мой комментарий в ответ.


В случае строк таблицы вы можете проверить, просматриваете ли вы абзац конца строки, используя Range.IsEndOfRowMark .

Это свойство возвращает True, если указанный диапазон свернут и находится в конце строки в таблице, и False, если нет.

Вы также можете использовать Range.Information [WdInformation.wdAtEndOfRowMarker] .

Возвращает значение True, если указанный выбор или диапазон находится в конце строки в таблице

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

Я также заметил, что это не работает, если вы обращаетесь к абзацу напрямую, например, Document.Paragraph [4]. Вы должны перебирать их, чтобы это работало. Кажется, это не задокументировано.

...