A few days ago, i worked for CGridView exporting functional for my client. He asked me to create a simple exporting to a CSV file a CGridView search results.
That's very easy. Let's start...
I just created an Export Button above my grid.
echo CHtml::button('Export', array('id'=>'export-button','class'=>'span-3 button'));
This javascript code does: 1. bind an .export() execution by clicking an export button, defined above. 2. extinds an yiiGridView javascript class for function update.
$('#export-button').on('click',function() { $.fn.yiiGridView.export(); }); $.fn.yiiGridView.export = function() { $.fn.yiiGridView.update('dates-grid',{ success: function() { $('#dates-grid').removeClass('grid-view-loading'); window.location = '". $this->createUrl('exportFile') . "'; }, data: $('.search-form form').serialize() + '&export=true' }); }
Because CGridView always uses for update the same action as initial render CGridView we need to use this action for our purpose in a next way: Add next peace of code at the top of action your CGridView render.
if(Yii::app()->request->getParam('export')) { $this->actionExport(); Yii::app()->end(); }
It will run our actionExport if GET['export'] set.
public function actionExport() { $fp = fopen('php://temp', 'w'); /* * Write a header of csv file */ $headers = array( 'd_date', 'client.clientFirstName', 'client.clientLastName', 'd_time', ); $row = array(); foreach($headers as $header) { $row[] = MODEL::model()->getAttributeLabel($header); } fputcsv($fp,$row); /* * Init dataProvider for first page */ $model=new MODEL('search'); $model->unsetAttributes(); // clear any default values if(isset($_GET['MODEL'])) { $model->attributes=$_GET['MODEL']; } $dp = $model->search(); /* * Get models, write to a file, then change page and re-init DataProvider * with next page and repeat writing again */ while($models = $dp->getData()) { foreach($models as $model) { $row = array(); foreach($headers as $head) { $row[] = CHtml::value($model,$head); } fputcsv($fp,$row); } unset($model,$dp,$pg); $model=new MODEL('search'); $model->unsetAttributes(); // clear any default values if(isset($_GET['MODEL'])) $model->attributes=$_GET['MODEL']; $dp = $model->search(); $nextPage = $dp->getPagination()->getCurrentPage()+1; $dp->getPagination()->setCurrentPage($nextPage); } /* * save csv content to a Session */ rewind($fp); Yii::app()->user->setState('export',stream_get_contents($fp)); fclose($fp); }
public function actionGetExportFile() { Yii::app()->request->sendFile('export.csv',Yii::app()->user->getState('export')); Yii::app()->user->clearState('export'); }
Total 8 comments
I just got confused because we are not adding it ass a Yii Add Script function.
So this JS I just need to put in the javascript part of the main layout in my case.
@CTala: The JavaScript goes in the same file as the first code snippet (the one that makes the Export button). That is, in the same view file that contains the CGridView. It makes the button work.
Where did you add that javaScript ? +
By the way, thanks for the how to !
Instead of dropping an extension somewhere, this article shows me how the mechanisms work, so I can adapt it to my needs easily.
Just a small thing: the last action should be named 'actionExportFile' instead of 'actionGetExportFile' or else the javascript at the top should be adapted.
When I tried this code I kept getting an infinite loop accessing the data. Then I realized that the entire outer loop that handles pagination isn't needed. Instead, just set the pagination of the CActiveDataProvider returned by the model search method to false.
In other words, insert this after the first call of the search function:
Then eliminate the outer loop and all the pagination stuff. So instead of this block of code:
We're just left with this:
is about how to make csv exporting. it's for understanding how to create it fast. When someone will need alot of exporting, he will write a class for this.
Well, I just use my extension EExcelView to do this :)
i've built something similar in one of my yii-apps. it gets a bit annoying if you need lots of csv exports because there is lots of code to write and maintain which does almost exactly what the corresponding cgridview does only using another data export format. maybe an extension to cgridview would be the better way.
Leave a comment
Please login to leave your comment.