我在Excel 2013中使用SQL Server DATETIME
对象时遇到了一个恼人的问题。问题已在SO中多次说明,我知道解决方法是重新格式化DATETIME
Excel中的对象:
yyyy-mm-dd hh:mm:ss.000
这很好但是我不愿意每次都这样做。除了创建宏之外,还有一个永久性的工作吗?我需要保持DATETIME
对象的粒度,以便我不能使用SMALLDATETIME
。我目前在win7机器上使用Microsoft SQL Server Management Studio 2008 r2。
提前致谢。
-Stelio K。
答案 0 :(得分:0)
没有任何代码,很难猜测数据如何从SQL Server到Excel。我假设它不是通过数据连接,因为Excel不会有任何问题直接将数据显示为日期。
数据连接怎么样?
在使用仅的数据连接时,Excel不支持任何类型的格式设置或任何有用的设计器。该功能由Power Query或数据透视表设计器提供。 Power Query集成在Excel 2016中,可以下载Excel 2010 +。
为什么需要格式化日期
Excel不保留类型信息。一切都是字符串或数字,其显示由单元格格式决定。
日期使用OLE自动化格式存储为小数 - 整数部分是自1900-01-01以来的日期数,小数部分是时间。这就是System.DateTime
具有FromOADate
和ToOADate
函数的原因。
要创建包含日期的Excel工作表,您应该在生成单元格的同时设置单元格格式。
如何格式化单元格
如果您使用Open XML SDK或像EPPlus这样的库,那么这样做是相对的。以下示例从客户列表中创建Excel工作表:
static void Main(string[] args)
{
var customers = new[]
{
new Customer("A",DateTime.Now),
new Customer("B",DateTime.Today.AddDays(-1))
};
File.Delete("customers.xlsx");
var newFile = new FileInfo(@"customers.xlsx");
using (ExcelPackage pck = new ExcelPackage(newFile))
{
var ws = pck.Workbook.Worksheets.Add("Content");
// This format string *is* affected by the user locale!
// and so is "mm-dd-yy"!
ws.Column(2).Style.Numberformat.Format = "m/d/yy h:mm";
//That's all it needs to load the data
ws.Cells.LoadFromCollection(customers,true);
pck.Save();
}
}
代码使用LoadFromCollection方法直接加载客户列表,而不处理单元格。 true
表示生成标头。
从其他源加载数据有相同的方法:LoadFromDatatable,LoadFromDataReader,CSV数据的LoadFromText,甚至是锯齿状对象数组的LoadFromArrays。
奇怪的是指定m/d/yy h:mm
或mm-dd-yy
格式使用用户的区域设置进行格式化,不美国格式!这是因为这些格式内置于Excel中,并被视为依赖于语言环境的格式。在日期格式列表中,它们显示为星号,表示它们受用户区域设置的影响。
这种奇怪的原因是,当Excel在10年前转移到基于XML的XLSX格式时,由于向后兼容的原因,它保留了旧XLS格式的怪癖。
当EPPlus保存xlsx
文件时,它会检测到它们并存储对内置格式ID的引用(分别为22和14),而不是存储整个格式字符串。
查找格式ID
标准格式ID列表显示在Open XML标准的NumberingFormat element documentation page中。 Excel最初定义了ID 0(常规)到49。
EPPlus不允许直接设置ID。它检查格式字符串并仅映射格式0-49,如ExcelNumberFormat的GetBfromBuildIdFromFormat方法所示。为了获得ID 22,我们需要将Format属性设置为"m/d/yy h:mm"
另一个技巧是检查现有工作表的样式表。 xlsx
是一个压缩的XML文件包,可以使用任何解压缩实用程序打开。样式存储在xl\styles.xml
文件中。