php 类似于excel公式,php - 获取麻木的类似Excel的列名的算法

php - 获取麻木的类似Excel的列名的算法

我正在编写一个生成一些Excel文档的脚本,我需要将一个数字转换为其等效的列名。 例如:

1 => A

2 => B

27 => AA

28 => AB

14558 => UMX

我已经编写了一个算法来做这个,但我想知道是否更简单或更快的方法:

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;

}

你知道更好的方法吗? 也许是为了让它更简单? 还是性能提升?

编辑

ircmaxell的实现工作得很好。 但是,我要添加这个不错的短文:

function num2alpha($n)

{

for($r = ""; $n >= 0; $n = intval($n / 26) - 1)

$r = chr($n%26 + 0x41) . $r;

return $r;

}

8个解决方案

121 votes

这是一个很好的简单递归函数(基于零索引数,意味着0 == A,1 == B等)......

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;

}

}

如果你想要一个索引(1 == A,等):

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;

}

}

测试从0到10000的数字......

ircmaxell answered 2019-05-23T06:42:17Z

73 votes

使用PhpSpreadsheet(不推荐使用PHPExcel)

// result = 'A'

\PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex(1);

注意索引0导致'Z'

[https://phpspreadsheet.readthedocs.io/en/develop/]

正确答案(如果您使用PHPExcel Library)是:

// result = 'A'

$columnLetter = PHPExcel_Cell::stringFromColumnIndex(0); // ZERO-based!

和倒退:

// result = 1

$colIndex = PHPExcel_Cell::columnIndexFromString('A');

ksn135 answered 2019-05-23T06:43:08Z

12 votes

索引为1 - > A,2 - &gt; B等

function numToExcelAlpha($n) {

$r = 'A';

while ($n-- > 1) {

$r++;

}

return $r;

}

索引0 - >; A,1 - &gt; B等

function numToExcelAlpha($n) {

$r = 'A';

while ($n-- >= 1) {

$r++;

}

return $r;

}

利用PHP在处理字符变量而不是C的算术运算时遵循Perl的约定这一事实。 请注意,字符变量可以递增但不递减。

Mark Baker answered 2019-05-23T06:43:46Z

4 votes

这将转换(假设整数运算),但我同意其他海报; 只需使用base_convert

function numberToColumnName($number)

{

$abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

$len = strlen($abc);

$result = "";

while ($number > 0) {

$index = $number % $len;

$result = $abc[$index] . $result;

$number = floor($number / $len);

}

return $result;

}

Lucas answered 2019-05-23T06:44:10Z

2 votes

迟到的答案,但这就是我所做的(1 == A索引):

function num_to_letters($num, $uppercase = true) {

$letters = '';

while ($num > 0) {

$code = ($num % 26 == 0) ? 26 : $num % 26;

$letters .= chr($code + 64);

$num = ($num - $code) / 26;

}

return ($uppercase) ? strtoupper(strrev($letters)) : strrev($letters);

}

然后,如果你想转换另一种方式:

function letters_to_num($letters) {

$num = 0;

$arr = array_reverse(str_split($letters));

for ($i = 0; $i < count($arr); $i++) {

$num += (ord(strtolower($arr[$i])) - 96) * (pow(26,$i));

}

return $num;

}

Mike answered 2019-05-23T06:44:41Z

1 votes

function numberToColumnName($number){

$abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

$abc_len = strlen($abc);

$result = "";

$tmp = $number;

while($number > $abc_len) {

$remainder = $number % $abc_len;

$result = $abc[$remainder-1].$result;

$number = floor($number / $abc_len);

}

return $abc[$number-1].$result;

}

echo numberToColumnName(1)."\n";

echo numberToColumnName(25)."\n";

echo numberToColumnName(26)."\n";

echo numberToColumnName(27)."\n";

echo numberToColumnName(28)."\n";

echo numberToColumnName(14558)."\n";

?>

corsiKa answered 2019-05-23T06:44:58Z

1 votes

结合ircmaxell的递归答案,我得到了这个:

function getNameFromNumber($num, $index=0) {

$index = abs($index*1); //make sure index is a positive integer

$numeric = ($num - $index) % 26;

$letter = chr(65 + $numeric);

$num2 = intval(($num -$index) / 26);

if ($num2 > 0) {

return getNameFromNumber($num2 - 1 + $index) . $letter;

} else {

return $letter;

}

}

我使用默认索引为0,但它可以是任何正整数,用于在PHP中使用数组进行操作。

Charlie Affumigato answered 2019-05-23T06:45:29Z

0 votes

我从来没有在生产中使用它,因为它不可读,但为了好玩......只有ZZ。

$col = 55;

print (($n = (int)(($col - 1) / 26)) ? chr($n + 64) : '') . chr((($col - 1) % 26) + 65);

?>

simesy answered 2019-05-23T06:45:54Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值