在EPPlus导出中检测数据表日期字段并强制使用日期格式
本文关键字:日期 格式 字段 检测 数据表 EPPlus | 更新日期: 2023-09-27 18:25:56
我的页面上有一个按钮,单击该按钮可将数据从网格视图导出到excel。
protected void btExport_Click(object sender, EventArgs e)
{
Response.Clear();
Response.Charset = "";
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=Output.xlsx");
DataTable dt= gvOutput.DataSource as DataTable;
ExcelPackage pck = new ExcelPackage();
using(pck)
{
ExcelWorksheet wsDt = pck.Workbook.Worksheets.Add("Sheet1");
wsDt.Cells["A1"].LoadFromDataTable(dt, true, TableStyles.None);
wsDt.Cells[wsDt.Dimension.Address].AutoFitColumns();
Response.BinaryWrite(pck.GetAsByteArray());
}
Response.Flush();
Response.End();
}
使用上面的代码可以很好地工作,但是日期字段的格式是整数。我知道特定的单元格可以强制使用特定的格式,但我的问题是,随着网格视图的数据集是动态的,日期列会发生变化。
我需要一种方法来快速识别哪一列是日期,并强制该列的格式为日期-时间。
我想它会涉及这样一个IF语句,但我不知道该放什么或放在哪里!
if (dt.Columns[x].DataType == typeof(DateTime))
{
//do something
}
任何想法/帮助都将不胜感激。
循环遍历DataTable列,并确定哪些列是DateTime值。如果找到一个,请设置列的格式,如下所示。我还没有测试代码,但它应该是要遵循的一般逻辑。
...
wsDt.Cells["A1"].LoadFromDataTable(dt, true, TableStyles.None);
int colNumber = 1;
foreach (DataColumn col in dt.Columns)
{
if (col.DataType == typeof(DateTime))
{
wsDt.Column(colNumber).Style.Numberformat.Format = "MM/dd/yyyy hh:mm:ss AM/PM";
}
colNumber++;
}
wsDt.Cells[wsDt.Dimension.Address].AutoFitColumns();
Response.BinaryWrite(pck.GetAsByteArray());
如果我错了,请纠正我,但我相信@desigoy和@Rick s的答案并不完全正确。
@desiguy的答案中,语句colNumber++
在数据表列的foreach
循环之外。
因此,因为索引增量是在循环之外完成的,所以循环将始终在colNumber=1
上工作。
关于@Rick S的解决方案;如果我没有错的话,在EPPlus中,列索引以1开头,而不是0,因此,语句:
wsDt.Column(colNumber++).Style.Numberformat.Format = "mm/dd/yyyy hh:mm:ss AM/PM"
应如下所示:
wsDt.Column(++colNumber).Style.Numberformat.Format = "MM/dd/yyyy hh:mm:ss AM/PM"
而存在两个差异:
将
colNumber++
更改为++colNumber
。在这种情况下,列将以1开头,而不是以0开头,因此您不会得到错误mm/dd/yyyy
改为MM/dd/yyyy
,因为小写mm
表示分钟而不是月份,因此MM
是月份表示的正确语法
另一个更简单的解决方案是只将int colNumber = 0;
设置为int colNumber = 1;
,就会得到相同的结果。
对上述答案进行了轻微修改。几乎正确。我用下面的代码修复了它。
wsDt.Cells["A1"].LoadFromDataTable(dt, true, TableStyles.None);
int colNumber = 0;
foreach (DataColumn col in dt.Columns)
{
colNumber++;
if (col.DataType == typeof(DateTime))
{
wsDt.Column(colNumber).Style.Numberformat.Format = "mm/dd/yyyy hh:mm:ss AM/PM"
}
}
wsDt.Cells[wsDt.Dimension.Address].AutoFitColumns();
Response.BinaryWrite(pck.GetAsByteArray());
完全校正(和测试)的代码:
int colNumber = 0;
foreach (DataColumn col in DataToExport.Columns)
{
colNumber++;
if (col.DataType == typeof(DateTime))
{
wsDt.Column(colNumber).Style.Numberformat.Format = "MM/dd/yyyy hh:mm:ss AM/PM";
}
}