Open XML SDK 2.0 для доступа к листу Excel 2010 по названию
У меня есть электронная таблица Excel 2010, которая имеет 3 листа с именем Sheet1, Sheet2 и Sheet3.
Я пытаюсь получить ссылку на рабочий лист по имени.
Я использую код:
using (SpreadsheetDocument myWorkbook = SpreadsheetDocument.Open(FileName, true))
{
//Access the main Workbook part, which contains all references
WorkbookPart workbookPart = myWorkbook.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.Last();
// this gives me Sheet1
SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
}
Я пытаюсь получить ссылку на Sheet2, но я не могу найти способ сделать это.
Я приближаюсь, но я еще не там:
var x = workbookPart.Workbook.Sheets.Where(s=> s.GetAttribute("name", "").Value == "Sheet2").FirstOrDefault();
Это дает мне ссылку на лист, но не на данные на листе
Спасибо
Ответы
Ответ 1
Что вам действительно нужно, это WorksheetPart
, который содержит SheetData
, который вы ищете. Захват Sheets
под Workbook
даст вам определенные метаданные о листах. Вот пример того, как захватить этот WorksheetPart
(не стесняйтесь добавлять проверку ошибок, как вы сочтете нужным, поскольку я предполагаю, что sheetName
уже существует, вызывая First
, а не FirstOrDefault
)
public WorksheetPart GetWorksheetPart(WorkbookPart workbookPart, string sheetName)
{
string relId = workbookPart.Workbook.Descendants<Sheet>().First(s => sheetName.Equals(s.Name)).Id;
return (WorksheetPart)workbookPart.GetPartById(relId);
}
Затем просто используйте свой код выше, чтобы получить правильную ссылку SheetData, и вы сможете найти нужные вам данные.
Ответ 2
Вот несколько кодов для обработки электронной таблицы с определенным именем вкладки или листа и сбрасыванием ее на что-то вроде CSV. (Я выбрал трубку вместо запятой).
Мне хотелось бы получить значение из ячейки, но я думаю, что это то, с чем мы застряли. Вы можете видеть, что я ссылаюсь на документы MSDN, где я получил большую часть этого кода. Это то, что рекомендует Microsoft.
/// <summary>
/// Got code from: https://msdn.microsoft.com/en-us/library/office/gg575571.aspx
/// </summary>
[Test]
public void WriteOutExcelFile()
{
var fileName = "ExcelFiles\\File_With_Many_Tabs.xlsx";
var sheetName = "Submission Form"; // Existing tab name.
using (var document = SpreadsheetDocument.Open(fileName, isEditable: false))
{
var workbookPart = document.WorkbookPart;
var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == sheetName);
var worksheetPart = (WorksheetPart)(workbookPart.GetPartById(sheet.Id));
var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
foreach (var row in sheetData.Elements<Row>())
{
foreach (var cell in row.Elements<Cell>())
{
Console.Write("|" + GetCellValue(cell, workbookPart));
}
Console.Write("\n");
}
}
}
/// <summary>
/// Got code from: https://msdn.microsoft.com/en-us/library/office/hh298534.aspx
/// </summary>
/// <param name="cell"></param>
/// <param name="workbookPart"></param>
/// <returns></returns>
private string GetCellValue(Cell cell, WorkbookPart workbookPart)
{
if (cell == null)
{
return null;
}
var value = cell.CellFormula != null
? cell.CellValue.InnerText
: cell.InnerText.Trim();
// If the cell represents an integer number, you are done.
// For dates, this code returns the serialized value that
// represents the date. The code handles strings and
// Booleans individually. For shared strings, the code
// looks up the corresponding value in the shared string
// table. For Booleans, the code converts the value into
// the words TRUE or FALSE.
if (cell.DataType == null)
{
return value;
}
switch (cell.DataType.Value)
{
case CellValues.SharedString:
// For shared strings, look up the value in the
// shared strings table.
var stringTable =
workbookPart.GetPartsOfType<SharedStringTablePart>()
.FirstOrDefault();
// If the shared string table is missing, something
// is wrong. Return the index that is in
// the cell. Otherwise, look up the correct text in
// the table.
if (stringTable != null)
{
value =
stringTable.SharedStringTable
.ElementAt(int.Parse(value)).InnerText;
}
break;
case CellValues.Boolean:
switch (value)
{
case "0":
value = "FALSE";
break;
default:
value = "TRUE";
break;
}
break;
}
return value;
}