#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….