PHPExcel如何在读取文件时解决编码问题

时间:2018-03-23 09:32:08

标签: php yii2 phpexcel phpexcelreader

我正在开发一个Yii2 API,我需要上传一个.csv或.xlsx文件并使用PHPExcel从中读取(现在已经弃用,但我坚持使用它,因为新的PhpSpreadsheet需要PHP 5.6或更新版本)返回数据数组。

这是API函数中使用的代码

public function actionUpload()
{
    $params = $_FILES['uploadFile'];
    if($params)
    {
        $data = array();
        $model = new UploadForm();
        $model->uploadFile = $_FILES['uploadFile'];
        $file =  UploadedFile::getInstanceByname('uploadFile');
        $inputFileName = $model->getpath($file,$data);
        //  Read your Excel workbook
        try
        {
            $inputFileType = \PHPExcel_IOFactory::identify($inputFileName['link']);
            $objReader = \PHPExcel_IOFactory::createReader($inputFileType);
            if($inputFileType == 'CSV')
            {   


                if (mb_check_encoding(file_get_contents($inputFileName['link']), 'UTF-8'))
                {
                    $objReader->setInputEncoding('UTF-8');
                }
                else
                {
                     $objReader->setInputEncoding('Windows-1255');
                     //$objReader->setInputEncoding('ISO-8859-8');
                }


            }
            $objPHPExcel = $objReader->load($inputFileName['link']);
        }
        catch(Exception $e)
        {
            die('Error loading file "'.pathinfo($inputFileName['link'],PATHINFO_BASENAME).'": '.$e->getMessage());
        }

        //  Get worksheet dimensions
        $sheet = $objPHPExcel->getSheet(0); 
        $highestRow = $sheet->getHighestRow(); 
        $highestColumn = $sheet->getHighestColumn();
        $fileData = array();
        //  Loop through each row of the worksheet in turn
        for ($row = 1; $row <= $highestRow; $row++)
        { 
            //  Read a row of data into an array
            $rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row,
                                            NULL,
                                            TRUE,
                                            FALSE);
            array_push($fileData,$rowData[0]);
            //  Insert row data array into your database of choice here
        }
        return $fileData;
    }

}

但是当我们上传包含希伯来语数据的excel文件时会出现编码问题。正如您所看到的,上面代码中的代码用于解决此问题

if (mb_check_encoding(file_get_contents($inputFileName['link']), 'UTF-8'))
{
    $objReader->setInputEncoding('UTF-8');
}
else
{
        $objReader->setInputEncoding('Windows-1255');

}

后来我发现UTF-8Windows-1255不是可能上传的苍蝇的唯一可能编码,而是其他编码,如UTF-16或其他编码,具体取决于用户的操作系统。除了使用mb_check_encoding

之外,还有更好的方法来查找编码

在读取文件中的数据过程中发生的常见错误是:

iconv(): Detected an illegal character in input string

正如您所看到的,由于无法检测到文件的相应编码而发生上述错误。有没有解决方法?

2 个答案:

答案 0 :(得分:1)

您可以尝试使用mb_detect_encoding来检测文件编码,但我发现结果会有所不同。您可能必须手动指定编码的自定义匹配顺序才能获得正确的结果。以下是有问题的if语句的示例替代:

if(inputFileType == 'CSV')
{
    // Try to detect file encoding
    $encoding = mb_detect_encoding(file_get_contents($inputFileName['link']),
                     // example of a manual detection order
                    'ASCII,UTF-8,ISO-8859-15');

    $objReader->setInputEncoding($encoding);
}

答案 1 :(得分:0)

确保首先清理页面中的输出缓冲区:

ob_end_clean();
header( "Content-type: application/vnd.ms-excel" );
header('Content-Disposition: attachment; filename="uploadFile.xls"');
header("Pragma: no-cache");
header("Expires: 0");
ob_end_clean();