当 DataGrid table 导出到 MS Excel 时,数据显示为 System.Data.DataRowView
Datat is shown as System.Data.DataRowView when DataGrid table is exported to MS Excel
我有一个导出到 Microsoft Excel 按钮单击事件。我的代码采用 DataGrid
table 并将其导出到 MS Excel.
我遇到的问题是当 DataGrid
导出到 Microsoft Excel 时,列 headers 是正确的,但单元格中的数据显示为 System.Data.DataRowView
下面是我的按钮点击事件的代码:
private void butn_ExportResults_Click(object sender, RoutedEventArgs e)
{
if (dt_ReportList.Items.Count > 0)
{
try
{
Microsoft.Office.Interop.Excel.Application xcelApp = new Microsoft.Office.Interop.Excel.Application();
xcelApp.Application.Workbooks.Add(Type.Missing);
// Worksheet sheet1 = (Worksheet)workbook.Sheets[1];
for (int i = 1; i < dt_ReportList.Columns.Count + 1; i++)
{
xcelApp.Cells[1, i] = dt_ReportList.Columns[i - 1].Header;
}
for (int i = 0; i < dt_ReportList.Items.Count; i++)
{
for (int j = 0; j < dt_ReportList.Columns.Count; j++)
{
xcelApp.Cells[i + 2, j + 1] = dt_ReportList.Items[i].ToString();
}
}
xcelApp.Columns.AutoFit();
xcelApp.Visible = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
当你这样做时
dt_ReportList.Items[i].ToString();
您正在引用该行,整行。这是您的基本问题,也是您获得数据行视图的原因。
您需要该行中的列值。
我想你可以使用列索引来引用它。
因此尝试:
dt_ReportList.Items[i][j].ToString();
您正在使用 DataTable
,因此 DataGrid
中的行数据类型将为 DataRowView
。它包含当前行所有列的值。问题是您不访问这些值,而是在这一行中将 DataRowView
实例转换为 string
:
xcelApp.Cells[i + 2, j + 1] = dt_ReportList.Items[i].ToString();
它不会覆盖 ToString
,因此结果将只是它的类型名称。相反,您必须通过 Row
属性 中的索引访问相应的列,例如:
xcelApp[i + 2, j + 1] = dataRowView.Row[j];
DataRowView
仅在外循环中发生变化,因此我们通过模式匹配获取并转换到那里。 if
语句确保给定的项目是 DataRowView
,因为当 DataGrid
上启用 CanUserAddRows
时,最后一行可以是类型 NewItemPlaceholder
的空白行] 需要跳过。
for (int i = 0; i < dt_ReportList.Items.Count; i++)
{
if (!(dt_ReportList.Items[i] is DataRowView dataRowView))
continue;
for (int j = 0; j < dt_ReportList.Columns.Count; j++)
{
xcelApp[i + 2, j + 1] = dataRowView.Row[j];
}
}
我有一个导出到 Microsoft Excel 按钮单击事件。我的代码采用 DataGrid
table 并将其导出到 MS Excel.
我遇到的问题是当 DataGrid
导出到 Microsoft Excel 时,列 headers 是正确的,但单元格中的数据显示为 System.Data.DataRowView
下面是我的按钮点击事件的代码:
private void butn_ExportResults_Click(object sender, RoutedEventArgs e)
{
if (dt_ReportList.Items.Count > 0)
{
try
{
Microsoft.Office.Interop.Excel.Application xcelApp = new Microsoft.Office.Interop.Excel.Application();
xcelApp.Application.Workbooks.Add(Type.Missing);
// Worksheet sheet1 = (Worksheet)workbook.Sheets[1];
for (int i = 1; i < dt_ReportList.Columns.Count + 1; i++)
{
xcelApp.Cells[1, i] = dt_ReportList.Columns[i - 1].Header;
}
for (int i = 0; i < dt_ReportList.Items.Count; i++)
{
for (int j = 0; j < dt_ReportList.Columns.Count; j++)
{
xcelApp.Cells[i + 2, j + 1] = dt_ReportList.Items[i].ToString();
}
}
xcelApp.Columns.AutoFit();
xcelApp.Visible = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
当你这样做时
dt_ReportList.Items[i].ToString();
您正在引用该行,整行。这是您的基本问题,也是您获得数据行视图的原因。
您需要该行中的列值。
我想你可以使用列索引来引用它。
因此尝试:
dt_ReportList.Items[i][j].ToString();
您正在使用 DataTable
,因此 DataGrid
中的行数据类型将为 DataRowView
。它包含当前行所有列的值。问题是您不访问这些值,而是在这一行中将 DataRowView
实例转换为 string
:
xcelApp.Cells[i + 2, j + 1] = dt_ReportList.Items[i].ToString();
它不会覆盖 ToString
,因此结果将只是它的类型名称。相反,您必须通过 Row
属性 中的索引访问相应的列,例如:
xcelApp[i + 2, j + 1] = dataRowView.Row[j];
DataRowView
仅在外循环中发生变化,因此我们通过模式匹配获取并转换到那里。 if
语句确保给定的项目是 DataRowView
,因为当 DataGrid
上启用 CanUserAddRows
时,最后一行可以是类型 NewItemPlaceholder
的空白行] 需要跳过。
for (int i = 0; i < dt_ReportList.Items.Count; i++)
{
if (!(dt_ReportList.Items[i] is DataRowView dataRowView))
continue;
for (int j = 0; j < dt_ReportList.Columns.Count; j++)
{
xcelApp[i + 2, j + 1] = dataRowView.Row[j];
}
}