使用OpenXML C#获取Excel中单元格的列索引 |
您所在的位置:网站首页 › 获取单元格列名 › 使用OpenXML C#获取Excel中单元格的列索引 |
我已经环顾了一段时间,但似乎找不到解决方法。 我有一个Excel工作表,正在使用OpenXML进行阅读。 现在正常的事情是遍历行,然后遍历单元格以获取值,这很好。 但是,与值一起,我需要单元格的位置,该位置应采用以下格式(行索引,列索引)。 我已经设法获得rowIndex,但似乎无法弄清楚获得列Index。 我实际上以为这很容易,但显然不是。 相关讨论 对于将来的读者,我建议您查看此答案。这比您想象的要复杂一些,因为该架构允许省略空单元格。 要获取索引,可以使用Cell对象,该对象具有CellReference属性,该属性以A1,B1等格式提供引用。您可以使用该引用来提取列号。 您可能知道,在Excel A = 1,B = 2等到Z = 26中,在该点处,单元格都以A为前缀,以给出AA = 27,AB = 28等。请注意,在第一个A的值为第二个的26倍;即它是"价值" 26,而第二个A是"价值" 1,总共为27。 要计算列索引,您可以反转字母,然后获取第一个字母的值并将其添加到运行总计中。然后取第二个字母的值,然后乘以26,将总数加到第一个数字上。对于第三个,将其乘以26两次并相加,对于第四个,将其乘以26 3次,依此类推。 因此,对于列ABC,您可以执行以下操作: 1234C = 3 B = 2 * 26 = 52 A = 1 * 26 *26 = 676 3 + 52 + 676 = 731在C#中,以下将起作用: 123456789101112131415161718192021222324252627private 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中(尽管我从未见过它不存在)。在CellReference为null的情况下,该单元格放置在最左侧的可用单元格中。 RowIndex在规范中也不是必需的,因此在这种情况下也可以将其省略,将单元格放置在可用的最高行中。在此问题中可以看到更多信息。在CellReference为null的情况下,@ BCdotWEB的答案是正确的方法。 相关讨论 您可以从columnNumber = 0开始,并且返回时不加一。 第二个字母中的Z会发生什么?与第三个A相同吗?所以Z = 26*26和A = 1*26*26。我问,因为我试图做从单元格索引到单元格名称的反向操作。 第二个字母中的Z为"值"26。该值将与第一个字母的值相加26倍。例如。 ZZ将是(26 * 26) + 26 = 702。第三列中的A是"值" 1。这将被添加到第二个字母的值的26倍和第一个字母的值的26 * 26倍。例如AAA将是(26 * 26 * 1) + (26 * 1) + 1 = 703。 @ bostero2顺便说一句,如果仍然不清楚,请创建一个新问题,然后在此处ping我,我将给您写一个有关如何进行反向操作的答案。 @petelids是的,发布评论后想通了。谢谢!小就是美丽 12345678int ColumnIndex(string reference) { int ci=0; reference=reference.ToUpper(); for (int ix = 0; ix = 'A';ix++ ) ci = (ci * 26) + ((int)reference[ix] - 64); return ci; } 相关讨论 关心解释64? @Yaron:64是(A-1) 1234567891011121314 [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 = '0' && c = 'A' && c ch - AsciiTrim) .Select((ch, i) => ch * Math.Pow(LastChar, i)) .Sum() - 1; //make zero-index based要还原,以及完整的代码和测试,请参阅此要点。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |