如何使用VSTO将数据从C#顺利地获取到Excel,然后再返回
本文关键字:Excel 获取 然后 返回 VSTO 何使用 数据 | 更新日期: 2023-09-27 18:24:23
我正在用C#为Excel编写一个应用程序级插件。
外接程序用于将来自外部源的数据(外接程序为此提供了一些GUI选项等)获取到Excel中。这些数据不会被更新并发送回数据源或类似的东西——尽管用户当然可以在本地Excel应用程序中自由编辑数据。
数据以XML格式到达,目前我已经使用了一个代码生成工具,能够将XML文档反序列化为C#对象。数据遵循关系模型。
我现在想的是:
- 我应该使用DataTables将所有内容转换为DataSet对象吗
- 如果我已经这样做了,我如何将这些数据放入Excel工作表?是否可以在excel中创建一个表,并将数据绑定到我的数据表/数据集
- 实际上,我不认为我想要一个"表"本身,而是将数据放入单元格中,然后用户就可以使用这些单元格了。只提供2D阵列是否更好?但是从DataTable数据行到2D数组不是很痛苦吗
还有其他一些问题。。。
- 将数据从Excel读回C#最简单/最好的方法是什么?我想我会满足于在这里得到2D阵列。但是遍历"Range"对象似乎很麻烦。一定有更好的方法吗
- 工作表可能在第一行中有列名,然后在其余行中有数据。当用户选择了组成我的"表"的单元格时,C#代码有什么方法可以识别这一点吗?还是这只是我必须在代码中手动处理的事情
我以前从未处理过这个问题,所以如果有些问题看起来很愚蠢,我会道歉。感谢您的帮助。
以下是我以前打开excel并从excel中获取数据的一些示例:公共类ExcelModule{private Excel.Application excelApp;private Excel.工作簿excelBook;private Excel.Wheet excelSheet;
object misValue = System.Reflection.Missing.Value;
object oMissing = System.Reflection.Missing.Value;
public ExcelModule()
{
}
public void OpenWorksheet(string fileName, int sheetNum)
{
excelApp = new Excel.Application();
excelBook = excelApp.Workbooks.Open(fileName,
0,
true,
5,
"",
"",
true,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,
"'t",
false,
false,
0,
true,
1,
0);
excelSheet = (Excel.Worksheet)excelBook.Worksheets.get_Item(sheetNum);
}
public string GetValue(string cellAddress)
{
if (excelSheet.get_Range(cellAddress, cellAddress).Value2 != null)
return excelSheet.get_Range(cellAddress, cellAddress).Value2.ToString();
else
return "";
}
public int Close()
{
excelApp.Quit();
return 0;
}
~ExcelModule()
{
excelApp.Quit();
}
}
要将数据写入Excel,您可以使用:
excelSheet.get_Range(cellAddress, cellAddress).Value2 = "your text";
注意事项:*我正在将VS10与Office2007 一起使用
不确定为什么我的问题被否决。。。至少要给出理由,否则他们下次会变得更好吗?
不管怎样。在我看来,最好的解决方案是将我的数据放入一个数据集,然后在Excel应用程序中创建一个ListObject,并使用它的数据绑定功能将数据放入Excel。
以前没有意识到这种巨大的控制力。
在Excel中使用range和2d数组将获得更好的性能。在这里,当您将传入的xml反序列化为对象时,不需要将其转换为数据集,然后再转换为2d数组。建议您在代码的视图层直接将对象转换为二维数组,然后在excel表中绑定范围。为了读回,从范围将数据读入2d数组,然后将其转换回对象,您可以序列化该对象并将其发送回服务器。现在,使用范围或数组的有效性或准确性将取决于工作表中数据的外观。为了区分标题和数据,您可以查看命名范围,这可能会有所帮助。
Excel表(又名"ListObjects")为您提供免费的格式设置,而且它们很容易使用。对应的类型为ListObject
。
您可以将它们与LINQ一起使用,而无需制造DataSet
对象:
ListObject myTable; // usually declared somewhere else, eg. via the designer
var data = from x in myObjects select new
{
Foo = x.Foo,
Bar = x.Bar
};
myTable.SetDataBinding(data.ToList());
这将使用反射用您的数据填充表格。在上面的示例中,您将有两个标题为Foo和Bar的列,以及与myObjects
中的元素一样多的行。
当然,您可以使用更复杂的查询。在您的情况下,将Linq用于XML可能是个好主意。关键是,你可以在几行中做你想做的事情。
此外,您可以将任何IList<object>
放入SetDataBinding
中。