Как получить части верхнего и нижнего колонтитулов из документа Excel

#excel #openxml #openxml-sdk

#excel #openxml #openxml-sdk

Вопрос:

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

Я думал, что это будет довольно просто… Рассмотрим этот код:

 using (SpreadsheetDocument spreadsheet = SpreadsheetDocument.Open(filePath, true))
{
    var headers = spreadsheet.GetPartsOfType<HeaderPart>().ToList();

    foreach (var header in headers)
    {
        //do something
    }
}
  

Даже с файлом, который содержит заголовок, заголовки всегда будут пустыми. Я попытался углубиться в workbook -> worksheets -> etc , но ничего не получил взамен. В моем тестовом файле Excel определенно есть заголовок (заголовки ужасны в Excel!).

К сожалению, API для Excel в openxml, похоже, хуже, так как в docx вы можете получить заголовок, вызвав:

 using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(filePath, true))
{
    MainDocumentPart documentPart = wordDoc.MainDocumentPart;

    var headerParts = wordDoc.MainDocumentPart.HeaderParts.ToList();

    foreach (var headerPart in headerParts)
    {
        //do something
    }
} 
  

Я видел, как некоторые люди в Google говорили, что я должен запросить потомков листа (код по этой ссылке):

 HeaderFooter hf = ws.Descendants<HeaderFooter>().FirstOrDefault();
if (hf != null)
{
//here you can add your code
//I just try to append here for demo
  hf = new HeaderFooter();
  ws.AppendChild<HeaderFooter>(hf);
}
  

Но я не вижу никакого способа запросить рабочую книгу / лист / что-либо с помощью .Descendants и, очевидно, ни один из примеров кода в Google не показывает, как они получили ws 🙃.

Есть идеи? Спасибо

Комментарии:

1. В VBA доступ к заголовкам должен осуществляться через LeftHeader , CenterHeader и RightHeader , а к нижним колонтитулам — через LeftFooter , CenterFooter и RightFooter , возможно, вам нужно что-то подобное?

Ответ №1:

HeaderFooter согласно вашему второму примеру, это правильный способ чтения верхнего и нижнего колонтитулов из электронной таблицы с использованием OpenXML. ws В вашем примере относится к Worksheet .

Ниже приведен пример, который считывает HeaderFooter и выгружает InnerText на консоль.

 using (SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, false))
{
    WorkbookPart workbookPart = document.WorkbookPart;
    WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
    Worksheet ws = worksheetPart.Worksheet;

    HeaderFooter hf = ws.Descendants<HeaderFooter>().FirstOrDefault();

    if (hf != null)
    {
        Console.WriteLine(hf.InnerText);
    }
}
  

Я бы настоятельно рекомендовал вам ознакомиться с документацией по HeaderFooter элементу, поскольку он сложнее, чем вы можете себе представить. Документацию можно найти в разделе 18.3.1.46 пятого издания Ecma Office Open XML, часть 1 — Основы и справочник по языку разметки, который можно найти здесь.

Комментарии:

1. Я действительно пытался ws.Descendants<HeaderFooter>().FirstOrDefault(); перед публикацией этого вопроса, но он возвращает null. Я смог получить это, выполнив ws.ChildElements.Where(c => c.GetType() == typeof(HeaderFooter)) . Я согласен, это сложно, я смог прочитать верхний и нижний колонтитулы и прочитать / заменить значения. Получение этого было ужасным процессом, и я почти испытываю искушение написать библиотеку-оболочку, чтобы другим людям не приходилось страдать от использования open xml….