【问题标题】:WPF - Exporting DataGrid to Excel, Microsoft.Office.Interop.Excel alternative for Office 2019 [closed]WPF - 将 DataGrid 导出到 Excel,Microsoft.Office.Interop.Excel 替代 Office 2019 [关闭]
【发布时间】:2021-08-19 12:21:47
【问题描述】:

我正在尝试将我的 DataGrid 导出到 Excel (Office 2019/365)。 我的方法是使用Microsoft.Office.Interop.Excel 扩展,但它会引发异常,并且我了解到它仅适用于 Office 2013。

所以我的问题是,是否有任何适用于 Office 2019 且可与 Microsoft.Office.Interop.Excel 互换的扩展?尽可能少地进行重构会很棒。

我的方法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Microsoft.Office.Interop.Excel;

namespace My.NameSpace {

    class ExcelExport {

        public static void ExportDataGrid(object sender) {

            DataGrid currentGrid = sender as DataGrid;
            if (currentGrid != null) {

                StringBuilder sbGridData = new StringBuilder();
                List<string> listColumns = new List<string>();

                List<DataGridColumn> listVisibleDataGridColumns = new List<DataGridColumn>();

                List<string> listHeaders = new List<string>();

                Microsoft.Office.Interop.Excel.Application application = null;
                Workbook workbook = null;
                Worksheet worksheet = null;

                int rowCount = 1;
                int colCount = 1;

                try {

                    application = new Microsoft.Office.Interop.Excel.Application();
                    workbook = application.Workbooks.Add(Type.Missing);
                    worksheet = (Worksheet)workbook.Worksheets[1];

                    if (currentGrid.HeadersVisibility == DataGridHeadersVisibility.Column || currentGrid.HeadersVisibility == DataGridHeadersVisibility.All) {

                        foreach (DataGridColumn dataGridColumn in currentGrid.Columns.Where(dataGridColumn => dataGridColumn.Visibility == Visibility.Visible)) {

                            listVisibleDataGridColumns.Add(dataGridColumn);
                            if (dataGridColumn.Header != null) {

                                listHeaders.Add(dataGridColumn.Header.ToString());
                            }

                            worksheet.Cells[rowCount, colCount] = dataGridColumn.Header;
                            colCount++;
                        }

                        // IEnumerable collection = currentGrid.ItemsSource

                        foreach (object data in currentGrid.ItemsSource) {

                            listColumns.Clear();
                            colCount = 1;
                            rowCount++;

                            foreach (DataGridColumn dataGridColumn in listVisibleDataGridColumns) {

                                string strValue = string.Empty;
                                Binding objBinding = null;
                                DataGridBoundColumn dataGridBoundColumn = dataGridColumn as DataGridBoundColumn;

                                if (dataGridBoundColumn != null) {

                                    objBinding = dataGridBoundColumn.Binding as Binding;
                                }

                                DataGridTemplateColumn dataGridTemplateColumn = dataGridColumn as DataGridTemplateColumn;

                                if (dataGridTemplateColumn != null) {

                                    // this is a template column, let's see the underlying dependency object
                                    DependencyObject dependencyObject = dataGridTemplateColumn.CellTemplate.LoadContent();

                                    FrameworkElement frameworkElement = dependencyObject as FrameworkElement;

                                    if (frameworkElement == null) {

                                        FieldInfo fieldInfo = frameworkElement.GetType().GetField("ContentProperty", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
                                        
                                        if (fieldInfo == null) {

                                            if (frameworkElement is System.Windows.Controls.TextBox || frameworkElement is TextBlock || frameworkElement is ComboBox) {

                                                fieldInfo = frameworkElement.GetType().GetField("TextProeprty");

                                            } else if (frameworkElement is DatePicker) {

                                                fieldInfo = frameworkElement.GetType().GetField("SelectedDateProperty");
                                            }
                                        }

                                        if (fieldInfo != null) {

                                            DependencyProperty dependencyProperty = fieldInfo.GetValue(null) as DependencyProperty;
                                            if (dependencyProperty != null) {

                                                BindingExpression bindingExpression = frameworkElement.GetBindingExpression(dependencyProperty);
                                                if (bindingExpression != null) {

                                                    objBinding = bindingExpression.ParentBinding;
                                                }
                                            }
                                        }
                                    }
                                }

                                if (objBinding != null) {

                                    if (!String.IsNullOrEmpty(objBinding.Path.Path)) {

                                        PropertyInfo pi = data.GetType().GetProperty(objBinding.Path.Path);

                                        if (pi != null) {

                                            object propValue = pi.GetValue(data, null);

                                            if (propValue != null) {

                                                strValue = Convert.ToString(propValue);

                                            } else {

                                                strValue = string.Empty;
                                            }
                                        }
                                    }

                                    if (objBinding.Converter != null) {

                                        if(!String.IsNullOrEmpty(strValue)) {

                                            strValue = objBinding.Converter.Convert(strValue, typeof(string), objBinding.ConverterParameter, objBinding.ConverterCulture).ToString();

                                        } else {

                                            strValue = objBinding.Converter.Convert(data, typeof(string), objBinding.ConverterParameter, objBinding.ConverterCulture).ToString();
                                        }
                                    }
                                }

                                listColumns.Add(strValue);

                                worksheet.Cells[rowCount, colCount] = strValue;

                                colCount++;
                            }
                        }
                    }

                } catch (System.Runtime.InteropServices.COMException) {

                } finally {

                    workbook.Close();
                    application.Quit();
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(application);
                }
            }
        }
    }
}

【问题讨论】:

  • 我最近一直在移动我的应用程序以使用 ClosedXML。你可以将它作为 Nuget 添加到你的项目中,它的 Github 存储库应该有关于如何开始的相当不错的文档!
  • @mm8,我使用的是 15.0.4795.1000(最新稳定版本)。回想起来,我应该看到它在描述中说它仅适用于 Office 2013。
  • @Jaskier,谢谢你的提示——我会调查的!
  • @OleM:尝试在 Visual Studio 的引用管理器的 COM 选项卡下添加对 Microsoft Office 16.0 Object Library 的引用。
  • @mm8,感谢您的建议 - 不幸的是,问题仍然存在。

标签: c# excel wpf datagrid office-interop


【解决方案1】:

它可能没有相同的 api,但 EPPlus 是从 c# 创建 excel 文件的好选择。

它不使用互操作库,因此它不依赖于安装的 Office 版本(根本不需要 office)。

4.5.3 版本是使用 LGPL 许可证的最后一个版本,以后的版本有双重许可证,商业用途需要收费。

【讨论】:

  • 感谢您的提示,我们会​​调查并回复您!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 2013-11-08
  • 2021-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多