Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

CakePHP: A view class for generating CSV

License

NotificationsYou must be signed in to change notification settings

FriendsOfCake/cakephp-csvview

Repository files navigation

CICoverage StatusTotal DownloadsLatest Stable VersionSoftware License

CsvView Plugin

Quickly enable CSV output of your model data.

This branch is for CakePHP5.x. For details seeversion map.

Background

I needed to quickly export CSVs of stuff in the database. Using a view class toiterate manually would be a chore to replicate for each export method, so Ifigured it would be much easier to do this with a custom view class,like JsonView or XmlView.

Installation

composer require friendsofcake/cakephp-csvview

Enable plugin

Load the plugin by running command

bin/cake plugin load CsvView

Usage

To export a flat array as a CSV, one could write the following code:

publicfunctionexport(){$data = [        ['a','b','c'],        [1,2,3],        ['you','and','me'],    ];$this->set(compact('data'));$this->viewBuilder()        ->setClassName('CsvView.Csv')        ->setOption('serialize','data');}

All variables that are to be included in the csv must be specified in theserialize view option, exactly howJsonView orXmlView work.

It is possible to have multiple variables in the csv output:

publicfunctionexport(){$data = [['a','b','c']];$data_two = [[1,2,3]];$data_three = [['you','and','me']];$serialize = ['data','data_two','data_three'];$this->set(compact('data','data_two','data_three'));$this->viewBuilder()        ->setClassName('CsvView.Csv')        ->setOption('serialize',$serialize);}

If you want headers or footers in your CSV output, you can specify either aheader orfooter view option. Both are completely optional:

publicfunctionexport(){$data = [        ['a','b','c'],        [1,2,3],        ['you','and','me'],    ];$header = ['Column 1','Column 2','Column 3'];$footer = ['Totals','400','$3000'];$this->set(compact('data'));$this->viewBuilder()        ->setClassName('CsvView.Csv')        ->setOptions(['serialize' =>'data','header' =>$header,'footer' =>$footer,        ]);}

You can also specify the delimiter, end of line, newline, escape characters andbyte order mark (BOM) sequence usingdelimiter,eol,newline,enclosureandbom respectively:

publicfunctionexport(){$data = [        ['a','b','c'],        [1,2,3],        ['you','and','me'],    ];$this->set(compact('data'));$this->viewBuilder()        ->setClassName('CsvView.Csv')        ->setOptions(['serialize' =>'data','delimiter' =>chr(9),'enclosure' =>'"','newline' =>'\r\n','eol' =>'~','bom' =>true,        ]);}

The defaults for these options are:

  • delimiter:,
  • enclosure:"
  • newline:\n
  • eol:\n
  • bom: false
  • setSeparator: false

Theeol option is the one used to generate newlines in the output.newline, however, is the character that should replace the newline charactersin the actual data. It is recommended to use the string representation of thenewline character to avoid rendering invalid output.

Some reader software incorrectly renders UTF-8 encoded files which do notcontain byte order mark (BOM) byte sequence. Thebom option is the one usedto add byte order mark (BOM) byte sequence beginning of the generated CSV outputstream. SeeWikipedia article about byte order markfor more information.

ThesetSeparator option can be used to set the separator explicitly in thefirst line of the CSV. Some readers need this in order to display the CSV correctly.

If you have complex model data, you can use theextract view option tospecify the individualHash::extract()-compatible pathsor a callable for each record:

publicfunctionexport(){$posts =$this->Posts->find();$header = ['Post ID','Title','Created'];$extract = ['id',function (array$row) {return$row['title'];        },'created'    ];$this->set(compact('posts'));$this->viewBuilder()        ->setClassName('CsvView.Csv')        ->setOptions(['serialize' =>'posts','header' =>$header,'extract' =>$extract,        ]);}

If your model data contains some null values or missing keys, you can use thenull option, just like you'd usedelimiter,eol, andenclosure,to set how null values should be displayed in the CSV.

null defaults to''.

Automatic view class switching

You can use the controller's content negotiation feature to automatically havethe CsvView class switched in as follows.

Enablecsv extension parsing using$routes->addExtensions(['csv']) within requiredscope in your app'sroutes.php.

// PostsController.php// Add the CsvView class for content type negotiationpublicfunctioninitialize():void{parent::initialize();$this->addViewClasses(['csv' =>'CsvView.Csv']);}// Controller actionpublicfunctionindex(){$posts =$this->Posts->find();$this->set(compact('posts'));if ($this->request->is('csv')) {$serialize ='posts';$header =array('Post ID','Title','Created');$extract =array('id','title','created');$this->viewBuilder()->setOptions(compact('serialize','header','extract'));    }}

With the above controller you can now access/posts.csv or useAccept headertext/csv to get the data as csv and use/posts to get normal HTML page.

For really complex CSVs, you can also use your own view files. To do so, eitherleaveserialize unspecified or set it to null. The view files will be locatedin thecsv subdirectory of your current controller:

// View used will be in templates/Posts/csv/export.phppublicfunctionexport(){$posts =$this->Posts->find();$this->set(compact('posts'));$this->viewBuilder()        ->setClassName('CsvView.Csv')        ->setOption('serialize',null);}

Setting a different encoding to the file

If you need to have a different encoding in you csv file you have to set theencoding of your data you are passing to the view and also set the encoding youwant for the csv file. This can be done by usingdataEncoding andcsvEncoding:

The defaults are:

  • dataEncoding:UTF-8
  • csvEncoding:UTF-8

** Only if those two variable are different your data will be converted to another encoding.

CsvView uses theiconv extension by default to encode your data. You can changethe php extension used to encode your data by setting thetranscodingExtension option:

$this->viewBuilder()->setOption('transcodingExtension','mbstring');

The currently supported encoding extensions are as follows:

  • iconv
  • mbstring

Setting the downloaded file name

By default, the downloaded file will be named after the last segment of the URLused to generate it. Eg:example.com/my-controller/my-action would downloadmy-action.csv, whileexample.com/my-controller/my-action/first-param woulddownloadfirst-param.csv.

In IE you are required to set the filename, otherwise it will download as a text file.

To set a custom file name, use theResponse::withDownload() method. The followingsnippet can be used to change the downloaded file fromexport.csv tomy-file.csv:

publicfunctionexport(){$data = [        ['a','b','c'],        [1,2,3],        ['you','and','me'],    ];$this->setResponse($this->getResponse()->withDownload('my-file.csv'));$this->set(compact('data'));$this->viewBuilder()        ->setClassName('CsvView.Csv')        ->setOption('serialize','data');}

Using a specific View Builder

In some cases, it is better not to use the current controller's View Builder$this->viewBuilder() as any call to$this->render() will compromise anysubsequent rendering.

For example, in the course of your current controller's action, if you need torender some data as CSV in order to simply save it into a file on the server.

Do not forget to add to your controller:

useCake\View\ViewBuilder;

So you can create a specific View Builder:

// Your data array$data = [];// Options$serialize ='data';$delimiter =',';$enclosure ='"';$newline ='\r\n';// Create the builder$builder =newViewBuilder();$builder    ->setLayout(false)    ->setClassName('CsvView.Csv')    ->setOptions(compact('serialize','delimiter','enclosure','newline'));// Then the view$view =$builder->build($data);$view->set(compact('data'));// And Save the filefile_put_contents('/full/path/to/file.csv',$view->render());

About

CakePHP: A view class for generating CSV

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors28

Languages


[8]ページ先頭

©2009-2025 Movatter.jp