C# 在EPPlus导出中检测数据表日期字段和强制日期格式

C# 在EPPlus导出中检测数据表日期字段和强制日期格式,c#,asp.net,epplus,C#,Asp.net,Epplus,我的页面上有一个按钮,单击该按钮可将数据从gridview导出到excel protected void btExport_Click(object sender, EventArgs e) { Response.Clear(); Response.Charset = ""; Response.ContentEncoding = System.Text.Encoding.UTF8; Response.Cache.SetCacheability(HttpCachea

我的页面上有一个按钮,单击该按钮可将数据从gridview导出到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();
}
使用上述代码可以很好地工作,但是日期字段的格式是整数。我知道可以强制特定单元格具有特定格式,但我的问题是,随着gridview的数据集是动态的,日期列将发生变化

我需要一种方法来动态识别哪个列是日期,并强制该列的格式为日期时间

我想它会涉及像这样的IF语句,但我不知道该放什么或放在哪里

if (dt.Columns[x].DataType == typeof(DateTime))
{ 
    //do something
}

非常感谢您的任何想法/帮助。

循环浏览数据表列,并确定哪些列是日期时间值。如果找到一个,则设置列的格式,如下所示。我还没有测试代码,但它应该是遵循的一般逻辑

...
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());

对上述答案稍作修改。几乎正确。我用下面的代码修复了它

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());

如果我错了,请纠正我,但我相信@desiguy和@Rick的答案并不完全正确

在@desigue的答案中,
colNumber++
语句在datatable列上的
foreach
循环之外

因此,由于索引增量是在循环外部完成的,因此循环将始终在
colNumber=1
上工作

关于@Rick的解决方案;如果我没有弄错的话,在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/yyyyy
    已更改为
    mm/dd/yyyy
    ,因为小写的
    mm
    表示分钟,而不是月份,因此,
    mm
    是表示月份的正确语法

  • 另一个更简单的解决方案是只设置
    int colNumber=0
    int colNumber=1和您得到的结果相同。

    完全更正(和测试)代码:


    此代码将遍历DataTable的列,对于DateTime的每个数据类型,它将在生成的电子表格中格式化列,以便日期以所选格式显示(例如“01/05/2005 12:00:00 AM”),而不是以数字形式显示。完美。但是“colNumber++”应该在if语句之外:
    if(col.DataType==typeof(DateTime)){wsDt.Column(colNumber.Style.Numberformat.Format=“MM/dd/yyyy hh:MM:ss AM/PM”;}colNumber++@FlorianD.You是正确的。我已经编辑了我的答案,谢谢。我建议你下次请求编辑原始答案。
    
            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";
                }
            }