Back after such a long time. But with some useful information.
Recently was exploring OpenXML sdk.
Its available as NuGet package. And can be installed directly from Visual studio package manager console.
I was trying to resolve a problem to update a cell by identifying its location based on the keyName. I found many solution on web to read and update any cell value by passing the exact cell reference.
But I just wanted to pass a keyName to identify the cell and update its corresponding value in sheet. I just wanted to pass Name of the test and then read or update the value.
One thing which we need to keep in mind is that when you are trying to read a particular value it has to be unique like my test names. If not then the sdk will pick up the first matched text.
I created a simple console application to pass the required data to the following helper method
Now lets focus on each line an options :
using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(filename, true))
The parameter 'true' or 'false' decides if document is being opened for editing it.
If you just want to read values from document just pass it as 'false'.
var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == "Results");
The above line is just to find the sheet in the document. Now here is a common sense trick to read large document. If you want to read a large document with several worksheets in it then pass this as parameter to this method and iterate through it.
As the SDK also uses the .NET Framework Language-Integrated Query (LINQ) technology to provide strongly typed object access to the XML content inside the parts of Open XML documents, its very easy to access the inner elements and update them if you need to.
So next few lines are trying to get to the cell level.
var workSheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
var sharedStringPart = workbookPart.SharedStringTablePart;
var values = sharedStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
var cells = workSheetPart.Worksheet.Descendants<Cell>();
Now we need to loop through cells to find the value we are looking for.
Now cell can have text values, numbers or formula. So if cell contains a string input which is not formula then we are doing following task:
if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
{
var index = int.Parse(cell.CellValue.Text);
if (values[index].InnerText == keyName)
{
var nextCell = cell.NextSibling<Cell>();
keyValue = nextCell.InnerText;
return keyValue;
}
}
If you want to read numbers then
if (cell.CellValue != null && cell.CellValue.Text == keyName)
{
var nextCell = cell.NextSibling<Cell>();
keyValue = nextCell.InnerText;
return keyValue;
}
Now the next one which I have not highlighted in the above code( As I was just trying to read keyValue) is to get the formula applied on any cell.
if (cell.CellFormula != null)
Now coming back to my example
Have a look at NextSibling method. It is used to traverse through columns if you have identified your row based on the keyName you passed.
var nextCell = cell.NextSibling<Cell>();
So if I will pass Test1 as keyName then nextCell will give me cell B2 and then nextCell.InnerText will return 10.
What if I want to access the actual value Cells (C2) ? Here it is, a basic LINQ concept:
var nextCell = cell.NextSibling().NextSibling<Cell>();
keyValue = nextCell.InnerText;
Now this is all about reading cell values. Lets see how to update cell value
Updating a cell Value
First of all the sheet need to be opened in editable mode as explained above.
Here I have tried updating the value of C2 cell to newValue. As this is numerical value so have used CellValues.Number.
if (cell.CellValue != null && cell.CellValue.Text == keyValue)
{
var nextCell = cell.NextSibling().NextSibling<Cell>();
nextCell.CellValue = new CellValue(newValue);
nextCell.DataType = new EnumValue<CellValues>(CellValues.Number);
workbookPart.Workbook.Save();
}
If you want to update text value then
CellValues has got enums like Boolean, Number, Error, SharedString, String, InlineString, Date.
And finally don't forget to Save the Workbook.
Sample Code:
/// <summary>
/// Reads the excel.
/// </summary>
/// <param name="keyName">Name of the key.</param>
/// <returns>Key Value</returns>
public string ReadExcel(string keyName)
{
string filename = ConfigurationManager.AppSettings.Get("C:/Logfile.xlsx");
string keyValue = string.Empty;
using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(filename, false))
{
var workbookPart = spreadSheetDocument.WorkbookPart;
var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == "Results");
if (sheet == null)
{
throw new InvalidOperationException("Unable to find the Results sheet");
}
var workSheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
var sharedStringPart = workbookPart.SharedStringTablePart;
var values = sharedStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
var cells = workSheetPart.Worksheet.Descendants<Cell>();
foreach (var cell in cells)
{
if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
{
var index = int.Parse(cell.CellValue.Text);
if (values[index].InnerText == keyName)
{
var nextCell = cell.NextSibling<Cell>();
keyValue = nextCell.InnerText;
return keyValue;
}
}
if (cell.CellValue != null && cell.CellValue.Text == keyName)
{
var nextCell = cell.NextSibling<Cell>();
keyValue = nextCell.InnerText;
return keyValue;
}
}
return keyValue;
}
}
Recently was exploring OpenXML sdk.
Its available as NuGet package. And can be installed directly from Visual studio package manager console.
I was trying to resolve a problem to update a cell by identifying its location based on the keyName. I found many solution on web to read and update any cell value by passing the exact cell reference.
But I just wanted to pass a keyName to identify the cell and update its corresponding value in sheet. I just wanted to pass Name of the test and then read or update the value.
One thing which we need to keep in mind is that when you are trying to read a particular value it has to be unique like my test names. If not then the sdk will pick up the first matched text.
![]() |
Example |
I created a simple console application to pass the required data to the following helper method
![]() |
Code |
using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(filename, true))
The parameter 'true' or 'false' decides if document is being opened for editing it.
If you just want to read values from document just pass it as 'false'.
var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == "Results");
The above line is just to find the sheet in the document. Now here is a common sense trick to read large document. If you want to read a large document with several worksheets in it then pass this as parameter to this method and iterate through it.
As the SDK also uses the .NET Framework Language-Integrated Query (LINQ) technology to provide strongly typed object access to the XML content inside the parts of Open XML documents, its very easy to access the inner elements and update them if you need to.
So next few lines are trying to get to the cell level.
var workSheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
var sharedStringPart = workbookPart.SharedStringTablePart;
var values = sharedStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
var cells = workSheetPart.Worksheet.Descendants<Cell>();
Now we need to loop through cells to find the value we are looking for.
Now cell can have text values, numbers or formula. So if cell contains a string input which is not formula then we are doing following task:
if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
{
var index = int.Parse(cell.CellValue.Text);
if (values[index].InnerText == keyName)
{
var nextCell = cell.NextSibling<Cell>();
keyValue = nextCell.InnerText;
return keyValue;
}
}
If you want to read numbers then
if (cell.CellValue != null && cell.CellValue.Text == keyName)
{
var nextCell = cell.NextSibling<Cell>();
keyValue = nextCell.InnerText;
return keyValue;
}
Now the next one which I have not highlighted in the above code( As I was just trying to read keyValue) is to get the formula applied on any cell.
if (cell.CellFormula != null)
{
Console.WriteLine(cell.CellFormula.Text);
}
Have a look at NextSibling method. It is used to traverse through columns if you have identified your row based on the keyName you passed.
var nextCell = cell.NextSibling<Cell>();
keyValue = nextCell.InnerText;
What if I want to access the actual value Cells (C2) ? Here it is, a basic LINQ concept:
var nextCell = cell.NextSibling().NextSibling<Cell>();
keyValue = nextCell.InnerText;
Now this is all about reading cell values. Lets see how to update cell value
Updating a cell Value
First of all the sheet need to be opened in editable mode as explained above.
Here I have tried updating the value of C2 cell to newValue. As this is numerical value so have used CellValues.Number.
if (cell.CellValue != null && cell.CellValue.Text == keyValue)
{
var nextCell = cell.NextSibling().NextSibling<Cell>();
nextCell.CellValue = new CellValue(newValue);
nextCell.DataType = new EnumValue<CellValues>(CellValues.Number);
workbookPart.Workbook.Save();
}
If you want to update text value then
nextCell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
And finally don't forget to Save the Workbook.
/// <summary>
/// Reads the excel.
/// </summary>
/// <param name="keyName">Name of the key.</param>
/// <returns>Key Value</returns>
public string ReadExcel(string keyName)
{
string filename = ConfigurationManager.AppSettings.Get("C:/Logfile.xlsx");
string keyValue = string.Empty;
using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(filename, false))
{
var workbookPart = spreadSheetDocument.WorkbookPart;
var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == "Results");
if (sheet == null)
{
throw new InvalidOperationException("Unable to find the Results sheet");
}
var workSheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);
var sharedStringPart = workbookPart.SharedStringTablePart;
var values = sharedStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
var cells = workSheetPart.Worksheet.Descendants<Cell>();
foreach (var cell in cells)
{
if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
{
var index = int.Parse(cell.CellValue.Text);
if (values[index].InnerText == keyName)
{
var nextCell = cell.NextSibling<Cell>();
keyValue = nextCell.InnerText;
return keyValue;
}
}
if (cell.CellValue != null && cell.CellValue.Text == keyName)
{
var nextCell = cell.NextSibling<Cell>();
keyValue = nextCell.InnerText;
return keyValue;
}
}
return keyValue;
}
}
If you want to read further about this please follow below links: