如何使用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#代码有什么方法可以识别这一点吗?还是这只是我必须在代码中手动处理的事情

我以前从未处理过这个问题,所以如果有些问题看起来很愚蠢,我会道歉。感谢您的帮助。

如何使用VSTO将数据从C#顺利地获取到Excel,然后再返回

以下是我以前打开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中。