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

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


当前回答

看到了另一个VBA答案-这可以在excel-vba中用1行UDF完成:

Function GetColLetter(ByVal colID As Integer) As String
    If colID > Columns.Count Then
        Err.Raise 9, , "Column index out of bounds"
    Else
        GetColLetter = Split(Cells(1, colID).Address, "$")(1)
    End If
End Function

其他回答

我的解决方案基于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);
    }
}

微软Excel微型,快速和肮脏的公式。

Hi,

下面是一种从数字....获取Excel字符-列-头的方法

我为Excel单元格创建了一个公式。

(即我采取了不使用VBA编程的方法。)

这个公式查看一个有数字的单元格,然后告诉你这个列是什么——用字母表示。

如图所示:

I put 1,2,3 etc in the top row all the way out to column ABS. I pasted my formula in the second row all the way out to ABS. My formula looks at row 1 and converts the number to Excel's column header id. My formula works for all numbers out to 702 (zz). I did it in this manner to prove that the formula works so you can look at the output from the formula and look at the column header above and easily visually verify that the formula works. :-) =CONCATENATE(MID("_abcdefghijklmnopqrstuvwxyz",(IF(MOD(K1,26)>0,INT(K1/26)+1,(INT(K1/26)))),1),MID("abcdefghijklmnopqrstuvwxyz",IF(MOD(K1,26)=0,26,MOD(K1,26)),1))

下划线的存在是为了调试目的——让您知道有一个实际的空格,并且它正在正确地工作。

用上面的公式——不管你在K1里放什么——这个公式会告诉你列的标题是什么。

目前的公式只有2位数字(ZZ),但可以修改为添加第3个字母(ZZZ)。

到目前为止,所有的解决方案都包含迭代或递归,这让我感到惊讶。

这是我的解,在常数时间内运行(没有循环)。此解决方案适用于所有可能的Excel列,并检查输入是否可以转换为Excel列。可能的列在[A, XFD]或[1,16384]范围内。(这取决于你的Excel版本)

private static string Turn(uint col)
{
    if (col < 1 || col > 16384) //Excel columns are one-based (one = 'A')
        throw new ArgumentException("col must be >= 1 and <= 16384");

    if (col <= 26) //one character
        return ((char)(col + 'A' - 1)).ToString();

    else if (col <= 702) //two characters
    {
        char firstChar = (char)((int)((col - 1) / 26) + 'A' - 1);
        char secondChar = (char)(col % 26 + 'A' - 1);

        if (secondChar == '@') //Excel is one-based, but modulo operations are zero-based
            secondChar = 'Z'; //convert one-based to zero-based

        return string.Format("{0}{1}", firstChar, secondChar);
    }

    else //three characters
    {
        char firstChar = (char)((int)((col - 1) / 702) + 'A' - 1);
        char secondChar = (char)((col - 1) / 26 % 26 + 'A' - 1);
        char thirdChar = (char)(col % 26 + 'A' - 1);

        if (thirdChar == '@') //Excel is one-based, but modulo operations are zero-based
            thirdChar = 'Z'; //convert one-based to zero-based

        return string.Format("{0}{1}{2}", firstChar, secondChar, thirdChar);
    }
}

Objective-C实现:

-(NSString*)getColumnName:(int)n {
     NSString *name = @"";
     while (n>0) {
     n--;
     char c = (char)('A' + n%26);
     name = [NSString stringWithFormat:@"%c%@",c,name];
     n = n/26;
  }    
     return name;

}

迅速实现:

func getColumnName(n:Int)->String{
 var columnName = ""
 var index = n
 while index>0 {
     index--
     let char = Character(UnicodeScalar(65 + index%26))
     columnName = "\(char)\(columnName)"
     index = index / 26
 }
 return columnName

}

答案是基于:https://stackoverflow.com/a/4532562/2231118

int nCol = 127;
string sChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol >= 26)
{
    int nChar = nCol % 26;
    nCol = (nCol - nChar) / 26;
    // You could do some trick with using nChar as offset from 'A', but I am lazy to do it right now.
    sCol = sChars[nChar] + sCol;
}
sCol = sChars[nCol] + sCol;

更新:Peter的评论是正确的。这就是我在浏览器中编写代码的结果。:-)我的解决方案是不编译,它是最左边的字母,它是在反向顺序构建字符串-现在都固定了。

除了bug之外,该算法基本上是将一个数字从10进制转换为26进制。

更新2:Joel Coehoorn是对的-上面的代码将返回AB为27。如果它是一个以26为底的实数,AA就等于A, Z之后的下一个数字就是BA。

int nCol = 127;
string sChars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol > 26)
{
    int nChar = nCol % 26;
    if (nChar == 0)
        nChar = 26;
    nCol = (nCol - nChar) / 26;
    sCol = sChars[nChar] + sCol;
}
if (nCol != 0)
    sCol = sChars[nCol] + sCol;