Так как MS Excel не умеет распознавать файлы CSV в кодировке utf-8 я попытался вручную создать такой файл, добавив префикс BOM. Но в моем случае мне нужно отправить его для открытия пользователю / браузеру, а не сохранить его на диске.
Хитрость заключается в том, что при небольшом количестве данных ~ 1-10 он работает хорошо, но при отсутствии большого количества записей он не может быть выведен в браузер (Google Chrome, FF), а печатает результат в виде HTML. Вы можете попробовать поиграть с ним по-разному count
параметр в запросе GET: http://tarex.ru/index.php?r=user/pricelist&Файл = 1&кол = 100
$limit = $_GET['count'] ? $_GET['count'] : 10;
$filename= 'test.csv';
$out = fopen('php://output', 'w'); // open to out in browser
fwrite($out, "\xEF\xBB\xBF"); // prepend BOM
$counter=0;
foreach(Assortment::model()->findAll( 'measure_unit<>"" AND price>0' ) as $d)
{
$arr = array( $d->article2, $d->title, $d->oem, $d->make, $d->availability , $d->getPrice(Yii::app()->user->id), $d->getDiscountOpt(Yii::app()->user->id) );
fputcsv($out, $arr, ';'); //delimiter - ;
if ($counter++ > $limit) break;
}
header('Content-type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');
fclose($out);
Есть ли решение?
В конце концов я сделал это с Yii::app()->request->sendFile
после предложения турутоции.
$filename='test.csv';
$filepath = Yii::app()->basePath . '/../files/'. $filename;
$out = fopen($filepath, 'w');
// writing csv ...
fwrite($out, "\xEF\xBB\xBF"); // put BOM at the beginning of file
fputcsv($out, $arr, ';');
foreach(Assortment::model()->findAll() as $d)
{
$arr = array( $d->article2, $d->title, $d->oem, $d->make, $d->availability);
fputcsv($out, $arr, ';'); // separator - ;
}
fclose($out);
Yii::app()->request->sendFile($filename, @file_get_contents($filepath));
Я предлагаю использовать xSendFile () метод для загрузки большого файла.
$limit = $_GET['count'] ? $_GET['count'] : 10;
$filename = 'test.csv';
$filepath = '/path/to/xsendfile-enabled/dir/' . $filename;
$out = fopen($filepath, 'w');
//
// write csv ...
//
fclose($out);
Yii::app()->request->xSendFile(filepath, array(
'saveName' => $filename
));
С исходным кодом проблема, вероятно, заключалась в том, что у вас есть header
заявления в конце. Если затем выходные данные настолько велики, что веб-сервер сбрасывает первый блок данных в браузер, то этот браузер получает данные без этих заголовков. С этого момента уже слишком поздно отправлять заголовки.
Поэтому сначала сгенерируйте эти заголовки:
$limit = $_GET['count'] ? $_GET['count'] : 10;
$filename= 'test.csv';
$out = fopen('php://output', 'w'); // open to out in browser
header('Content-type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');
fwrite($out, "\xEF\xBB\xBF"); // prepend BOM
//
// rest of output generating code comes here
//
fclose($out);