simple CSV export

You are viewing revision #4 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.

« previous (#3)

Por: Christian Salazar

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