如何在c#中将数值转换为Excel列名,而不使用直接从Excel中获取值的自动化。

Excel 2007的范围可能是1到16384,这是它支持的列数。结果值应以excel列名的形式出现,例如A、AA、AAA等。


当前回答

(我知道这个问题与c#有关,但是,如果读者需要用Java做同样的事情,那么下面的内容可能会有用)

事实证明,使用Jakarta POI中的“CellReference”类可以很容易地做到这一点。此外,转换可以以两种方式进行。

// Convert row and column numbers (0-based) to an Excel cell reference
CellReference numbers = new CellReference(3, 28);
System.out.println(numbers.formatAsString());

// Convert an Excel cell reference back into digits
CellReference reference = new CellReference("AC4");
System.out.println(reference.getRow() + ", " + reference.getCol());

其他回答

这是一个javascript版本,根据格雷厄姆的代码

function (columnNumber) {
    var dividend = columnNumber;
    var columnName = "";
    var modulo;

    while (dividend > 0) {
        modulo = (dividend - 1) % 26;
        columnName = String.fromCharCode(65 + modulo) + columnName;
        dividend = parseInt((dividend - modulo) / 26);
    }

    return columnName;
};

下面是我在Python中如何做的。算法说明如下:

alph = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')
def labelrec(n, res):
    if n<26:
        return alph[n]+res
    else:
        rem = n%26
        res = alph[rem]+res
        n = n/26-1
        return labelrec(n, res)

函数labelrec可以用数字和一个空字符串来调用,比如:

print labelrec(16383, '')

以下是它有效的原因: 如果十进制数字的书写方式与Excel表格列相同,那么数字0-9将被正常书写,但10将变成“00”,然后20将变成“10”,以此类推。映射几个数字:

0-0

9-9

10-00

20-10

100-90

110-000

1110-0000

所以,模式很清楚。从单位的位置开始,如果一个数字小于10,它的表示与数字本身相同,否则您需要通过减去1来调整剩余的数字并递归。当数字小于10时可以停止。

同样的逻辑适用于上述解决方案中以26为基数的数字。

注:如果你想让数字从1开始,在输入数字减去1后调用相同的函数。

T-sql (sql server 18)

第一页的解决方案副本

CREATE FUNCTION dbo.getExcelColumnNameByOrdinal(@RowNum int)  
RETURNS varchar(5)   
AS   
BEGIN  
    DECLARE @dividend int = @RowNum;
    DECLARE @columnName varchar(max) = '';
    DECLARE @modulo int;

    WHILE (@dividend > 0)
    BEGIN  
        SELECT @modulo = ((@dividend - 1) % 26);
        SELECT @columnName = CHAR((65 + @modulo)) + @columnName;
        SELECT @dividend = CAST(((@dividend - @modulo) / 26) as int);
    END
    RETURN 
       @columnName;

END;

我的解决方案基于Graham, Herman Kan和desseim的回答,使用StringBuilder:

internal class Program
{
    #region get_excel_col_name
    /// <summary>
    /// Returns the name of the column by its number
    /// </summary>
    /// <param name="col_num">Column number</param>
    /// <returns>Column name</returns>
    /// <remarks>Numbering columns from zero</remarks>
    private static string get_excel_col_name(int col_num)
    {
        StringBuilder sb = new StringBuilder(2);
        if (col_num >= 0)
        {
            do
            {
                sb.Insert(0, (char)(col_num % 26 + 65));
                col_num /= 26;
            }
            while (--col_num >= 0);
        }
        return sb.ToString();
    }
    #endregion

    private static void Main(string[] args)
    {
        Console.WriteLine(get_excel_col_name(34));//outputs AI
        Console.ReadKey(true);
    }
}

我想在我使用的静态类中加入,用于在col index和col Label之间进行交互。我对ColumnLabel方法使用了修改后的可接受答案

public static class Extensions
{
    public static string ColumnLabel(this int col)
    {
        var dividend = col;
        var columnLabel = string.Empty;
        int modulo;

        while (dividend > 0)
        {
            modulo = (dividend - 1) % 26;
            columnLabel = Convert.ToChar(65 + modulo).ToString() + columnLabel;
            dividend = (int)((dividend - modulo) / 26);
        } 

        return columnLabel;
    }
    public static int ColumnIndex(this string colLabel)
    {
        // "AD" (1 * 26^1) + (4 * 26^0) ...
        var colIndex = 0;
        for(int ind = 0, pow = colLabel.Count()-1; ind < colLabel.Count(); ++ind, --pow)
        {
            var cVal = Convert.ToInt32(colLabel[ind]) - 64; //col A is index 1
            colIndex += cVal * ((int)Math.Pow(26, pow));
        }
        return colIndex;
    }
}

用这个…

30.ColumnLabel(); // "AD"
"AD".ColumnIndex(); // 30