【发布时间】: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