我正在开发一个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-8
和Windows-1255
不是可能上传的苍蝇的唯一可能编码,而是其他编码,如UTF-16
或其他编码,具体取决于用户的操作系统。除了使用mb_check_encoding
在读取文件中的数据过程中发生的常见错误是:
iconv(): Detected an illegal character in input string
正如您所看到的,由于无法检测到文件的相应编码而发生上述错误。有没有解决方法?
答案 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();