我使用以下代码将日期时间添加到电子表格中的列:
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
});
Run Code Online (Sandbox Code Playgroud)
当我尝试在Excel 2010中打开该文件时,我收到错误
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
});
Run Code Online (Sandbox Code Playgroud)
如果我注释掉这一行,一切都很好.
我在StackOverFlow上提到了simiiar问题,但它们基本上和我一样有相同的代码
Dav*_*ams 24
像往常一样迟到了派对,但我必须发布一个答案,因为以前的所有人都是完全错误的,除了Oleh的失败投票答案,这很遗憾.
由于问题与Excel有关,最简单的方法是创建一个包含所需数据和样式的Excel电子表格,然后将其作为部分打开并查看原始XML.
将日期01/01/2015添加到单元格A1中会产生以下结果:
<row r="1">
<c r="A1" s="0">
<v>42005</v>
</c>
</row>
Run Code Online (Sandbox Code Playgroud)
请注意,type属性不存在.然而,有是一个样式属性引用以下样式:
<xf numFmtId="14" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1" />
Run Code Online (Sandbox Code Playgroud)
这是您必须添加的最基本的样式.
所以生成上面的代码:
var CellFormats = new CellFormats();
CellFormats.Append(new CellFormat()
{
BorderId = 0,
FillId = 0,
FontId = 0,
NumberFormatId = 14,
FormatId = 0,
ApplyNumberFormat = true
});
CellFormats.Count = (uint)CellFormats.ChildElements.Count;
var StyleSheet = new Stylesheet();
StyleSheet.Append(CellFormats);
Run Code Online (Sandbox Code Playgroud)
该NumberFormatId = 14指内置格式mm-dd-yy,这里的一些其它的格式列表.
不幸的是,似乎将只是上面的样式是不是很够,如果你这样做实际上导致Excel崩溃.需要注意的是BorderId,FillId,FontId需要对应的样式表,这意味着你需要为他们提供的项目.GetStyleSheet()完整代码清单中的方法提供了Excel无错误工作所需的最小默认样式表.
SheetData.AppendChild(new Row(
new Cell()
{
// CellValue is set to OADate because that's what Excel expects.
CellValue = new CellValue(date.ToOADate().ToString(CultureInfo.InvariantCulture)),
// Style index set to style (0 based).
StyleIndex = 0
}));
Run Code Online (Sandbox Code Playgroud)
注意:Office 2010和2013 可以以不同方式处理日期,但默认情况下似乎不会.
它们为ISO 8601格式的日期提供支持,即yyyy-MM-ddTHH:mm:ss恰好这也是标准格式可排序("s"),因此您可以:
SheetData.AppendChild(new Row(
new Cell()
{
CellValue = new CellValue(date.ToString("s")),
// This time we do add the DataType attribute but ONLY for Office 2010+.
DataType = CellValues.Date
StyleIndex = 1
}));
Run Code Online (Sandbox Code Playgroud)
结果:
<row>
<c s="0" t="d">
<v>2015-08-05T11:13:57</v>
</c>
</row>
Run Code Online (Sandbox Code Playgroud)
下面是添加具有日期格式的单元格所需的最小代码示例.
private static void TestExcel()
{
using (var Spreadsheet = SpreadsheetDocument.Create("C:\\Example.xlsx", SpreadsheetDocumentType.Workbook))
{
// Create workbook.
var WorkbookPart = Spreadsheet.AddWorkbookPart();
var Workbook = WorkbookPart.Workbook = new Workbook();
// Add Stylesheet.
var WorkbookStylesPart = WorkbookPart.AddNewPart<WorkbookStylesPart>();
WorkbookStylesPart.Stylesheet = GetStylesheet();
WorkbookStylesPart.Stylesheet.Save();
// Create worksheet.
var WorksheetPart = Spreadsheet.WorkbookPart.AddNewPart<WorksheetPart>();
var Worksheet = WorksheetPart.Worksheet = new Worksheet();
// Add data to worksheet.
var SheetData = Worksheet.AppendChild(new SheetData());
SheetData.AppendChild(new Row(
new Cell() { CellValue = new CellValue(DateTime.Today.ToOADate().ToString(CultureInfo.InvariantCulture)), StyleIndex = 1 },
// Only works for Office 2010+.
new Cell() { CellValue = new CellValue(DateTime.Today.ToString("s")), DataType = CellValues.Date, StyleIndex = 1 }));
// Link worksheet to workbook.
var Sheets = Workbook.AppendChild(new Sheets());
Sheets.AppendChild(new Sheet()
{
Id = WorkbookPart.GetIdOfPart(WorksheetPart),
SheetId = (uint)(Sheets.Count() + 1),
Name = "Example"
});
Workbook.Save();
}
}
private static Stylesheet GetStylesheet()
{
var StyleSheet = new Stylesheet();
// Create "fonts" node.
var Fonts = new Fonts();
Fonts.Append(new Font()
{
FontName = new FontName() { Val = "Calibri" },
FontSize = new FontSize() { Val = 11 },
FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 },
});
Fonts.Count = (uint)Fonts.ChildElements.Count;
// Create "fills" node.
var Fills = new Fills();
Fills.Append(new Fill()
{
PatternFill = new PatternFill() { PatternType = PatternValues.None }
});
Fills.Append(new Fill()
{
PatternFill = new PatternFill() { PatternType = PatternValues.Gray125 }
});
Fills.Count = (uint)Fills.ChildElements.Count;
// Create "borders" node.
var Borders = new Borders();
Borders.Append(new Border()
{
LeftBorder = new LeftBorder(),
RightBorder = new RightBorder(),
TopBorder = new TopBorder(),
BottomBorder = new BottomBorder(),
DiagonalBorder = new DiagonalBorder()
});
Borders.Count = (uint)Borders.ChildElements.Count;
// Create "cellStyleXfs" node.
var CellStyleFormats = new CellStyleFormats();
CellStyleFormats.Append(new CellFormat()
{
NumberFormatId = 0,
FontId = 0,
FillId = 0,
BorderId = 0
});
CellStyleFormats.Count = (uint)CellStyleFormats.ChildElements.Count;
// Create "cellXfs" node.
var CellFormats = new CellFormats();
// A default style that works for everything but DateTime
CellFormats.Append(new CellFormat()
{
BorderId = 0,
FillId = 0,
FontId = 0,
NumberFormatId = 0,
FormatId = 0,
ApplyNumberFormat = true
});
// A style that works for DateTime (just the date)
CellFormats.Append(new CellFormat()
{
BorderId = 0,
FillId = 0,
FontId = 0,
NumberFormatId = 14, // or 22 to include the time
FormatId = 0,
ApplyNumberFormat = true
});
CellFormats.Count = (uint)CellFormats.ChildElements.Count;
// Create "cellStyles" node.
var CellStyles = new CellStyles();
CellStyles.Append(new CellStyle()
{
Name = "Normal",
FormatId = 0,
BuiltinId = 0
});
CellStyles.Count = (uint)CellStyles.ChildElements.Count;
// Append all nodes in order.
StyleSheet.Append(Fonts);
StyleSheet.Append(Fills);
StyleSheet.Append(Borders);
StyleSheet.Append(CellStyleFormats);
StyleSheet.Append(CellFormats);
StyleSheet.Append(CellStyles);
return StyleSheet;
}
Run Code Online (Sandbox Code Playgroud)
尝试指示它是一种CellValues.String类型,而不是CellValues.Date类型.
使用
ToString()
代替
CellValues.Date
现在,在没有ToString()转换的情况下将其添加为日期是有意义的,并使用CellValues.StringDataType - 但CellValue()仅将字符串作为参数.[为什么,OpenXmlSDK,为什么 ??? 你是一个包装者.很好地包装好东西.让它们隐形,让我的生活更轻松.:::叹:::]
此外,如果目标单元格希望格式化日期,我们应该指出它是一个日期.
但我发现,虽然CellValues.Date并CellValues.Date都得到预期(相同的)格式,只有CellValues.Date抛出抛出了载了"无法读取内容".
我对dt.ToOADate().ToString(new CultureInfo("en-US"));方法的任何变化完全没有运气- 我最终得到一个五位数的数字,它在电子表格中显示为五位数字,当它应该是格式化的日期时.
我在添加字符串值时收到了相同的错误消息,但使用的是CellValues.NumberDataType.
尝试dt.ToOADate().ToString().Replace (",", ".")而不是dt.ToOADate().ToString()
有关一些工作代码示例,请参阅http://www.codeproject.com/KB/office/ExcelOpenXMLSDK.aspx
编辑:
请将您的代码更改为:
dt.ToOADate().ToString(new CultureInfo("en-US"));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17159 次 |
| 最近记录: |