Yii 1.1: simple CSV export

12 followers

Hello everyone, this simple component extract data to CSV. The main difference with others is the ability to format each column using Yii::app()->format functions in a very similar way as CGridView does.

  1. This component can output the result directly to your browser as a downloadble CSV, so use the input arguments to provide a filename, if not, the output will be returned as a string.

  2. The input argument to be converted to CSV must be any array of CModel objects, or any indexed array like $ar['key1'],$ar['key2']. You can pass an CActiveRecord array to this component too.

  3. example usage:

public function actionExport(){
  CsvExport::export(
    People::model()->findAll(), // a CActiveRecord array OR any CModel array
    array('idpeople'=>array('number'),'birthofdate'=>array('date')),
    true, // boolPrintRows
    'registers-upto--'.date('d-m-Y H-i').".csv"
   );
}
 
in a view put a link:
 
echo CHtml::link('Download CSV',array('site/export'));
  1. please note the input: People::model()->findAll(), this component is not limited to CActiveRecord, you could pass any array or any CModel objects array to it.

  2. for each column definition you can concatenate formats: array('idpeople'=>array('number','fixed8'),'birthofdate'=>array('date')), please note 'fixed8' this will invoke Yii::app()->format->formatFiexed8, this method must exist in your CFormatter implementation in order to work, you can extend CFormatter and implement the required methods.

  3. copy this class into your protected/components/CsvExport.php:

<?php
/**
    CsvExport
 
    helper class to output an CSV from a CActiveRecord array.
 
    example usage:
 
        CsvExport::export(
            People::model()->findAll(), // a CActiveRecord array OR any CModel array
            array(
                'idpeople'=>array('number'),      'number' and 'date' are strings used by CFormatter
                'birthofdate'=>array('date'),
            )
        ,true,'registros-hasta--'.date('d-m-Y H-i').".csv");
 
 
    Please refer to CFormatter about column definitions, this class will use CFormatter.
 
    @author    Christian Salazar <christiansalazarh@gmail.com> @bluyell @yiienespanol (twitter)
    @licence Protected under MIT Licence.
    @date 07 october 2012.
*/
class CsvExport {
    /*
        export a data set to CSV output.
 
        Please refer to CFormatter about column definitions, this class will use CFormatter.
 
        @rows    CModel array. (you can use a CActiveRecord array because it extends from CModel)
        @coldefs    example: 'colname'=>array('number') (See also CFormatter about this string)
        @boolPrintRows    boolean, true print col headers taken from coldefs array key
        @csvFileName if set (defaults null) it echoes the output to browser using binary transfer headers
        @separator if set (defaults to ';') specifies the separator for each CSV field
    */
    public static function export($rows, $coldefs, $boolPrintRows=true, $csvFileName=null, $separator=';')
    {
        $endLine = '\r\n';
        $returnVal = '';
 
        if($csvFileName != null)
        {
            header("Cache-Control: public");
            header("Content-Description: File Transfer");
            header("Content-Disposition: attachment; filename=".$csvFileName);
            header("Content-Type: application/octet-stream");
            header("Content-Transfer-Encoding: binary");
        }
 
        if($boolPrintRows == true){
            $names = '';
            foreach($coldefs as $col=>$config){
                $names .= $col.$separator;
            }
            $names = rtrim($names,$separator);
            if($csvFileName != null){
                echo $names.$endLine;
            }else
            $returnVal .= $names.$endLine;
        }
 
        foreach($rows as $row){
            $r = '';
            foreach($coldefs as $col=>$config){
 
                if(isset($row[$col])){
 
                    $val = $row[$col];
 
                    foreach($config as $conf)
                        if(!empty($conf))
                            $val = Yii::app()->format->format($val,$conf);
 
                    $r .= $val.$separator;
                }
            }
            $item = trim(rtrim($r,$separator)).$endLine;
            if($csvFileName != null){
                echo $item;
            }else{
                $returnVal .= $item;
            }
        }
        return $returnVal;
    }
}

twitter: @yiienespanol

Need advanced RBAC UI functionality in Yii ? use Cruge...https://bitbucket.org/christiansalazarh/cruge

Total 5 comments

#15378 report it
Patrice at 2013/11/03 11:05am
Thanks, works fine

As suggested by sinigami83, I changed :

$endLine = PHP_EOL;
Changed the output (for UTF-8 needs) :
$r .= '="'.utf8_decode($val).'"'.$separator;
Called from menu (CPortlet operation):
$this->menu=array(
    array('label' => '...', 'url' => array('export')),
);
Works fine. Thanks again.
#15105 report it
Shachish at 2013/10/08 03:18am
export csv have error

Export csv have this information.

id;download_date\r\n1;1970/01/01\r\n2;1970/01/01\r\n3;1970/01/01\r\n4;1970/01/01\r\n5;1970/01/01\r\n6;1970/01/01\r\n7;1970/01/01\r\n8;1970/01/01\r\n9;1970/01/01\r\n10;1970/01/01\r\n11;1970/01/01\r\n12;1970/01/01\r\n13;....

How to fix this ??

#12293 report it
sinigami83 at 2013/03/11 03:58pm
its cool! and working!

but it inserts char symbold '\n\r' instead of their binary codes values. Fixed the problem with $endLine = PHP_EOL;

#11415 report it
bluyell at 2013/01/12 11:44am
@razz, and what the error is ?

please copy and paste your error or code here

#11134 report it
razz at 2012/12/19 09:26am
not working

i tried this but not working///

Leave a comment

Please to leave your comment.

Write new article
  • Written by: bluyell
  • Category: How-tos
  • Yii Version: 1.1
  • Votes: +4 / -1
  • Viewed: 15,560 times
  • Created on: Oct 10, 2012
  • Last updated: Jan 22, 2013
  • Tags: csv, excel, export