friendsofcake/cakephp-csvview
Composer 安装命令:
composer require friendsofcake/cakephp-csvview
包简介
A CSV View class for CakePHP
README 文档
README
CsvView Plugin
Quickly enable CSV output of your model data.
This branch is for CakePHP 5.x. For details see version map.
Background
I needed to quickly export CSVs of stuff in the database. Using a view class to iterate manually would be a chore to replicate for each export method, so I figured 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:
public function export() { $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 the
serialize view option, exactly how JsonView or XmlView work.
It is possible to have multiple variables in the csv output:
public function export() { $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 a
header or footer view option. Both are completely optional:
public function export() { $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 and
byte order mark (BOM) sequence using delimiter, eol, newline, enclosure
and bom respectively:
public function export() { $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:\neol:\nbom: falsesetSeparator: false
The eol option is the one used to generate newlines in the output.
newline, however, is the character that should replace the newline characters
in the actual data. It is recommended to use the string representation of the
newline character to avoid rendering invalid output.
Some reader software incorrectly renders UTF-8 encoded files which do not
contain byte order mark (BOM) byte sequence. The bom option is the one used
to add byte order mark (BOM) byte sequence beginning of the generated CSV output
stream. See Wikipedia article about byte order mark
for more information.
The setSeparator option can be used to set the separator explicitly in the
first line of the CSV. Some readers need this in order to display the CSV correctly.
If you have complex model data, you can use the extract view option to
specify the individual Hash::extract()-compatible paths
or a callable for each record:
public function export() { $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 the
null option, just like you'd use delimiter, eol, and enclosure,
to set how null values should be displayed in the CSV.
null defaults to ''.
Extract paths now consistently resolve through Hash::get(), so missing keys
become null. If an extract path resolves to an array or object that cannot be
stringified, use a callable extractor to flatten it before rendering.
Automatic view class switching
You can use the controller's content negotiation feature to automatically have the CsvView class switched in as follows.
Enable csv extension parsing using $routes->addExtensions(['csv']) within required
scope in your app's routes.php.
// PostsController.php // Add the CsvView class for content type negotiation public function initialize(): void { parent::initialize(); $this->addViewClasses(['csv' => 'CsvView.Csv']); } // Controller action public function index() { $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 use Accept header
text/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, either
leave serialize unspecified or set it to null. The view files will be located
in the csv subdirectory of your current controller:
// View used will be in templates/Posts/csv/export.php public function export() { $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 the
encoding of your data you are passing to the view and also set the encoding you
want for the csv file. This can be done by using dataEncoding and csvEncoding:
The defaults are:
dataEncoding:UTF-8csvEncoding:UTF-8
** Only if those two variable are different your data will be converted to another encoding.
CsvView uses the iconv extension by default to encode your data. You can change
the php extension used to encode your data by setting the transcodingExtension option:
$this->viewBuilder()->setOption('transcodingExtension', 'mbstring');
The currently supported encoding extensions are as follows:
iconvmbstring
Excel-friendly UTF-8 export
Microsoft Excel on Windows does not recognise a UTF-8 CSV unless it has a byte-order mark, CRLF line endings, and an explicit UTF-8 declaration. Setting all three options individually each time is repetitive and easy to get wrong.
The excel shorthand sets the right defaults in one go:
$this->viewBuilder() ->setClassName('CsvView.Csv') ->setOptions([ 'serialize' => 'data', 'excel' => true, ]);
excel => true is equivalent to:
'bom' => true, 'eol' => "\r\n", 'csvEncoding' => 'UTF-8',
The shorthand always wins for the three keys it controls; if you need a
different combination (e.g. UTF-16, no BOM) do not enable excel and set the
individual keys yourself instead. Other CSV options (delimiter, enclosure,
setSeparator, header, extract, etc.) are independent and behave normally.
Setting the downloaded file name
By default, the downloaded file will be named after the last segment of the URL
used to generate it. Eg: example.com/my-controller/my-action would download
my-action.csv, while example.com/my-controller/my-action/first-param would
download first-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 the Response::withDownload() method. The following
snippet can be used to change the downloaded file from export.csv to my-file.csv:
public function export() { $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 any
subsequent rendering.
For example, in the course of your current controller's action, if you need to render some data as CSV in order to simply save it into a file on the server.
Do not forget to add to your controller:
use Cake\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 = new ViewBuilder(); $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 file file_put_contents('/full/path/to/file.csv', $view->render());
friendsofcake/cakephp-csvview 适用场景与选型建议
friendsofcake/cakephp-csvview 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2.62M 次下载、GitHub Stars 达 176, 最近一次更新时间为 2014 年 09 月 19 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「csv」 「view」 「cakephp」 「export」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 friendsofcake/cakephp-csvview 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 friendsofcake/cakephp-csvview 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 friendsofcake/cakephp-csvview 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Shoot aims to make providing data to your templates more manageable
CakePHP 4.x AdminLTE Theme.
Illuminate View for Morningmedley.
Email Toolkit Plugin for CakePHP
Blade template for Kirby
laravel facade to read/write csv file
统计信息
- 总下载量: 2.62M
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 178
- 点击次数: 18
- 依赖项目数: 4
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2014-09-19