PHPExcel как решить проблему кодирования при чтении файла

Я работал над API Yii2, где мне нужно загрузить файл.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-8 а также Windows-1255 не единственная возможная кодировка для мух, которая может быть загружена, но другая кодировка, такая как UTF-16 или другие в зависимости от операционной системы пользователя. Есть ли лучший способ найти кодировку, кроме использования mb_check_encoding

Распространенная ошибка, возникающая в процессе чтения данных в файле:

iconv(): Detected an illegal character in input string

Как видите, вышеописанная ошибка возникает из-за невозможности определить соответствующую кодировку файла. Есть ли обходной путь?

2 ответа

Вы можете попытаться использовать 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);
}

Убедитесь, что сначала очистите выходной буфер на вашей странице:

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();
Другие вопросы по тегам