如何使用 C# 和 Interop.Excel 库从现有 Excel 文件中获取特定元素?
我需要从 Excel 文件获取数据,以将它们打印在 HTML 表中(使用 MVC,无 gridview),并最终将它们存储在数据库中。
表格与Excel的映射关系如下:
Excel->Excel表
第一行 ->表格标题
其他单元格 ->表数据
我正在使用 Interop.Excel 库,它提供了在 .NET 中操作 Excel 文件的方法。
使用此代码,我在 lworkSheet 变量中获得 Excel 文件的 Nth 工作表:
var lworkSheet = xlWorkBook.Worksheets.get_Item(N);
假设 Excel 文件只有一个工作表 (N = 1),我可以使用特定于工作表的工作表属性来获取行、列、单元格和范围。这些属性返回 Interop.Excel.Range 类型的对象。
问题在于,行、列和单元格分别返回 Excel 文件中的所有行、列和单元格,而不仅仅是填充数据的行、列和单元格。因此,为了获取我所做的数据(Excel项的索引是从1开始的):
var lheaders = xlWorkSheet.Rows.get_Item(1);
var lexcelItems = new Excel.Range[xlWorkSheet.Rows.Count, xlWorkSheet.Columns.Count];
for (var i=0; i < xlWorkSheet.Rows.Count; i++)
{
for(var j=0; j < xlWorkSheet.Columns.Count; j++)
{
lexcelItems[i,j] = xlWorkSheet.Cells.get_Item(i+2, j+1);
}
}
除了循环所有行和列的计算浪费之外,这些解决方案仍然不可接受,因为 get_Item() 方法返回 Range 对象!!为了获取单元格中的项目,我必须使用 get_Range(cell_start, cell_end) 方法并以“A1”、“A2”等格式指定单元格。
问题:
1)有什么方法可以识别行和列中的最后一项吗?
2)有什么方法可以在不指定范围的情况下获取单元格中的值?
3)有没有实现Excel.Range增量的库? (即(A1++)== A2,等等...)。
4)如果以上都不可行,有没有简单的方法用OLEDB读取Excel?
谢谢
弗朗西斯科
I need to get data from an Excel file to print them in a HTML table (using MVC, no gridview) and eventually store them in a Database.
The mapping between table and Excel is as follows:
Excel -> Table
First Row -> Table headers
Other Cells -> Table data
I am using the Interop.Excel library that provides methods to manipulate Excel files in .NET.
With this code I obtain in lworkSheet variable the Nth worksheet of the Excel file:
var lworkSheet = xlWorkBook.Worksheets.get_Item(N);
Let's assume the Excel file has just one worksheet (N = 1), I can use worksheet specific properties to get Rows, Columns, Cells and Range. These properties return objects of type Interop.Excel.Range.
The problem is that Rows, Columns and Cells return, respectively, all the rows, columns and cells in the Excel file not just those that are filled with data. Therefore in order to get the data I do (the index of the Excel items are 1-based):
var lheaders = xlWorkSheet.Rows.get_Item(1);
var lexcelItems = new Excel.Range[xlWorkSheet.Rows.Count, xlWorkSheet.Columns.Count];
for (var i=0; i < xlWorkSheet.Rows.Count; i++)
{
for(var j=0; j < xlWorkSheet.Columns.Count; j++)
{
lexcelItems[i,j] = xlWorkSheet.Cells.get_Item(i+2, j+1);
}
}
Besides the computational waste of cycling all rows and columns, these solution is still not acceptable because the get_Item() method returns Range objects!! In order to get the item in the cell I have to use the get_Range(cell_start, cell_end) method and specify the cells in the "A1", "A2", etc... format.
QUESTIONS:
1) Any way to identify last item in row and column?
2) Any way to get the value in the cell without specify the range?
3) Any library that implements the Excel.Range increment? (i.e. (A1++) == A2, etc...).
4) If none of the above is feasible, is there an easy way to read Excel with OLEDB?
Thanks
Francesco
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
还没有使用过这个库,所以我只是从 MSDN 文档中做出有根据的猜测。您是否在寻找
Worksheet.UsedRange
?http: //msdn.microsoft.com/en-us/library/microsoft.office.interop.excel._worksheet.usedrange(v=office.11).aspx
获得
范围
后,看起来您可以使用Range.Cells
属性(类似于您正在使用的Worksheet.Cells
属性)来获取单个单元格的范围,然后使用Range.Value
或Range.Value2
属性来获取该单元格的值:http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range_properties (v=office.11).aspx
要根据位置而不是行/列名称指定
UsedRange
内的单元格,请使用Range.Offset
:< a href="http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range(v=office.11).aspx" rel="nofollow">http://msdn .microsoft.com/en-us/library/microsoft.office.interop.excel.range(v=office.11).aspx
Haven't worked with this library so I'm just making an educated guess from the MSDN documentation. Are you looking for
Worksheet.UsedRange
?http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel._worksheet.usedrange(v=office.11).aspx
Once you have the
Range
, it looks like you can use theRange.Cells
property (analogous to theWorksheet.Cells
property you're using) to get a range of a single cell and then use theRange.Value
orRange.Value2
property to get that cell's value:http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range_properties(v=office.11).aspx
To specify the cells within the
UsedRange
based on position rather than row/column names, useRange.Offset
:http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range(v=office.11).aspx
使用 OLEDB 访问/处理 Excel 数据比循环 .Cells(); 更好将带有一个 SQL 语句的(选择的)工作表放入数据库表中,或者将结果集作为 HTML 表而不使用任何 Fors 的 .GetString 是很有吸引力的。
缺点:如果您的数据包含垃圾,高级 ADO/OLEDB 设施不会给您干预的机会。
添加:
在做一些有关“全部”对于 Excel 工作表意味着什么的实验时,我偶然发现了一个有趣的事实?关于“$”。也许我不是唯一一个没有意识到这一点的人:
这是我的 VBScript 测试脚本的输出:
看起来 [Sheet$] 打开了 Excel Quirks 模式,该模式将比 [Sheet] 启用的更严格的方法考虑更多的行]。
Using OLEDB to access/process Excel data is better than to loop over .Cells(); putting a (selection of) a sheet with one SQL statement into a database table or .GetString a resultset as a HTML table without any Fors is attractive.
The con: if your data contains garbage, the high level ADO/OLEDB facilities won't give you a chance to interfere.
ADDED:
While doing some experiments wrt what "all" means for an Excel sheet, I stumbled upon an interesting fact? about the "$". Perhaps I'm not the only one being not aware of this:
This is the output from my VBScript test script:
Looks like [Sheet$] turns on an Excel Quirks mode, that will consider more rows than the stricter approach enabled by [Sheet].