简而言之,它是 null,因为它应该用于数字和日期类型。
OpenXML 文档
对于数字和日期类型,DataType 属性的值为 null。
它包含字符串值 CellValues.SharedString,以及
CellValues.Boolean 用于布尔值。
有一种方法可以使用以下命令来区分日期和数字单元格格式数字格式ID on the 单元格式。诀窍是找到什么 id 映射到什么格式。您可以通过创建新的 Excel 文件并将单元格设置为相关格式(即日期)来找出要使用的格式:
然后使用 7zip 提取 excel 文件并查看 xl/styles.xml 文件:
在上图中,您可以看到 formatId 14 转换为短日期。有关格式的完整列表,请参阅Office Open XML 格式的 ECMA-376 文档 http://www.ecma-international.org/publications/standards/Ecma-376.htm(数字格式表应该埋在第4部分内部的某个地方。他们将其移至第18.8.30节中的第1部分)。
我为最常见的 formatId 创建了一个枚举:
private enum Formats
{
General = 0,
Number = 1,
Decimal = 2,
Currency = 164,
Accounting = 44,
DateShort = 14,
DateLong = 165,
Time = 166,
Percentage = 10,
Fraction = 12,
Scientific = 11,
Text = 49
}
然后,您可以创建一个辅助函数,它将按照您想要的方式获取格式化值:
private static string GetFormattedCellValue(WorkbookPart workbookPart, Cell cell)
{
if (cell == null)
{
return null;
}
string value = "";
if (cell.DataType == null) // number & dates
{
int styleIndex = (int)cell.StyleIndex.Value;
CellFormat cellFormat = (CellFormat)workbookPart.WorkbookStylesPart.Stylesheet.CellFormats.ElementAt(styleIndex);
uint formatId = cellFormat.NumberFormatId.Value;
if (formatId == (uint)Formats.DateShort || formatId == (uint)Formats.DateLong)
{
double oaDate;
if (double.TryParse(cell.InnerText, out oaDate))
{
value = DateTime.FromOADate(oaDate).ToShortDateString();
}
}
else
{
value = cell.InnerText;
}
}
else // Shared string or boolean
{
switch (cell.DataType.Value)
{
case CellValues.SharedString:
SharedStringItem ssi = workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(int.Parse(cell.CellValue.InnerText));
value = ssi.Text.Text;
break;
case CellValues.Boolean:
value = cell.CellValue.InnerText == "0" ? "false" : "true";
break;
default:
value = cell.CellValue.InnerText;
break;
}
}
return value;
}