将Excel列字母(例如AA)转换为数字(例如25)

25

在我的表格中,列标题像Excel电子表格一样被命名为 A,B,C......AA,AB,AC... 等。我该如何将这个字符串转换成数字呢,比如: A => 1,B => 2,AA => 27


1
一个小修正... AA 应该是 27。 - Chetter Hummin
2
你不能直接使用要转换的列的位置作为其数字值吗?如果AA在第25个位置,那就是你要找的答案... - Yaniro
1
没有相应的代码片段。如果你正在写一个,把你已经完成的展示出来吧。顺便问一下,为什么 AA 是25而不是27? - Andy E
这是“Excel列编号”,已经有一些关于概念和瑕疵的SO问题存在,可能不是使用JavaScript。 - user166390
这会有帮助的:https://dev59.com/SHA75IYBdhLWcg3wuLjD - Adrien Schuler
我只得到一个对象,其中包含 { columnfrom:'A', columnTo:'AB' }.. 这就是问题。 - Jaison Justus
10个回答

49

请尝试:

var foo = function(val) {
  var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', i, j, result = 0;

  for (i = 0, j = val.length - 1; i < val.length; i += 1, j -= 1) {
    result += Math.pow(base.length, j) * (base.indexOf(val[i]) + 1);
  }

  return result;
};

console.log(['A', 'AA', 'AB', 'ZZ'].map(foo)); // [1, 27, 28, 702]

19

解决方案1:最佳性能和浏览器兼容性

// convert A to 1, Z to 26, AA to 27
function lettersToNumber(letters){
    var chrs = ' ABCDEFGHIJKLMNOPQRSTUVWXYZ', mode = chrs.length - 1, number = 0;
    for(var p = 0; p < letters.length; p++){
        number = number * mode + chrs.indexOf(letters[p]);
    }
    return number;
}

解决方案2:性能和兼容性最佳,且代码更短 (推荐)

// convert A to 1, Z to 26, AA to 27
function lettersToNumber(letters){
    for(var p = 0, n = 0; p < letters.length; p++){
        n = letters[p].charCodeAt() - 64 + n * 26;
    }
    return n;
}

解决方案3:短代码(ES6箭头函数)

// convert A to 1, Z to 26, AA to 27
function lettersToNumber(letters){
    return letters.split('').reduce((r, a) => r * 26 + parseInt(a, 36) - 9, 0);
}

测试:

['A', 'Z', 'AA', 'AB', 'ZZ','BKTXHSOGHKKE'].map(lettersToNumber);
// [1, 26, 27, 28, 702, 9007199254740991]

lettersToNumber('AAA'); //703

8
这是一个快速的实现代码示例。 这将适用于任何给定数量的字母。
function letterToNumbers(string) {
    string = string.toUpperCase();
    var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', sum = 0, i;
    for (i = 0; i < string.length; i++) {
        sum += Math.pow(letters.length, i) * (letters.indexOf(string.substr(((i + 1) * -1), 1)) + 1);
    }
    return sum;
}

你的指数运算存在一些小错误。例如,使用你的函数进行计算,AB 的结果为 53 而不是 28 - Yoshi
你是正确的。我修复了代码。应该是:string.substr(((i + 1) * -1), 1) - iMoses

4
// Given Column to Number
function colToNumber(str) {
  let num = 0
  let i = 0
  while (i < str.length) {
    num = str[i].charCodeAt(0) - 64 + num * 26;
    i++;
  }
  return num;
}

//Given Number to Column name
function numberToCol(num) {
  let str = '', q, r;
  while (num > 0) {
    q = (num-1) / 26;
    r = (num-1) % 26
    num = Math.floor(q)
    str = String.fromCharCode(65 + r) + str;
  }
  return str;
}

你有尝试过吗?numberToCol根本不起作用。 - John Hamm
1
这是一个打字错误。numberToCol 应该有 "num = Math.floor(q);"。它可以工作! - Udhayha Karthik

3
我刚写了一段糟糕的代码...需要进行优化.. :)
charToNum = function(alpha) {
        var index = 0
        for(var i = 0, j = 1; i < j; i++, j++)  {
            if(alpha == numToChar(i))   {
                index = i;
                j = i;
            }
        }
        console.log(index);
    }

numToChar = function(number)    {
        var numeric = (number - 1) % 26;
        var letter = chr(65 + numeric);
        var number2 = parseInt((number - 1) / 26);
        if (number2 > 0) {
            return numToChar(number2) + letter;
        } else {
            return letter;
        }
    }
chr = function (codePt) {
        if (codePt > 0xFFFF) { 
            codePt -= 0x10000;
            return String.fromCharCode(0xD800 + (codePt >> 10), 0xDC00 + (codePt & 0x3FF));
        }
        return String.fromCharCode(codePt);
    }

