以编程方式获取最后填充的Excel行使用C#
我正在尝试使用Microsoft.interop.Excel库和C#以编程方式获取Excel表格的最后一行。 我想这样做,因为我负责循环查看Excel电子表格的所有logging并对它们执行某种操作。 具体来说,我需要最后一行的实际数字,因为我将这个数字放入函数中。 任何人有任何想法如何做到这一点?
夫妻方式,
using Excel = Microsoft.Office.Interop.Excel; Excel.ApplicationClass excel = new Excel.ApplicationClass(); Excel.Application app = excel.Application; Excel.Range all = app.get_Range("A1:H10", Type.Missing);
要么
Excel.Range last = sheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing); Excel.Range range = sheet.get_Range("A1", last); int lastUsedRow = last.Row; int lastUsedColumn = last.Column;
这是Excel中的常见问题。
这里是一些C#代码:
// Find the last real row nInLastRow = oSheet.Cells.Find("*",System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, Excel.XlSearchOrder.xlByRows,Excel.XlSearchDirection.xlPrevious, false,System.Reflection.Missing.Value,System.Reflection.Missing.Value).Row; // Find the last real column nInLastCol = oSheet.Cells.Find("*", System.Reflection.Missing.Value, System.Reflection.Missing.Value,System.Reflection.Missing.Value, Excel.XlSearchOrder.xlByColumns,Excel.XlSearchDirection.xlPrevious, false,System.Reflection.Missing.Value,System.Reflection.Missing.Value).Column;
在这里find
或使用SpecialCells
Excel.Range last = sheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing); Excel.Range range = sheet.get_Range("A1", last);
[编辑]类似的线程:
- VB.NET – 读取excel文件的整个内容
- 如何获得Excel表格中占用的单元格的范围
Pryank的答案是最接近我的。 我添加了一点点( .Row
),所以我不只是返回一个range
,而是一个integer
。
int lastRow = wkSheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing).Row;
对于涉及Excel对象模型的问题,首先在VBA中试用它比较容易,然后转换为C#是相当简单的。
在这种情况下,在VBA中做到这一点的一个方法是:
Worksheet.UsedRange.Row + Worksheet.UsedRange.Rows.Count - 1
唯一的办法,我可以得到它在所有情况下工作(除保护表):
它支持:
-
扫描隐藏的行/列
-
忽略没有数据/公式的格式化单元格
码:
// Unhide All Cells and clear formats sheet.Columns.ClearFormats(); sheet.Rows.ClearFormats(); // Detect Last used Row - Ignore cells that contains formulas that result in blank values int lastRowIgnoreFormulas = sheet.Cells.Find( "*", System.Reflection.Missing.Value, InteropExcel.XlFindLookIn.xlValues, InteropExcel.XlLookAt.xlWhole, InteropExcel.XlSearchOrder.xlByRows, InteropExcel.XlSearchDirection.xlPrevious, false, System.Reflection.Missing.Value, System.Reflection.Missing.Value).Row; // Detect Last Used Column - Ignore cells that contains formulas that result in blank values int lastColIgnoreFormulas = sheet.Cells.Find( "*", System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, InteropExcel.XlSearchOrder.xlByColumns, InteropExcel.XlSearchDirection.xlPrevious, false, System.Reflection.Missing.Value, System.Reflection.Missing.Value).Column; // Detect Last used Row / Column - Including cells that contains formulas that result in blank values int lastColIncludeFormulas = sheet.UsedRange.Columns.Count; int lastColIncludeFormulas = sheet.UsedRange.Rows.Count;
ActiveSheet.UsedRange.Value返回[row,column]的二维对象数组。 检查两个维度的长度将提供LastRow索引和LastColumn索引。 以下示例使用C#。
Excel.Worksheet activeSheet; Excel.Range activeRange; public virtual object[,] RangeArray { get { return ActiveRange.Value; } } public virtual int ColumnCount { get { return RangeArray.GetLength(1); } } public virtual int RowCount { get { return RangeArray.GetLength(0); } } public virtual int LastRow { get { return RowCount; } }
这个问题在有可能是空单元的时候会更糟。 但是,即使只填充了一个值,也必须读取一行。 当有很多未填充的单元格时,可能需要一段时间,但是如果input接近正确,则速度相当快。
我的解决scheme忽略完全空行并返回最长的列的行数:
private static int GetLastRow(Worksheet worksheet) { int lastUsedRow = 1; Range range = worksheet.UsedRange; for (int i = 1; i < range.Columns.Count; i++) { int lastRow = range.Rows.Count; for (int j = range.Rows.Count; j > 0; j--) { if (lastUsedRow < lastRow) { lastRow = j; if (!String.IsNullOrWhiteSpace(Convert.ToString((worksheet.Cells[j, i] as Range).Value))) { if (lastUsedRow < lastRow) lastUsedRow = lastRow; if (lastUsedRow == range.Rows.Count) return lastUsedRow - 1; break; } } else break; } } return lastUsedRow; }
对于那些使用SpecialCells方法的人(我不太确定其他人),请注意,如果你的最后一个单元格被合并 ,你将无法使用Range.Row和Range.Column得到最后一行和列号最后一行和一列作为数字。 你需要先取消你的范围,然后再次获得最后一个单元格。 这花了我很多。
private int[] GetLastRowCol(Ex.Worksheet ws) { Ex.Range last = ws.Cells.SpecialCells(Ex.XlCellType.xlCellTypeLastCell, Type.Missing); bool isMerged = (bool)last.MergeCells; if (isMerged) { last.UnMerge(); last = ws.Cells.SpecialCells(Ex.XlCellType.xlCellTypeLastCell, Type.Missing); } return new int[2] { last.Row, last.Column }; }