Reputation:
I am testing the possible replacement of the EPPlus library in an ASP.Net MVC application written in C# with the Open XML SDK library because of a bug in EPPlus we can't squash with Macro Enabled Spreadsheets. One think I liked about EPPlus was that the I could use this:
public ExcelWorksheet this[string Name] { get; }
to get the worksheet by name. Looking at the definition of the Sheets class in Open XML SDK, there is not a similar construct.
I already have the tab name. I need to get the associated worksheet so I can edit it without looping through all of the sheets each time I need the sheet.
Everything I found has been the opposite, getting the name of a Sheet object. Is there a way to get the Sheet by the tab text in Open XML SDK? OR should I download the source and add this feature to the class?
Upvotes: 3
Views: 13754
Reputation: 2052
You can use below method to get WorkSheet with sheetName.
public static Worksheet GetworksheetBySheetName(string sheetName)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Open(@"C:\Users\Public\Documents\Sheet7.xlsx", true))
{
var workbookPart = document.WorkbookPart;
string relationshipId = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name.Equals(sheetName))?.Id;
var worksheet = ((WorksheetPart)workbookPart.GetPartById(relationshipId)).Worksheet;
return worksheet;
}
}
Upvotes: 3
Reputation:
This answer, however has what I was looking for - How to retrieve Tab names from excel sheet using OpenXML. I'm working on implementing the changes into my application and will post the code then. I wrapped the functionality into a generic utility class based upon that answer.
Utility Class Code:
public static class OpenXMLUtilities
{
public static void UpdateCell(SpreadsheetDocument spreadSheet, string sheetName, DataAccess.Domain.CellType cellType, string value, uint rowIndex, string columnName)
{
WorksheetPart worksheetPart = GetWorksheetPartByName(spreadSheet, sheetName);
if (worksheetPart != null)
{
Cell cell = GetCell(worksheetPart.Worksheet, columnName, rowIndex);
cell.CellValue = new CellValue(value);
switch (cellType)
{
case DataAccess.Domain.CellType.BidLocation:
case DataAccess.Domain.CellType.Constant:
case DataAccess.Domain.CellType.Email:
case DataAccess.Domain.CellType.General:
case DataAccess.Domain.CellType.Industry:
case DataAccess.Domain.CellType.Name:
case DataAccess.Domain.CellType.ProposalNumber:
case DataAccess.Domain.CellType.Department:
case DataAccess.Domain.CellType.Money:
case DataAccess.Domain.CellType.Phone:
cell.DataType = new EnumValue<CellValues>(CellValues.String);
break;
case DataAccess.Domain.CellType.Date:
cell.DataType = new EnumValue<CellValues>(CellValues.Date);
break;
case DataAccess.Domain.CellType.Float:
case DataAccess.Domain.CellType.Integer:
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
break;
case DataAccess.Domain.CellType.YesNoOrBlank:
case DataAccess.Domain.CellType.YesOrNo:
cell.DataType = new EnumValue<CellValues>(CellValues.Boolean);
break;
}
worksheetPart.Worksheet.Save();
}
}
public static WorksheetPart GetWorksheetPartByName(SpreadsheetDocument document, string sheetName)
{
IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>().Where(s => s.Name == sheetName);
if (sheets.Count() == 0)
{
// The specified worksheet does not exist.
return null;
}
string relationshipId = sheets.First().Id.Value;
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId);
return worksheetPart;
}
private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex)
{
Row row = GetRow(worksheet, rowIndex);
if (row == null)
{
return null;
}
return row.Elements<Cell>().Where(c => string.Compare(c.CellReference.Value, columnName + rowIndex, true) == 0).First();
}
private static Row GetRow(Worksheet worksheet, uint rowIndex)
{
return worksheet.GetFirstChild<SheetData>().Elements<Row>().Where(r => r.RowIndex == rowIndex).First();
}
}
Upvotes: 0