2016-10-18 16 views
1

現在、データベースからExcelファイルに一部のデータをエクスポートしようとしています。 1つの列を除いてすべてがうまくいく。DataBaseからExcelへ:日付形式の問題

Excelシートに表示したいターゲットテーブル(開始日と終了日)に2つの日付フィールドがあります。つまり、開始日が(mm/dd/yyyy)ではない間に終了日が正しく表示されます(dd/mm/yyyy)。それらの定義は、データベースレベルでは全く同じです。ここで

は私が私のDataTableを構築しています方法は次のとおりです。

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; 

    } 

私はデバッグと開始した日付がうまく表示されなければなりません。ここで私は私のExcelを構築するために使用するコードです:

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; 
     } 

列Kとしては間違った日付を含むものである、私は私の日付がうまくフォーマットされ得るために、このコラムをフォーマットしようとしたが、成功しませんでした。

おそらく何が起こっているのかについてのアイデアはありますか?

+0

interopの代わりに、EPPlusのようなライブラリを使用します。これは 'sheet.LoadFromDataTable(someTable)'を呼び出すのと同じくらい簡単で、日付のコピーを正しく処理します。日付と時刻は文字列ではありません。実際のDateTime値をinteropで設定するか、 'DateTime.ToODate'から返された生のdoubleを格納する必要があります –

+0

PS - データテーブルの列が間違っています.DateTimeの代わりに文字列です。データベースから日付を文字列としてロードすると、すでにバグの可能性がある変換が行われています。データベースに日付を文字列として格納するとさらに悪化します。いずれの場合でも、格納されたテキスト形式に適したCultureInfoを使用して、文字列を 'DateTime'に明示的に解析する必要があります。良い考えではありません –

+0

@PanagiotisKanavosご意見ありがとうございます。私はDateTime型でも問題があったので、実際に変更を加えました。 – Traffy

答えて

0

私は、Excelにあまりにも多くを残しておき、データの入力とレンダリングの方法を明示する必要があると思います。

私の推薦:

  1. が日付としてデータベースからデータを読み込み、文字列ではありません
  2. Excelが日付を
  3. フォーマットセルの方法あなたの解釈として、日付としてExcelにそれを入力します。見たいと思って、それ

例:

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] 
} 

データテーブルをすべてスキップしてOracleDataReaderを使用してデータを読み取り、Excelに直接入力することができます。

さらに、ODBC接続を使用している場合、Excelで直接Oracleから読み取ってテーブルに入れることができます。このようにすれば、日付も正しく処理されます。ところで、コードの数行で、C#からこれを行うことができます。そして、あなたはExcelに重労働をさせることができます。