2016-10-18 3 views
1

Ich versuche derzeit, einige Daten aus meiner Datenbank in eine Excel-Datei zu exportieren. Bis auf eine Spalte ist alles in Ordnung.Von DataBase zu Excel: Datumsformat Problem

Ich habe zwei Datumsfelder in meiner Zieltabelle (Anfangs- und Enddatum), die ich in meinem Excel-Blatt anzeigen möchte. Die Sache ist, das Enddatum wird korrekt angezeigt (TT/MM/JJJJ), während mein Startdatum nicht (MM/TT/JJJJ) ist. Ihre Definition ist auf Datenbankebene absolut gleich.

Hier ist, wie ich meine Datatable baue:

public System.Data.DataTable ExportLastChangesToExcel() 
    { 


     List<HD_DISCOUNTS> listDiscount = (from d in dbHosp.HD_DISCOUNTS where d.TO_EXTRACT == "N" orderby d.EXTRACT_TEXT descending select d).ToList(); 


     System.Data.DataTable table = new System.Data.DataTable(); 
     table.Columns.Add("Condition Type", typeof(string)); 
     table.Columns.Add("Sales organisation", typeof(string)); 
     table.Columns.Add("Distribution Channel", typeof(string)); 
     table.Columns.Add("Customer", typeof(string)); 
     table.Columns.Add("Customer Name", typeof(string)); 
     table.Columns.Add("Material", typeof(string)); 
     table.Columns.Add("Material name", typeof(string)); 
     table.Columns.Add("Amount", typeof(string)); 
     table.Columns.Add("Unit", typeof(string)); 
     table.Columns.Add("C..", typeof(string)); 
     table.Columns.Add("Valid From", typeof(string)); 
     table.Columns.Add("Valid To", typeof(string)); 
     table.Columns.Add("Valid Action", typeof(string)); 

     var allCust = (from v in dbCust.CUSTOMER_MASTER where v.INCLUDE_INTO_HD == "Y" select v).ToList(); 

     foreach (HD_DISCOUNTS disc in listDiscount) 
     { 
      string compareId = disc.ID_HOSP.ToString(); 
      CUSTOMER_MASTER cust = (from h in allCust where h.SOLDTOPARTY.TrimStart('0') == compareId select h).FirstOrDefault(); 
      DIM_PRODUCT prod = (from p in db.DIM_PRODUCT where p.P_KEY_AZ == disc.ID_PRODUCT select p).FirstOrDefault(); 
      DIM_PRODUCT_SAP sap = (from s in db.DIM_PRODUCT_SAP where s.P_KEY_AZ == prod.P_KEY_AZ && s.P_TYPE_SAP == "Domestic" select s).FirstOrDefault(); 

      table.Rows.Add("ZD22", "BE10", "1", cust.SOLDTOPARTY, cust.SOLDTOPARTY_DESC, sap.P_KEY_SAP.ToString(), prod.P_DESC_AZ, disc.DISCOUNT.ToString(), "%", "A", disc.START_DATE.Value.ToString("dd/MM/yyyy"), disc.END_DATE.Value.ToString("dd/MM/yyyy"), disc.EXTRACT_TEXT); 

     } 


     return table; 

    } 

ich gedebuggt haben und das Startdatum sollte gut angezeigt werden. Hier ist der Code, den ich verwende, um meine Excel zu bauen:

