Reputation: 31
Im developing a reusable code to read the excel cell value. My code as follows:
private string ReadCellValue(WorksheetPart worksheetPart, string cellAddress)
{
string value = null;
Cell theCell = worksheetPart.Worksheet.Descendants<Cell>().
Where(c => c.CellReference == cellAddress).FirstOrDefault();
// If the cell does not exist, return an empty string.
if (theCell != null)
{
value = theCell.InnerText;
if (theCell.DataType != null)
{
switch (theCell.DataType.Value)
{
case CellValues.SharedString:
var stringTable =
worksheetPart.GetPartsOfType<SharedStringTablePart>()
.FirstOrDefault();
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;
}
Im calling this method from following code block:
public string IsPackingListValid()
{
// Open the spreadsheet document for read-only access.
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false))
{
// Retrieve a reference to the workbook part.
WorkbookPart wbPart = document.WorkbookPart;
// Find the sheet with the supplied name, and then use that
// Sheet object to retrieve a reference to the first worksheet.
Sheet theSheet = wbPart.Workbook.Descendants<Sheet>().
Where(s => s.Name == sheetName).FirstOrDefault();
// Throw an exception if there is no sheet.
if (theSheet == null)
{
throw new ArgumentException("Could not find work sheet: " + sheetName);
}
// Retrieve a reference to the worksheet part.
WorksheetPart worksheetPart = (WorksheetPart)(wbPart.GetPartById(theSheet.Id));
return ReadCellValue(WorksheetPart worksheetPart, "B2")
}
}
The method does not return the actual value for some cells. For some cells it returns the value and for some cells it returns the inner text. I debuged and checked
var stringTable = worksheetPart.GetPartsOfType<SharedStringTablePart>()
.FirstOrDefault();
the above code returns null.
I cant find why it s working for some cells and not working for some. Any helps to resolve this.
Upvotes: 2
Views: 4486
Reputation: 973
Also an extra check on SharedString datatype is needed (http://msdn.microsoft.com/en-us/library/office/ff921204(v=office.14).aspx for more info):
private static string ReadCellValue(WorksheetPart worksheetPart, string cellAddress, List<SharedStringItem> sharedStrings)
{
try
{
string value = null;
var cell = worksheetPart.Worksheet.Descendants<Cell>().Where(c => c.CellReference == cellAddress).FirstOrDefault();
value = cell.InnerText;
if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
{
int sharedStringIndex;
if (int.TryParse(cell.InnerText, out sharedStringIndex) && sharedStrings.Count > sharedStringIndex && sharedStrings[sharedStringIndex].Text != null)
{
value = sharedStrings[sharedStringIndex].Text.Text;
}
}
return value;
}
catch (Exception ex) { throw ex; }
}
Upvotes: 0
Reputation: 392
From my understanding (at least, it's true for a document I've checked it on), SharedStringTablePart is a descendant of WorkbookPart rather than WorksheetPart. So what you can do to fix your code is to get a list of shared strings from wbPart in IsPackingListValid() method:
List<SharedStringItem> sharedStrings = wbPart.SharedStringTablePart.SharedStringTable.ChildElements.OfType<SharedStringItem>().ToList();
And then pass it into ReadCellValue method as an additional argument:
return ReadCellValue(worksheetPart, "B2", sharedStrings);
After it, you can get actual value of your Shared string inside of your switch in ReadCellValue() method:
value = cell.InnerText;
int sharedStringIndex;
if (int.TryParse(cell.InnerText, out sharedStringIndex) && sharedStrings.Count > sharedStringIndex
&& sharedStrings[sharedStringIndex].Text != null)
{
value = sharedStrings[sharedStringIndex].Text.Text;
}
Upvotes: 6