phpexcel将长数字读为布尔值

时间:2015-06-02 19:53:31

标签: php symfony phpexcel

我正在使用Symfony2.3.​​4,PHP5.6.3和PHPExcel 1.8.0。

当我尝试读取excel文件时,几乎所有单元格都可以正常工作。

如果单元格包含非常大的数字,当我读取它并在html视图中显示该值时,它会输出 false

我尝试使用自定义值绑定器,例如Mark Ba​​ker指示here,但我无法使其工作,它只是从一开始就作为布尔值。

重要:

我试图加载html的excels是从其他网站下载(生成)的,我注意到当你尝试用Microsoft Excel打开它时,它会首先提示你一个警告窗口告诉用户文件扩展名和文件格式不匹配,但无论如何你选择打开它,它打开正常。

我认为这是导致问题的原因,我几乎可以肯定(我无法联系那些实施其他网站下载功能的人)他们做了类似的事情:

$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, $ext == 'xlsx' ?
 'Excel5' : 'Excel2007');

当他们应该做这样的事情时:

$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, $ext == 'xls' ?
 'Excel5' : 'Excel2007');

按照PHPExcel文档中的说明进行EXTENSION和FORMAT匹配。

如果您需要任何具体说明,请询问。

我的代码将文件加载到html:

public function uploadAction() {
    $request = $this->getRequest();
    $form = $this->createFormBuilder()
        ->add('file', 'file')
        ->getForm();
if ($request->getMethod() == 'POST'){

    $form->submit($request);

    $file = $form['file'];
    $file->getData()->move(
                'uploads', $form['file']->getData()->getClientOriginalName());

    $ext = pathinfo($file->getData()->getClientOriginalName(), PATHINFO_EXTENSION);
    $name = pathinfo($file->getData()->getClientOriginalName(), PATHINFO_BASENAME);

    //$objReader = \PHPExcel_IOFactory::createReader('xlsx' == $ext ? 'Excel2007' : 'Excel5');
    $objReader = \PHPExcel_IOFactory::createReaderForFile('uploads/' . $name);
    $objReader->setReadDataOnly(true);

    $objPHPExcel = $objReader->load('uploads/' . $name);
    $activeSheet = $objPHPExcel->getActiveSheet();

    $rowIter = $activeSheet->getRowIterator();
    foreach ($rowIter as $key => $row) {
        $columns = array();
        $cellIterator = $row->getCellIterator();
        $cellIterator->setIterateOnlyExistingCells(false);
        foreach ($cellIterator as $cell)
            $columns[] = $cell->getCalculatedValue();
    }
}
}

注意:我真的不知道:

之间的区别
$objReader = \PHPExcel_IOFactory::createReader('xlsx' == $ext ? 'Excel2007' : 'Excel5');

$objReader = \PHPExcel_IOFactory::createReaderForFile('uploads/' . $name);

我知道我不能使用第一个因为我上面描述的关于文件生成不良的问题等等。如果我尝试使用它,浏览器会:

The filename uploads/<name>.xls is not recognised as an OLE file.

任何人都可以指出我的解决方法,因为现在我已经陷入困境,我应该让它以某种方式工作。也许这些文件没有任何问题,而且我做错了。请帮助,这也导致我的日期问题,但一次只有一步。

修改

这只是 OLERead.php 中的读取功能。

我正在浏览它并且var_dump-ing我可以得到所有的东西。

正如您所看到的,下面的代码中有两个var_dump,那些输出:

string '<div>    
    ' (length=8)

string '��ࡱ�' (length=8)

当我尝试使用手动创建的常规 .xls 文件时,这种情况不会发生:

string '��ࡱ�' (length=8)

string '��ࡱ�' (length=8)

我猜想如果它有所帮助,你可以比我更好地使用它。再次感谢。

public function read($sFileName) {
        // Check if file exists and is readable
        if (!is_readable($sFileName)) {
            throw new PHPExcel_Reader_Exception("Could not open " . $sFileName . " for reading! File does not exist, or it is not readable.");
        }

        // Get the file identifier
        // Don't bother reading the whole file until we know it's a valid OLE file


        $this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8);

         ////VAR_DUMPSSSSSSSSSSSS
         var_dump($this->data);
         var_dump(self::IDENTIFIER_OLE);
         die();
        // Check OLE identifier
        if ($this->data != self::IDENTIFIER_OLE) {
            throw new PHPExcel_Reader_Exception('The filename ' . $sFileName . ' is not recognised as an OLE file');
        }

        // Get the file data
        $this->data = file_get_contents($sFileName);

        // Total number of sectors used for the SAT
        $this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);

        // SecID of the first sector of the directory stream
        $this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS);

        // SecID of the first sector of the SSAT (or -2 if not extant)
        $this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS);

        // SecID of the first sector of the MSAT (or -2 if no additional sectors are used)
        $this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS);

        // Total number of sectors used by MSAT
        $this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS);

        $bigBlockDepotBlocks = array();
        $pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS;

        $bbdBlocks = $this->numBigBlockDepotBlocks;

        if ($this->numExtensionBlocks != 0) {
            $bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS) / 4;
        }

        for ($i = 0; $i < $bbdBlocks; ++$i) {
            $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
            $pos += 4;
        }

        for ($j = 0; $j < $this->numExtensionBlocks; ++$j) {
            $pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE;
            $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1);

            for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) {
                $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);
                $pos += 4;
            }

            $bbdBlocks += $blocksToRead;
            if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
                $this->extensionBlock = self::_GetInt4d($this->data, $pos);
            }
        }

        $pos = 0;
        $this->bigBlockChain = '';
        $bbs = self::BIG_BLOCK_SIZE / 4;
        for ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) {
            $pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE;

            $this->bigBlockChain .= substr($this->data, $pos, 4 * $bbs);
            $pos += 4 * $bbs;
        }

        $pos = 0;
        $sbdBlock = $this->sbdStartBlock;
        $this->smallBlockChain = '';
        while ($sbdBlock != -2) {
            $pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE;

            $this->smallBlockChain .= substr($this->data, $pos, 4 * $bbs);
            $pos += 4 * $bbs;

            $sbdBlock = self::_GetInt4d($this->bigBlockChain, $sbdBlock * 4);
        }

        // read the directory stream
        $block = $this->rootStartBlock;
        $this->entry = $this->_readData($block);

        $this->_readPropertySets();
    }

1 个答案:

答案 0 :(得分:0)

之间的区别
$objReader = \PHPExcel_IOFactory::createReader('xlsx' == $ext ? 'Excel2007' : 'Excel5');

$objReader = \PHPExcel_IOFactory::createReaderForFile('uploads/' . $name);

第一个是 信任 ,扩展名对于文件的实际格式是正确的,扩展名为.xlsx的文件确实是{ {1}}文件或OfficeOpenXML-format的扩展名实际上是.xls文件,然后告诉PHPExcel使用适当的阅读器。

这通常不是问题,除非它(例如)只是在带有BIFF-format.xls扩展名的文件中的HTML标记....然后你#&# 39;为文件的实际格式选择错误的Reader;这就是MS Excel本身告诉你的信息&#34; FILE EXTENSION和FILE FORMAT不匹配&#34;

第二种方法是使用PHPExcel的.xlsx方法计算文件 实际 的格式(不论它声称是基于什么)在虚假扩展名上),然后为该格式选择合适的Reader。

修改

确定您的大数字究竟有多大,但我会查看HTML阅读器,看看我是否可以确定为什么它应该给出布尔值identify()而不是实际的数值< / p>