编辑:太好了,我刚刚注意到我错过了您问题的很大一部分,将更新和删除返回到工作表。我完全不知道这是否可能,但我认为这使我的解决方案毫无价值。无论如何我都会把它留在这里,也许它可以以任何方式提供帮助。
为什么需要 VSTO?据我所知,VSTO 用于 Office 加载项。但是由于您想在 DataGridView 中显示数据,我假设您有一个应该只访问工作簿的 WinForms 应用程序。在这种情况下,您只需使用 Office Interop 打开工作簿。只需在项目中添加对 Microsoft.Office.Interop.Excel 的引用并添加using Microsoft.Office.Interop.Excel;
语句。
Excel Interop 的 MSDN 参考文档可在此处找到:http: //msdn.microsoft.com/en-us/library/ms262200%28v=office.14%29.aspx
我会给你 Excel 部分,也许其他人可以做剩下的。
首先,打开 Excel 和工作簿:
Application app = new Application();
// Optional, but recommended if the user shouldn't see Excel.
app.Visible = false;
app.ScreenUpdating = false;
// AddToMru parameter is optional, but recommended in automation scenarios.
Workbook workbook = app.Workbooks.Open(filepath, AddToMru: false);
然后以某种方式获得正确的工作表。你有几个可能性:
// Active sheet (should be the one which was active the last time the workbook was saved).
Worksheet sheet = workbook.ActiveSheet;
// First sheet (notice that the first is actually 1 and not 0).
Worksheet sheet = workbook.Worksheets[1];
// Specific sheet.
// Caution: Default sheet names differ for different localized versions of Excel.
Worksheet sheet = workbook.Worksheets["Sheet1"];
然后得到正确的范围。您没有指定如何知道所需数据的位置,因此我假设它位于固定列中。
// If you also know the row count.
Range range = sheet.Range["A1", "D20"];
// If you want to get all rows until the last one that has some data.
Range lastUsedCell = sheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell);
string columnName = "D" + lastUsedCell.Row;
Range range = sheet.Range["A1", columnName];
获取值:
// Possible types of the return value:
// If a single cell is in the range: Different types depending on the cell content
// (string, DateTime, double, ...)
// If multiple cells are in the range: Two dimensional array that exactly represents
// the range from Excel and also has different types in its elements depending on the
// value of the Excel cell (should always be that one in your case)
object[,] values = range.Value;
然后可以将该二维对象数组用作 DataGridView 的数据源。好多年没用过WinForms了,不知道能不能直接绑定还是先把数据弄成某种特定的格式。
最后再次关闭 Excel:
workbook.Close(SaveChanges: false);
workbook = null;
app.Quit();
app = null;
// Yes, we really want to call those two methods twice to make sure all
// COM objects AND all RCWs are collected.
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
使用 Interop 后正确关闭 Excel 本身就是一项任务,因为您必须确保已释放对 COM 对象的所有引用。我发现做到这一点的最简单方法是以单独的方法完成所有工作,除了打开和关闭 Excel 和工作簿(所以我的第一个和最后一个代码块)。这可确保在该方法中使用的所有 COM 对象在Quit
被调用时都超出范围。