It might help to realize that the column name is essentially a base-26 number, using A as '0'. Then a div+mod loop while anything is left would only require building a 26 character alphabet. (for all I know, this could be how the XLS utils mentioned above handle it).
There are a couple of fencepost errors here. Fix coming shortly Ok, this is not quite a base-26 number. The least significant digit is treated slightly different than all other digits.
sub mlx_xls2col {
my $col = shift;
my $alphabet = shift || [ 'A' .. 'Z' ];
my $alphabet_size = scalar( @$alphabet );
my $result = '';
my $remainder = $col;
while ( $remainder ) {
my $letter = $remainder % $alphabet_size;
my $adj = length( $result ) ? -1 : 0; # Not quite a base-26
+ number
$result = $alphabet->[$letter + $adj] . $result;
$remainder = int( $remainder / $alphabet_size );
}
$result ||= $alphabet->[0];
$result;
}
print mlx_xls2col( 0 ), "\n";
print mlx_xls2col( 1 ), "\n";
print mlx_xls2col( 2 ), "\n";
print mlx_xls2col( 24 ), "\n";
print mlx_xls2col( 25 ), "\n";
print mlx_xls2col( 26 ), "\n";
print mlx_xls2col( 27 ), "\n";
print mlx_xls2col( 51 ), "\n";
print mlx_xls2col( 52 ), "\n";
print mlx_xls2col( 53 ), "\n";
__DATA__
A
B
C
Y
Z
AA
AB
AZ
BA
BB