kangfz

解决 PHPExcel 长数字串显示为科学计数--寻找根本原因


网上这样的解决方案很多,甚至是抄来抄去地,但大多没有深入研究。最常见的答案是有三种方法: 
 1、设置单元格为文本类型: 
$objPHPExcel->getActiveSheet()->getStyle('E')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_TEXT); 
 2、指定填写的值的类型: 
$objPHPExcel->getActiveSheet()->setCellValueExplicit('D1',123456789033,PHPExcel_Cell_DataType::TYPE_STRING); 
 3、在值前面加空格: 
$objPHPExcel->getActiveSheet()->setCellValue('D1', ' ' . 123456789033); 
 
然后说第一种设置单元格格式那种不管用,也有说是因为excel把字符变成了数字,其实都不是。 
根本的原因是当excell的单元格数字类型设置为文本时,依然可以指定输入的值的类型为数值型;反过来也可以。所以当设置好单元格的数字类型为文本之后,如果使用setCellValue这个方法,还是会有问题。从字面意思就是设置单元格的值,但其实打开PHPExcel里对这个方法的描述就发现,不是这么简单。此方法在Worksheet.php里 

 可以发现,它是用bindValue去实现的,然后在DefaultValueBinder.php里找到此方法,看看怎么回事 

 这个时候发现,在给单元格赋值时,指定的数据格式是从输入的值去获取的,那么当我们输入的是值是数字时,获取的类型到底是什么呢? 
通过测试(echo self::dataTypeForValue($value);),当填写的内容里面只有纯数字时dataTypeForValue返回的值为n,否则返回的值为s,它是调用的自己的dataTypeForValue方法得到的,如下: 

 各类型的定义从DataType.php中得到: 

 

  也就是说,虽然通过 
$currentSheet->getStyle('B')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_TEXT); 
这样的方法,把单元格变成了文本格式,但如果在赋值时,使用的是setCellValue,如果值为纯数字,那么程序会判断为是数值型的,从而实际最后执行的是: 
setValueExplicit(value,TYPE_NUMERIC);所以觉得不管用了。 
 
所以要想正确地输入纯数字当成文本,最好用setValueExplicit自己指定类型,而且此方法默认类型为字符串,在Cell.php中可以找到:    public function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING) 
 
此这里,我们应该多问一个问题,是不是设置单元格格式没有用了呢?其实是有用的。 
我们应该要把单元格本身的格式和输入的值的类型要区分开来,他们是两个东西。我们可以从excel本身上去体会一下: 
当单元格的格式设置为文本时,我们在里面输入字符或者纯数字,都会原样显示,按文本在处理;当单元格格式是默认的常规时,我们通过程序指定输入类型,把纯数字当成字符串写入了,但当我们手动再修改时,如果输入的是纯数字,又会被当成数值处理了。

评论