背景
最近工作需要计算工资,取值excel表里列比较多,开发中使用开源库POI读取excel文件其中取某列方式row.getCell(列索引)
,而 表格里面列比较多,有些列被其他列遮盖从而导致人工去数列对应的索引很容易数错且比较耗时耗力。
问题
我们平时excel里计算取某个数据可以简单使用=A1
表示取第1行A列的单元格数据值。如果在使用POI读取列的使用列名 代替索引,这样就简单也不容易出错。当时直接感觉可以实现。:A代表1;B代表2;Z代表26,单个数字好表示但如AA、 AAA、AAAA 这些使用数字代表哪些列就比较困难。有困难也要上啊。
分析
我们知道A到Z共26个字母,那么可以用1到26一一映射到A到Z上面
excel列名和数字映射关系
A - Z 1 - 26 <=> 1 - 26
AA - AZ 27 - 52 <=> 26+1 - 26+26
BA - BZ 53 - 78 <=> 26*2+1 - 26*2+26
...
...
ZA - ZZ 677 - 702 <=> 26*26+1 - 26*26+26
AAA - AAZ 702 - 728 <=> 26*26+26+1 - 26*26+26+26
ABA - ABZ 729 - 753 <=> 26*26+26*2+1 - 26*26+26*2+26
从上面映射关系我们看可以看出相邻列对应相差26,每个字母都可以使用26表示,类似十进制表示方法 如222 = 10 * 10 * 2 + 10 * 2 + 2.所有我们可以这样找到列名对应的数字。列字母从右到左,每移动一位字母,字母代表的数字翻26倍,字母代表数字为字母对应 翻倍数*字母本身值,最后列字母表示数字为各个字母计算出来的数字相加和。如ABC代表数字 C + 26 * B + 26 * 26 * A = 3 + 26 * 2 + 26 * 26 * 1 = 731
解决
既然找到规律就可以使用代码表示,具体算法如下
int result = 0;
int radix = 1;
for (int i = col.length() - 1; i >= 0; i--) {
char c = col.charAt(i);//从右到左的每个字母
result += (c - 'A' + 1) * radix;
radix *= 26;//每移动一位翻26倍
}
总结
在解决问题时候,我们需要先观察事物变化的规律,有了规律问题就会迎刃而解。