I'm working on a script that generate some Excel documents and I need to convert a number into its column name equivalent. For example:
1 => A 2 => B 27 => AA 28 => AB 14558 => UMX
I have already written an algorithm to do so, but I'd like to know whether are simpler or faster ways to do it:
function numberToColumnName($number){ $abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $abc_len = strlen($abc); $result_len = 1; // how much characters the column's name will have $pow = 0; while( ( $pow += pow($abc_len, $result_len) ) < $number ){ $result_len++; } $result = ""; $next = false; // add each character to the result... for($i = 1; $i<=$result_len; $i++){ $index = ($number % $abc_len) - 1; // calculate the module // sometimes the index should be decreased by 1 if( $next || $next = false ){ $index--; } // this is the point that will be calculated in the next iteration $number = floor($number / strlen($abc)); // if the index is negative, convert it to positive if( $next = ($index < 0) ) { $index = $abc_len + $index; } $result = $abc[$index].$result; // concatenate the letter } return $result; }
Do you know a better way to do it? Maybe something to keep it simpler? or a performance improvement?
ircmaxell's implementation works pretty fine. But, I'm going to add this nice short one:
function num2alpha($n) { for($r = ""; $n >= 0; $n = intval($n / 26) - 1) $r = chr($n%26 + 0x41) . $r; return $r; }
In a row of Excel, e.g. cell A1, enter the column number =column() In the row below, enter =Address(1,A1) This will provide the result $A$1.
Just click the column header. The status bar, in the lower-right corner of your Excel window, will tell you the row count. Do the same thing to count columns, but this time click the row selector at the left end of the row. If you select an entire row or column, Excel counts just the cells that contain data.
Here's a nice simple recursive function (Based on zero indexed numbers, meaning 0 == A, 1 == B, etc)...
function getNameFromNumber($num) { $numeric = $num % 26; $letter = chr(65 + $numeric); $num2 = intval($num / 26); if ($num2 > 0) { return getNameFromNumber($num2 - 1) . $letter; } else { return $letter; } }
And if you want it one indexed (1 == A, etc):
function getNameFromNumber($num) { $numeric = ($num - 1) % 26; $letter = chr(65 + $numeric); $num2 = intval(($num - 1) / 26); if ($num2 > 0) { return getNameFromNumber($num2) . $letter; } else { return $letter; } }
Tested with numbers from 0 to 10000...
Using PhpSpreadsheet (PHPExcel is deprecated)
// result = 'A' \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex(1);
Note index 0 results in 'Z'
https://phpspreadsheet.readthedocs.io/en/develop/
The correct answer (if you use PHPExcel Library) is:
// result = 'A' $columnLetter = PHPExcel_Cell::stringFromColumnIndex(0); // ZERO-based!
and backwards:
// result = 1 $colIndex = PHPExcel_Cell::columnIndexFromString('A');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With