2013-03-24 159 views
4

我的程序在Excel中创建输出。Excel Interop单元格日期格式

一些日期似乎越来越误解: enter image description here

在打开该文件的日期,如屏幕截图的混合物。
如果我实际上将光标放在Excel的计算框中(在screenprint中)并按回车,单元格的格式将恢复为正确的格式。

我正在使用Microsoft.Office.Interop.Excel将数据从Datatable移至保存在我的解决方案中的Excel模板。

之前将数据放入细胞我改变各列的NumberFormat相应使用switch

for(int i = 1; i < NumColumns + 1; i++) { 
    switch(dt.Columns[i-1].DataType.ToString()) { 
     case "System.Int32": 
      xlWorkSheet.Columns[i].NumberFormat = "#,##0_ ;[Red]-#,##0 "; 
      break; 
     case "System.String": 
      xlWorkSheet.Columns[i].NumberFormat = "@"; 
      break; 
     case "System.DateTime": 
      xlWorkSheet.Columns[i].NumberFormat = "[$-809]dd mmmm yyyy;@"; //"dd-mmm-yy"; 
      break; 
     case "System.Date": 
      xlWorkSheet.Columns[i].NumberFormat = "[$-809]dd mmmm yyyy;@"; //"dd-mmm-yy"; 
      break; 
     default: 
      xlWorkSheet.Columns[i].NumberFormat = "@"; 
      break; 
    } 
} 

要移动从数据表中的值我使用嵌套循环:

//move header totals into the spreadsheet 
for(int i = 1; i < NumColumns + 1; i++) { 
    xlWorkSheet.Cells[1, i].value = dt.Columns[i - 1].ColumnName; 
} 

//move in the data 
DataView dv = new DataView(dt); 
dv.Sort = "Date ASC"; 

int rowCount = 2; 
string theValue; 
try { 
    foreach(DataRowView dr in dv) {//(DataRow dr indt.Rows) 
     for(int i = 1; i < NumColumns + 1; i++) { 
      theValue = dr[i - 1].ToString(); 
      xlWorkSheet.Cells[rowCount, i].value = theValue; 
     } 
     rowCount += 1; 
    } 
} catch(Exception) { 
    throw; 
} 

在存储当我填充数据表我试着用DATETIME和以下内容明确地说明了类型:

SELECT 
"Date" = CONVERT(DATE,b.[Date]) 
    ... 

如何使我的日期数据如此明确以至Excel无法曲解并且应用所有所需的格式?


编辑

下一页(未经测试)在嵌套循环尝试如下:

int rowCount = 2; 
string theValue; 
DateTime dtm; 
DateTime d; 
try { 
    foreach(DataRowView dr in dv) {//(DataRow dr indt.Rows) 
     for(int i = 1; i < NumColumns + 1; i++) { 
      //theValue = dr[i - 1].ToString(); 
      //xlWorkSheet.Cells[rowCount, i].value = theValue; 
      switch(dr[i - 1].GetType().ToString()) { 
       case "System.DateTime": 
        dtm = Convert.ToDateTime(dr[i - 1]); 
        xlWorkSheet.Cells[rowCount, i].value = dtm.ToOADate(); 
        break; 
       case "System.Date": 
        d = Convert.ToDateTime(dr[i - 1]); 
        xlWorkSheet.Cells[rowCount, i].value = d.ToOADate(); 
        break; 
       default: 
        theValue = dr[i - 1].ToString(); 
        xlWorkSheet.Cells[rowCount, i].value = theValue; 
        break; 
      } 

     } 
     rowCount += 1; 
    } 
} catch(Exception) { 
    throw; 
} 

回答

5

这里的问题是,你作为一个字符串写入一切Excel和Excel将以这种方式存储它。在编辑并按Enter键后,Excel将重新解释单元格内容,然后可能以不同的方式存储它。

当您在DateTime上调用ToString()时,默认格式的格式为DD/MM/YY HH:mm:ss,这正是您在结果文件中看到的内容。

Excel中的日期存储为表示自1900年以来经过的天数的数字。要获取此数字,您可以调用ToOADate()方法。

http://msdn.microsoft.com/en-gb/library/system.datetime.tooadate.aspx

随着数据设置为double和适当的格式字符串,你应该得到你希望的结果!我应该执行嵌套循环内`之开关,对于`datatype`测试;:

+0

... + 1个感谢如果它的日期时间使用'ToOADate()';如果它的字符串,然后使用'ToString()'等? – whytheq 2013-03-25 09:19:11

+0

是的,这将工作。另外,我认为'DataRow'索引器(例如'dr [i-1]')将根据列类型为您打字。所以你应该能够测试返回对象(例如'if(value is DateTime)'并且调用'ToOADate()'。 – 2013-03-25 13:06:21

+0

...好的 - 我将用新的嵌套循环编辑我的OP - 我还没有测试过,我在黑暗中感觉有点;所以不要笑! – whytheq 2013-03-25 13:38:10

-3

只是(格式化值),这个替换(串)

+0

这不起作用,因为Excel将使用不同的区域设置重新解释字符串作为日期(因此设置01/09/2017的日期可以通过Excel认为它是09/01/2017) – 2017-12-14 09:48:40