2017-07-03 83 views
0

我正在嘗試將數據從WPF DataGrid導出到Excel文檔中。當我運行這個按鈕時,它會輸出在屏幕上可見的或者適合窗口的所有內容。 DataGrid已經足夠了,你必須向下滾動才能看到所有的值,這些隱藏的值不會導出到excel文檔中,並且錯誤「對象引用未設置爲對象的實例」。發生。如果所有的值都適合在屏幕上,那就沒有問題了。將所有DataGrid行(包括不可見)WPF導出到Excel

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
    Excel.Application excel = new Excel.Application(); 
    excel.Visible = true; 
    Workbook workbook = excel.Workbooks.Add(System.Reflection.Missing.Value); 
    Worksheet sheet1 = (Worksheet)workbook.Sheets[1]; 

    for (int ExcelRow = 1, GridRow = 0; ExcelRow <= dgrid.Items.Count - 1; 
     ExcelRow++, GridRow++) 

     { 
     Range myRange = (Range)sheet1.Cells[ExcelRow, 1]; 
     myRange.Value2 = dgrid.Columns[0].Header; 

     TextBlock b = dgrid.Columns[0].GetCellContent(dgrid.Items[GridRow]) 
         as TextBlock; 

     Microsoft.Office.Interop.Excel.Range myRange2 = 
        (Microsoft.Office.Interop.Excel.Range)sheet1.Cells[2, 1]; 

     myRange.Value2 = b.Text; 
     /////////////////////// 

     myRange = (Range)sheet1.Cells[ExcelRow, 2]; 
     myRange.Value2 = dgrid.Columns[1].Header; 

     b = dgrid.Columns[1].GetCellContent(dgrid.Items[GridRow]) as 
      TextBlock; 

     myRange2 = (Microsoft.Office.Interop.Excel.Range)sheet1.Cells[3, 2]; 
     myRange.Value2 = b.Text; 
     ///////////////////////// 

     myRange = (Range)sheet1.Cells[ExcelRow, 3]; 
     myRange.Value2 = dgrid.Columns[2].Header; 

     b = dgrid.Columns[2].GetCellContent(dgrid.Items[GridRow]) as 
      TextBlock; 

     myRange2 = (Microsoft.Office.Interop.Excel.Range)sheet1.Cells[4, 3]; 
     myRange.Value2 = b.Text; 
     } 

    } 
+0

爲什麼不從DataGrid的DataContext/ItemsSource中抽取數據,因爲它包含了所有內容?直接從UI控件而不是從視圖模型拉動它很奇怪。 – hoodaticus

回答

0

如果你不需要任何需要從DataGrid(如自定義列排序或其他),你應該直接從數據源本身導出數據。

有了這個,有很多選項可用。就我個人而言,我喜歡這裏的方法,其中擴展方法處理所有事情。

https://stackoverflow.com/a/13973274/1415307

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Excel = Microsoft.Office.Interop.Excel; 
using System.Data; 
using System.Data.OleDb; 

DataTable dt; 
// fill table data in dt here 
... 

// export DataTable to excel 
// save excel file without ever making it visible if filepath is given 
// don't save excel file, just make it visible if no filepath is given 
dt.ExportToExcel(ExcelFilePath); 

的DataTable類的擴展方法:

public static class My_DataTable_Extensions 
{ 

    // Export DataTable into an excel file with field names in the header line 
    // - Save excel file without ever making it visible if filepath is given 
    // - Don't save excel file, just make it visible if no filepath is given 
    public static void ExportToExcel(this DataTable tbl, string excelFilePath = null) { 
     try { 
      if (tbl == null || tbl.Columns.Count == 0) 
       throw new Exception("ExportToExcel: Null or empty input table!\n"); 

      // load excel, and create a new workbook 
      var excelApp = new Excel.Application(); 
      excelApp.Workbooks.Add(); 

      // single worksheet 
      Excel._Worksheet workSheet = excelApp.ActiveSheet; 

      // column headings 
      for (var i = 0; i < tbl.Columns.Count; i++) { 
       workSheet.Cells[1, i + 1] = tbl.Columns[i].ColumnName; 
      } 

      // rows 
      for (var i = 0; i < tbl.Rows.Count; i++) { 
       // to do: format datetime values before printing 
       for (var j = 0; j < tbl.Columns.Count; j++) { 
        workSheet.Cells[i + 2, j + 1] = tbl.Rows[i][j]; 
       } 
      } 

      // check file path 
      if (!string.IsNullOrEmpty(excelFilePath)) { 
       try { 
        workSheet.SaveAs(excelFilePath); 
        excelApp.Quit(); 
        MessageBox.Show("Excel file saved!"); 
       } 
       catch (Exception ex) { 
        throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n" 
             + ex.Message); 
       } 
      } else { // no file path is given 
       excelApp.Visible = true; 
      } 
     } 
     catch (Exception ex) { 
      throw new Exception("ExportToExcel: \n" + ex.Message); 
     } 
    } 
} 

而且,這種拼勁,他們已經安裝Excel對消費者的要求。這可能會導致一些併發症。如果你不需要Excel中的任何東西,只需要Excel可以讀取的輸出,我建議只創建一個CSV。

0

我以前遇到同樣的問題,我發現你需要在ScrollViewer中添加你自己的DataGrid,讓我們來看看下面這個例子 添加了scrollViewer後,我確定你的代碼會運行完美Excel活躍。

<ScrollViewer Grid.Row="0" 
        Margin="5 5 5 5"> 
     <Grid Grid.Row="0"> 
      <DataGrid 
       Name="DataGridName" 
       HorizontalAlignment="Stretch" 
       Margin="10,10,10,10" 
       VerticalAlignment="Top" 
       Height="Auto" Width="Auto" 
       IsReadOnly="True" 
       CanUserSortColumns="False" 
       FontSize="13" 
       ItemsSource="{Binding Path=ListCustomer}"/> 
     </Grid> 
    </ScrollViewer>