OpenXML - 将日期写入 Excel 电子表格会导致内容不可读
我使用以下代码将 DateTime
添加到电子表格中的列:
var dt = DateTime.Now;
r.AppendChild<Cell>(new Cell()
{
CellValue = new CellValue(dt.ToOADate().ToString()),
DataType = new EnumValue<CellValues>(CellValues.Date),
StyleIndex = 1,
CellReference = header[6] + index
});
当我尝试在 Excel 2010 中打开文件时,出现错误
Excel 在 file.xlsx 中发现不可读的内容
如果我注释掉该行,一切都很好。
我在 StackOverflow 上提到了类似问题 ,但他们的代码基本上和我一样。
I am using the following code to add a DateTime
to a column in my spreadsheet:
var dt = DateTime.Now;
r.AppendChild<Cell>(new Cell()
{
CellValue = new CellValue(dt.ToOADate().ToString()),
DataType = new EnumValue<CellValues>(CellValues.Date),
StyleIndex = 1,
CellReference = header[6] + index
});
When I try to open the file in Excel 2010, I get the error
Excel found unreadable content in file.xlsx
All is fine if I comment out the line.
I have referred to similar questions on StackOverflow, but they basically have the same code as I do.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
像往常一样迟到了,但我必须发布一个答案,因为之前的所有答案都是完全错误的,除了 Oleh 被否决的答案,遗憾的是它不完整。
由于问题与 Excel 相关,最简单的方法是使用所需的数据和样式创建一个 Excel 电子表格,然后将其作为部件打开并查看原始 XML。
将日期 01/01/2015 添加到单元格 A1 中会产生以下结果:
请注意,类型属性不存在。但是,有一个样式属性引用以下样式:
这是您必须添加的最基本样式。
因此,生成上述内容的代码:
NumberFormatId = 14
引用内置格式mm-dd-yy
,这里是 < href="https://stackoverflow.com/questions/4730152/what-indicates-an-office-open-xml-cell-contains-a-date-time-value#4730266">其他一些列表格式。不幸的是,似乎仅添加上述样式还不够,如果这样做实际上会导致 Excel 崩溃。请注意,
BorderId
、FillId
、FontId
需要与样式表中的一项相对应,这意味着您需要提供它们。完整代码清单中的GetStyleSheet()
方法提供了 Excel 正常工作所需的最小默认样式表。注意:Office 2010 和 2013 可以以不同的方式处理日期,但默认情况下似乎并非如此。
它们提供对 ISO 8601 格式日期的支持,即
yyyy-MM-ddTHH:mm:ss
恰好这也是可排序的标准格式(“s”),因此您可以执行以下操作:结果:
完成代码列表
下面是添加日期格式单元格所需的最少代码示例。
Late to the party as usual but I have to post an answer because ALL of the previous ones are completely wrong except for Oleh's down voted answer which was sadly incomplete.
As the question is related to Excel, the easiest thing to do is create an Excel spread sheet with the data and style you want, then open it as parts and look at the raw XML.
Adding the date 01/01/2015 into cell A1 results in the following:
Note that the type attribute is not there. However there is a style attribute referencing the following style:
That is the most basic style that you must add.
So code to generate the above:
The
NumberFormatId = 14
refers to the built-in formatmm-dd-yy
, here's a list of some other formats.Unfortunately it seems that adding just the above style is not quite enough and if you do it actually causes Excel to crash. Note that
BorderId
,FillId
,FontId
need to correspond to an item in the style sheet which means you need to provide them. TheGetStyleSheet()
method in the complete code listing provides the minimum default stylesheet required for Excel to work without errors.Note: Office 2010 and 2013 can handle dates differently but by default it seems they do not.
They provide support for dates in ISO 8601 format i.e.
yyyy-MM-ddTHH:mm:ss
just so happens that this is also standard format sortable ("s") so you can do:The result:
Complete Code Listing
Below is an example of the minimum code required to add a cell with date format.
尝试指示它是
CellValues.String
类型,而不是CellValues.Date
类型。使用
而不是
Now,将其添加为 date 是有意义的,无需
ToString()
转换,并使用CellValues.Date
DataType -- 但是 CellValue() 仅采用字符串 作为参数。[为什么,OpenXmlSDK,为什么???你是一个包装纸。把东西包裹得很好。让它们隐形,让我的生活更轻松。 :::sigh:::]
此外,如果目标单元格期望格式化日期,我们应该指示它是一个日期。
但我发现,虽然
CellValues.String
和CellValues.Date
都按预期格式化(相同),但只有CellValues.Date
抛出加载时“不可读的内容”。我对 dt.ToOADate().ToString(new CultureInfo("en-US")); 方法的任何变化都完全没有运气——我最终得到了一个五位数字在电子表格中显示为五位数字,而它应该是格式化日期。
添加字符串值但使用 CellValues.Number 数据类型时,我收到了相同的错误消息。
Try indicating it is a
CellValues.String
type, instead of aCellValues.Date
type.Use
instead of
Now, it would make sense to add it as date, without the
ToString()
conversion, and use theCellValues.Date
DataType -- but CellValue() only takes a string as a parameter.[Why, OpenXmlSDK, WHY??? You're a wrapper. Wrap things nicely. Make them invisible, and make my life easier. :::sigh:::]
Additionally, if the target cell expects to be formatting a date, we should be indicating it is a date.
But I've found that while
CellValues.String
andCellValues.Date
both get formatted as expected (identically), only theCellValues.Date
throws up the "unreadable content" on-load.I've had utterly no luck with any variation on
dt.ToOADate().ToString(new CultureInfo("en-US"));
method -- I end up with a five-digit number that gets displayed in the spreadsheet as five-digit number, when it should be a formatted date.I was receiving the same error message when adding a string value, but using the
CellValues.Number
DataType.尝试使用
dt.ToOADate().ToString().Replace (",", ".")
而不是dt.ToOADate().ToString()
对于某些工作代码示例请参见http://www.codeproject.com/KB/office/ExcelOpenXMLSDK.aspx
编辑:
请将您的代码更改为:
try
dt.ToOADate().ToString().Replace (",", ".")
instead ofdt.ToOADate().ToString()
For some working code samples see http://www.codeproject.com/KB/office/ExcelOpenXMLSDK.aspx
EDIT:
please change your code to this:
例如,您可以创建自己的带有日期列的 Excel 文件。然后,如果您使用 Open XML SDK 中的生产力工具打开它,您会发现没有为具有日期值的单元格指定
DataType
。这意味着您在创建日期单元格时应省略DataType
。在这种情况下,还需要将 dt.ToOADate().ToString() 作为单元格值传递。As an example you can create your own excel file with date column. Then if you open it with Productivity Tool from Open XML SDK you will find there is no
DataType
specified for the cell with date value. This means that you should omitDataType
when creating date cell. In this case it is also required to passdt.ToOADate().ToString()
as a cell value.以下代码可用于在电子表格中设置日期时间值:
The following code can be used to set a DateTime value in a spreadsheet:
以下内容对我们有用:
将
DataType
设置为CellValues.Number
,然后确保使用CellFormats
中的适当样式索引格式化单元格。在我们的例子中,我们在工作表中构建一个样式表,StyleDate
是样式表中CellFormats
的索引。The following worked for us:
Set the
DataType
toCellValues.Number
and then be sure to format the cell with the appropriate style index from theCellFormats
. In our case we build a stylesheet within the worksheet, andStyleDate
is an index into theCellFormats
in the stylesheet.