我正在尝试将数据从WPF DataGrid导出到Excel文档中。当我运行此按钮时,它会导出屏幕上可见的所有内容,或者适合窗口中的内容。 DataGrid已足够填充,您必须向下滚动才能看到所有值,这些隐藏值不会导出到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 :(得分: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。
答案 1 :(得分:0)
之前我遇到了同样的问题,我发现你需要将自己的DataGrid添加到ScrollViewer中,让我们看一下以下示例 添加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>