今天接到个需求是对excel里的礼包数据导入到数据库
使用composer包
composer require phpoffice/phpspreadsheet:^1.18
由于对应的奖品众多,奖品数量不固定,对列的数量也不固定,想通过代码实现一劳永逸的办法。
该插件提供的获取最大的列的方法
$col = $sheet->getHighestColumn(); //返回列名 “AA”
到这里就无法遍历所有列了
因为ord('AA') = 65, 只取了第一个字母。
为解决这个问题,需要按照excel的格式将类似AAB, CZ等列转成数字进行遍历,获取单元格时再转成列名。实现方法如下:
列名和列数字相互转换
// 通过列名推导列排在第几个数字
function colToNum($col)
{
$initAsciiNum = 64; // 第一个字母A的ASCII值
$letterNum = 26; // 字母个数
$num = 0;
$len = strlen($col);
for ($i = 0; $i < $len; $i++) {
$c = $col[$len - $i - 1];
$num += pow($letterNum, $i) * (ord($c) - $initAsciiNum);
}
return $num;
}
// 通过数字反推列名
function numToCol($num)
{
$n = $num;
$str = '';
$letterNum = 26; // excel一共使用26个字母来组合
$initAsciiNum = 64; // 第一个字母A的ASCII值
while (true) {
if ($n > 0) {
$y = $n % $letterNum; // 计算余数
if (!$y) {
$n--;
$y = $letterNum;
}
$str = chr($y + $initAsciiNum) . $str;
$n = intval($n / $letterNum);
if ($n === 1 && $y === 0) {
break;
}
} else {
break;
}
}
return $str;
}
对以上的代码进行测试
wps的excel中最大的列名是XFD,转换成数字是16384。说明excel的表格最大支持16384个列,足以满足大多数业务使用。