charToNum('A') => 返回1,charToNum('AA') => 返回27;


(说明:该内容涉及IT技术,是一段代码示例,其中charToNum是一个函数名,它的作用是将字母转换成数字)

1
numToChar函数工作得很好,但是你的charToNum函数似乎不完整(而且效率低下)。 - mpen
@Mark 是的,这只是一个快速解决方法。如果可能的话,您能否优化代码并发布更好的答案。提前致谢。 - Jaison Justus

1

我重新编写了Yoshi的答案,使用更详细的形式来解释它的工作原理,并且更易于转换成其他语言:

var foo = function(val) {
    var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var baseNumber = base.length;

    var runningTotal = 0;
    var characterIndex = 0;
    var indexExponent = val.length - 1;

    while( characterIndex < val.length ){
        var digit = val[characterIndex];
        var digitValue = base.indexOf(digit) + 1;
        runningTotal += Math.pow(baseNumber, indexExponent) * digitValue;

        characterIndex += 1
        indexExponent -= 1
    }

    return runningTotal;
};

console.log(['A', 'AA', 'AB', 'ZZ'].map(foo)); // [1, 27, 28, 702]

0
Public Function ColLet2Num(Letras As String)
'RALONSO MAYO 2017
'A-> 1
'OQ ->407
'XFD->16384
Dim UnChar As String
Dim NAsc As Long
Dim F As Long
Dim Acum As Long
Dim Indice As Long
Letras = UCase(Letras)
Acum = 0
Indice = 0
For F = Len(Letras) - 1 To 0 Step -1

    UnChar = Mid(Letras, F + 1, 1)
    NAsc = Asc(UnChar) - 64
    Acum = Acum + (NAsc * (26 ^ Indice))
    Indice = Indice + 1
Next
If Acum > 16384 Then
    MsgBox "La celda máxima es la XFD->16384", vbCritical
End If
ColLet2Num = Acum
End Function

0
一个良好的可读性和性能示例:
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// create dict to O(1) access to letter number
const dict = Object.fromEntries(letters.split('').map((it, index) => [it, index + 1]));

function toNumber(col) {
    return col
        .toUpperCase()
        .split('')
        .reduce((acc, letter, index) => acc + Math.pow(letters.length, col.length - (index + 1)) * dict[letter], 0);
}

0

受到此页面上提出的不同解决方案的极大启发



//fixed the one taken from here
function colToNumber(str: string): number {
    var num = 0

    for (var i = 0; i < str.length; i++) {
        const current_letter = str.charCodeAt(i) - 64
        const current_char = str[i]
        if (i == str.length - 1) {
            num += current_letter

        } else {
            var current = current_letter * Math.pow(26, str.length - i - 1)
            num += current
        }

    }
    return num;
}

//Given Number to Column name (taken from here)
function numberToCol(num: number) {
    var str = '', q: number, r: number;
    while (num > 0) {
        q = (num - 1) / 26;
        r = (num - 1) % 26
        num = Math.floor(q)
        str = String.fromCharCode(65 + r) + str;
    }
    return str;
}


function test_both() {
    const dic = new Map<number, string>()
    dic.set(1,"A")
    dic.set(10,"J")
    dic.set(13,"M")
    dic.set(33,"AG")
    dic.set(63,"BK")
    dic.set(66,"BN")
    dic.set(206,"GX")
    dic.set(502,"SH")
    dic.set(1003,"ALO")
    dic.set(100,"CV")
    
    dic.set(10111,"NXW")
    dic.set(10001,"NTQ")
    dic.set(9002,"MHF")
    dic.set(5002,"GJJ")
    dic.set(3002,"DKL")
    dic.set(16384,"XFD")

    for (var key of dic.keys()) {
        const expected_a1 = dic.get(key) || ""
        //console.log(`${ key }, ${ expected_a1 } `)
        var actual = numberToCol(key)

        var actual_num = colToNumber(expected_a1)

        if (actual.localeCompare(expected_a1) != 0) {

            console.error(`key = ${key} == expected=${expected_a1} actual = ${actual} `)

        }
        if (actual_num != key) {
            console.error(`expected = ${expected_a1} key = ${key} == actual = ${actual_num} `)

        }


    }
}



0
    const getColumnName = (columnNumber) => {
        let columnName = "";
        const alphabets = "abcdefghijklmnopqrstuvwxyz".toUpperCase();
        while (columnNumber > 0) {
            const rem = columnNumber % 26;
            if (rem === 0) {
                columnName += "Z";
                columnNumber = columnNumber / 26 - 1;
            } else {
                columnName += alphabets[rem - 1];
                columnNumber = Math.floor(columnNumber / 26);
            }
        }
        return columnName.split("").reverse().join("");
    };

    console.log(getColumnName(27));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接