将Datagrid WPF C#导出为ex​​cel

时间:2018-01-11 13:21:26

标签: c# wpf excel datagrid

我是C#的新手, 我花时间寻找关于如何将在C#中开发的数据网格WPF导出为ex​​cel的问题的答案。我找到了一些解决方案,比如使用CSV文件,但是这个解决方案不允许在Excel中创建工作表,或者更改格式单元格。

最后,我找到一个解决方案,从此链接的数据网格中逐个单元格迭代:how to loop through all the the cells in datagrid然后我使用该库导出到excel Microsoft.Office.Interop.Excel。

我使用的代码如下:

private void export_Click(object sender, RoutedEventArgs e)
    {
        Microsoft.Office.Interop.Excel._Application excel = new Microsoft.Office.Interop.Excel.Application();
        excel.Visible = true;
        Microsoft.Office.Interop.Excel._Workbook workbook = excel.Workbooks.Add(System.Reflection.Missing.Value);
        DataGrid dg = new DataGrid();

        for (int h = 0; h < _headers.Count; h++)
        {
            int fila = 1;
            dg = ownername_to_datagrid[_headersown[h]];
            workbook.Sheets.Add(After: workbook.Sheets[workbook.Sheets.Count]); // Adiciona una nueva hoja de calculo
            Microsoft.Office.Interop.Excel._Worksheet RCSA1 = (Microsoft.Office.Interop.Excel._Worksheet)workbook.Sheets[h + 1];
            RCSA1.Name = _headers[h];
            Microsoft.Office.Interop.Excel.Range myRange = (Microsoft.Office.Interop.Excel.Range)RCSA1.Cells[fila, 1];
            for (int j = 0; j < dg.Columns.Count; j++)
            {
                myRange = (Microsoft.Office.Interop.Excel.Range)RCSA1.Cells[fila, j + 1];
                RCSA1.Cells[fila, j + 1].Font.Bold = true;
                RCSA1.Columns[j + 1].ColumnWidth = 15;
                myRange.Value2 = dg.Columns[j].Header;
            }
            fila++;

            for (int i = 0; i < dg.Items.Count; i++)
            {
                for (int j = 0; j < dg.Columns.Count; j++)
                {
                    DataGridCell cell = GetCell(i, j, dg);
                    if (cell == null)
                    {

                        TextBlock tb = new TextBlock();
                        tb.Text = "x";
                        myRange = (Microsoft.Office.Interop.Excel.Range)RCSA1.Cells[fila, j + 1];
                        myRange.Value2 = tb.Text;
                        //MessageBox.Show(tb.Text);
                    }
                    else
                    {
                        TextBlock tb = cell.Content as TextBlock;
                        myRange = (Microsoft.Office.Interop.Excel.Range)RCSA1.Cells[fila, j + 1];
                        myRange.Value2 = tb.Text;
                        //MessageBox.Show(tb.Text);
                    }
                }
                fila++;
            }
        }
        MessageBox.Show("Finalizado el proceso de exportación");
    }

    public DataGridCell GetCell(int row, int column, DataGrid dg)
    {
        DataGridRow rowContainer = GetRow(row, dg);

        if (rowContainer != null)
        {
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);

            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            if (cell == null)
            {
                dg.ScrollIntoView(rowContainer, dg.Columns[column]);
                cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            }
            return cell;
        }
        return null;
    }

    public DataGridRow GetRow(int index, DataGrid dg)
    {
        DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
        if (row == null)
        {
            dg.UpdateLayout();
            dg.ScrollIntoView(dg.Items[index]);
            row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
        }
        return row;
    }

    public static T GetVisualChild<T>(Visual parent) where T : Visual
    {
        T child = default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < numVisuals; i++)
        {
            Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
            child = v as T;
            if (child == null)
            {
                child = GetVisualChild<T>(v);
            }
            if (child != null)
            {
                break;
            }
        }
        return child;
    }

解释代码时,第一个for循环是生成2张具有相应名称的表,每张表包含一个数据网格,然后for的for循环中的frist for to export to excel每列的标题(title),那么下一个是打印每个数据网格单元格的内容为excel。

我遇到的问题如下: 如果我不刷新包含datagrid的每个选项卡(我知道数据网格有数据但我没有打开选项卡)当我导出到excel时,我检测到空值。 (我在检测空值时设置了打印x的条件)

我在c#中的屏幕看起来像: C# tabs to excel

我没有打开包含带数据的数据网格的RCSA选项卡,当我看到excel时,它有以下内容: RCSA TAB Null Values

有时,使用相同的数据,有时会出现以下错误: error

为了避免这种错误,我只需打开RCSA选项卡并在datagrid中单击,或者只查看整个数据网格。

我不知道发生了什么,或者为什么neede喜欢在C#视图中刷新数据网格,

感谢您的帮助

0 个答案:

没有答案