没有任何代码,很难猜出如何数据从 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 表示生成了一个header。
有等效的方法可以从其他来源加载数据: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 文件中。