2014-11-14 35 views
0

由於MS Excel不能夠recognize CSV files as of utf-8 encoding我試圖手動創建這樣一個文件,並在此前添加了BOM前綴。但在我的情況下,我需要發送給用戶/瀏覽器打開,而不是將其保存在磁盤上。 012-訣竅是,對於少量的數據〜1-10它效果很好,但是當出現更多的記錄時,它無法在瀏覽器(Google Chrome,FF)中輸出,而是將結果打印爲HTML。你可能會嘗試與它在GET請求不同count參數玩:http://tarex.ru/index.php?r=user/pricelist&file=1&count=100將hude csv文件直接發送到瀏覽器輸出不起作用

代碼

 $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 turutosiya的建議後做了。

$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)); 
+0

頭()不用於設置在$出resourcehandler報頭信息的方法......我覺得在工作時是隻在Chrome,FF是()方法,輸出總是在屏幕上(html) – RichardBernards 2014-11-14 15:24:30

+0

guestimating當我去除它。它不會改變您發送的數據的任何內容,也不會改變它在客戶端上的保存/查看方式。通過刪除內容類型頭,你只是讓服務器使用其默認的MIME類型,這將是文本/ HTML。 – 2014-11-14 15:27:21

+0

header()業務應用**只有**到http部分的文件類型 – 2014-11-14 15:29:51

回答

0

我建議使用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 
)); 
+0

感謝您提供的方法。但是它會返回一個空文件:在文檔中:*要使用此方法,應該由Web服務器啓用X-SENDFILE選項/模塊,併發送適當的xHeader ...如果Web服務器禁用此選項,當這種方法被稱爲下載配置對話框將打開,但下載的文件將有0字節。*這一定是這裏的情況。如果服務器是共享服務器,如何啓用此選項? – 2014-11-17 15:01:12

+0

@IgorSavinkin你會問服務器管理員啓用x-sendfile嗎? – turutosiya 2014-11-18 00:28:23

+0

我只用'Yii :: app() - > request-> sendfile'來完成它。 – 2014-11-18 09:54:19

0

對於原始代碼,問題可能是您最後有header聲明。如果輸出量很大,那麼該Web服務器會將第一個數據塊刷新到瀏覽器,那麼該瀏覽器會收到沒有這些標頭的數據。從那一刻起,發送標題爲時已晚。

因此,首先產生的標題:

$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); 
相關問題