protected void btnExport_Click(object sender, EventArgs e) 
    { 
     Microsoft.Office.Interop.Excel.Application excel; 
     Microsoft.Office.Interop.Excel.Workbook worKbooK; 
     Microsoft.Office.Interop.Excel.Worksheet worksheet; 
     Microsoft.Office.Interop.Excel.Range celLrangE; 

     try 
     { 
      excel = new Microsoft.Office.Interop.Excel.Application(); 
      excel.Visible = false; 
      excel.DisplayAlerts = false; 
      worKbooK = excel.Workbooks.Add(Type.Missing); 

      worksheet = (Microsoft.Office.Interop.Excel.Worksheet)worKbooK.ActiveSheet; 
      worksheet.Name = "Sheet1"; 

      System.Data.DataTable tab = ExportLastChangesToExcel(); 
      Range excelRange = worksheet.get_Range("K1"); 

      excelRange.NumberFormat = "dd/mm/yyyy;@"; 
      int rowcount = 2; 

      foreach (DataRow datarow in tab.Rows) 
      { 
       rowcount += 1; 
       for (int i = 1; i <= tab.Columns.Count; i++) 
       { 

        if (rowcount == 3) 
        { 
         worksheet.Cells[1, i] = tab.Columns[i - 1].ColumnName; 
         worksheet.Cells.Font.Color = System.Drawing.Color.Black; 

        } 

        worksheet.Cells[rowcount-1, i] = datarow[i - 1].ToString(); 
        //worksheet.Cells[i, 11].NumberFormat = "@"; 

        if (rowcount > 3) 
        { 
         if (i == tab.Columns.Count) 
         { 
          if (rowcount % 2 == 0) 
          { 
           celLrangE = worksheet.Range[worksheet.Cells[rowcount, 1], worksheet.Cells[rowcount, tab.Columns.Count]]; 


          } 

         } 
        } 

       } 

      } 
      celLrangE = worksheet.Range[worksheet.Cells[1, 1], worksheet.Cells[rowcount, tab.Columns.Count]]; 
      celLrangE.EntireColumn.AutoFit(); 

      celLrangE = worksheet.Range[worksheet.Cells[1, 1], worksheet.Cells[2, tab.Columns.Count]]; 

      worKbooK.SaveAs("C:\\Temp\\Hospital Discount\\Genpact\\GenpactExtract.xlsx"); 
      worKbooK.Close(); 
      excel.Quit(); 



     } 
     catch (Exception ex) 
     { 

     } 
     finally 
     { 
      worksheet = null; 
      celLrangE = null; 
      worKbooK = null; 

      lblResultMessage.Text = "Extract for Genpact has been successfully generated"; 
      lblResultMessage.Visible = true; 
     } 

Als Säule K ist derjenige, der die falschen Termine enthält, habe ich versucht, diese Spalte zu formatieren, um meine Daten gut formatieren, aber ohne Erfolg.

Irgendeine Idee, was möglicherweise schief geht?

+0

Anstelle von Interop eine Bibliothek wie EPPlus verwenden. Es ist so einfach wie das Aufrufen von 'sheet.LoadFromDataTable (someTable)' und es wird darauf geachtet, Daten korrekt zu kopieren. Datum und Uhrzeit sind * nicht * Zeichenfolgen. Sie können den tatsächlichen DateTime-Wert mit interop festlegen, oder Sie sollten den von "DateTime.TooDate" zurückgegebenen unformatierten Doppelwert speichern. –

+0

PS - die Datatable-Spalten sind falsch, sie sind Zeichenfolge anstelle von DateTime. Wenn Sie Daten aus der Datenbank als Zeichenfolgen laden, haben Sie bereits eine möglicherweise fehlerhafte Konvertierung. Es ist noch schlimmer, wenn Sie Daten in der Datenbank als Zeichenfolgen speichern. In jedem Fall müssen Sie die Zeichenfolgen explizit mit dem für das gespeicherte Textformat geeigneten CultureInfo zu einer DateTime analysieren. Keine gute Idee –

+0

@ PanagiotisKanavos danke für Ihren Kommentar. Ich habe die Änderung tatsächlich vorgenommen, weil ich das Problem sogar mit dem DateTime-Typ hatte. – Traffy

Antwort

0

Ich denke, das Problem ist, dass Sie Excel zu viel verlassen und explizit in wie Sie die Daten eingeben und rendern müssen.

Meine Empfehlung:

  1. die Daten aus der Datenbank als Datum lesen, keinen String
  2. es in Excel als Datum eingeben, wie Excel Sie Termine
  3. Format der Zelle die Art und Weise interpretiert sehen wollen es

Beispiel:

Excel.Range r = worksheet.Cells[rowcount - 1, i]; 

if (datarow[i - 1] is DateTime) 
{ 
    r.Value2 = ((DateTime)(datarow[i - 1])).ToOADate(); 
    r.NumberFormat = "dd/MM/yyyy"; 
} 
else 
{ 
    r.Value2 = datarow[i - 1] 
} 

Denken Sie daran, Sie können die Datentabelle alle zusammen überspringen und verwenden Sie einfach eine , um die Daten zu lesen und dann direkt in Excel zu legen.

Weiter, wenn Sie eine ODBC-Verbindung haben, können Sie Excel direkt von Oracle lesen und in eine Tabelle einfügen - es wird sogar die Daten richtig behandeln, wenn Sie es so machen. Das können Sie übrigens auch mit C# machen, mit ein paar Codezeilen, und Sie lassen Excel das Heavy Lifting durchführen.