使用OpenXML C#获取Excel单元格的列索引

我一直在寻找一段时间,似乎无法find如何做到这一点。 我有一个Excel表格,我正在使用OpenXML阅读。 现在正常的事情是循环行,然后循环通过单元格获取值,这很好。 但是,随着值我需要的单元格的位置,这将是格式(rowindex,ColumnIndex)。 我设法得到rowIndex,但似乎无法find列索引。

我其实觉得这很容易,但显然不是。

由于可以使用Worksheet.Descendants<Cell>()循环访问一行的Worksheet.Descendants<Cell>() ,因此可以简单地使用for -loop来确定单元格的索引。

我有点晚了,回答这个问题,但是如果在你感兴趣的行中有空单元格,那么接受的答案将不起作用,因为它们不能保证在XML中,模式允许空单元格被省略。

要获取索引,您可以使用Cell对象,其中有一个CellReference属性,以A1B1等格式给出引用。您可以使用该引用来提取列号。

正如你可能知道的那样,在Excel A = 1B = 2等中,直到Z = 26在这个点上单元格前缀为A ,给出AA = 27AB = 28等等。注意,在AA的情况下,具有第二十六倍的价值; 即“值得”26,而第二个“值得”1,总共27。

要计算列索引,您可以反转字母,然后取第一个字母的值,并将其添加到正在运行的总数中。 然后取第二个字母的值并乘以26,将总和加到第一个数字上。 第三,你乘以26乘以两次,第四次乘以26三次,依此类推。

所以对于列ABC你会这样做:

 C = 3 B = 2 * 26 = 52 A = 1 * 26 *26 = 676 3 + 52 + 676 = 731 

在C#中,以下内容将起作用:

 private static int? GetColumnIndex(string cellReference) { if (string.IsNullOrEmpty(cellReference)) { return null; } //remove digits string columnReference = Regex.Replace(cellReference.ToUpper(), @"[\d]", string.Empty); int columnNumber = -1; int mulitplier = 1; //working from the end of the letters take the ASCII code less 64 (so A = 1, B =2...etc) //then multiply that number by our multiplier (which starts at 1) //multiply our multiplier by 26 as there are 26 letters foreach (char c in columnReference.ToCharArray().Reverse()) { columnNumber += mulitplier * ((int)c - 64); mulitplier = mulitplier * 26; } //the result is zero based so return columnnumber + 1 for a 1 based answer //this will match Excel's COLUMN function return columnNumber + 1; } 

请注意, CellReference 保证在XML中(尽pipe我从来没有见过它)。 在CellReference为空的情况下,该单元被放置在最左边的可用单元中。 RowIndex在规范中也不是强制性的,所以在这种情况下,单元格可以放在最高的行中。 更多的信息可以在这个问题中看到。 在CellReferencenull情况下, CellReference的答案是正确的。

小是美丽的

 int ColumnIndex(string reference) { int ci=0; reference=reference.ToUpper(); for (int ix = 0; ix < reference.Length && reference[ix] >= 'A';ix++ ) ci = (ci * 26) + ((int)reference[ix] - 64); return ci; } 

要开始回答,我请你先看看这个 。

正如我所解释的, 没有简单的方法来提取行和列。 你得到的最接近的是提取一个单元格的CellReference ,其格式为A1B2 ,实际上是COLUMN_ROW格式。

你可以做的是从CellReference提取Row和Column。 是的,这将需要你实现一个方法,你需要通过char检查char来validation数字和string。

比方说,你有A11 ,那么当你需要索引列时,你需要提取A ,这将列为column 1 。 是的,这并不容易,但是除非您在扫描/遍历单元格时只是select计算列数,否则这是唯一的方法。

再次看看这个问题的答案是做同样的事情。

  [TestCase( 1, 0, "A1" )] [TestCase( 2, 25, "Z2" )] [TestCase( 2, 38, "AM2" )] [TestCase( 2, (26 * 4) + 1, "DB2" )] [TestCase( 2, (26 * 26 * 26 * 18) + (26 * 26 * 1) + (26 * 26 * 1) + ( 26 * 1 ) + 2, "RBAC2" )] public void CanGetCorrectCellReference( int row, int column, string expected ) => GetCellReference( (uint)row, (uint)column ).Value.ShouldEqual( expected ); public static StringValue GetCellReference( uint row, uint column ) => new StringValue($"{GetColumnName("",column)}{row}"); static string GetColumnName( string prefix, uint column ) => column < 26 ? $"{prefix}{(char)( 65 + column)}" : GetColumnName( GetColumnName( prefix, ( column - column % 26 ) / 26 - 1 ), column % 26 );