空卡 / 蛋糕PHP-csvview
为 CakePHP 3.x 定制的 CSV 视图类
Requires
- php: >=5.4.16
- cakephp/cakephp: ~3.0
README
CsvView 插件
快速启用模型数据的 CSV 输出。
背景
我需要快速导出数据库中东西的 CSV 文件。使用视图类手动迭代会是一件麻烦事,所以我想用自定义视图类,比如 JsonView 或 XmlView,会容易得多。
要求
- CakePHP 3.x
- PHP 5.4.16 或更高版本
- 耐心
安装
[使用 Composer]
composer require kongka/cakephp-csvview:dev-master
启用插件
在应用的 config/bootstrap.php
文件中加载插件
Plugin::load('CsvView', ['routes' => true]);
用法
要将扁平数组导出为 CSV,可以编写以下代码
public function export() { $data = [ ['a', 'b', 'c'], [1, 2, 3], ['you', 'and', 'me'], ]; $_serialize = 'data'; $this->viewBuilder()->setClassName('CsvView.Csv'); $this->set(compact('data', '_serialize')); }
所有要包含在 CSV 中的变量都必须在 $_serialize
视图变量中指定,与 JsonView 或 XmlView 的工作方式相同。
CSV 输出中可以有多个变量
public function export() { $data = [['a', 'b', 'c']]; $data_two = [[1, 2, 3]]; $data_three = [['you', 'and', 'me']]; $_serialize = ['data', 'data_two', 'data_three']; $this->viewBuilder()->setClassName('CsvView.Csv'); $this->set(compact('data', 'data_two', 'data_three', '_serialize')); }
如果您想在 CSV 输出中包含标题或页脚,可以指定 $_header
或 $_footer
视图变量。这两个都是完全可选的
public function export() { $data = [ ['a', 'b', 'c'], [1, 2, 3], ['you', 'and', 'me'], ]; $_serialize = 'data'; $_header = ['Column 1', 'Column 2', 'Column 3']; $_footer = ['Totals', '400', '$3000']; $this->viewBuilder()->setClassName('CsvView.Csv'); $this->set(compact('data', '_serialize', '_header', '_footer')); }
您还可以使用 $_delimiter
、$_eol
、$_newline
、$_enclosure
和 $_bom
分别指定分隔符、行结束符、换行符、转义字符和字节顺序标记(BOM)序列
public function export() { $data = [ ['a', 'b', 'c'], [1, 2, 3], ['you', 'and', 'me'], ]; $_serialize = 'data'; $_delimiter = chr(9); //tab $_enclosure = '"'; $_newline = '\r\n'; $_eol = '~'; $_bom = true; $this->viewBuilder()->setClassName('CsvView.Csv'); $this->set(compact('data', '_serialize', '_delimiter', '_enclosure', '_newline', '_eol', '_bom')); }
这些变量的默认值如下
_delimiter
:,
_enclosure
:"
_newline
:\n
_eol
:\n
_bom
: false_setSeparator
: false
_eol
变量用于在输出中生成换行符。然而,_newline
是应替换实际数据中的换行符的字符。建议使用换行符的字符串表示形式,以避免生成无效输出。
某些阅读器软件错误地渲染不包含字节顺序标记(BOM)字节序列的 UTF-8 编码文件。_bom
变量用于在生成的 CSV 输出流的开头添加字节顺序标记(BOM)字节序列。有关更多信息,请参阅 维基百科关于字节顺序标记的文章
。
可以使用 _setSeparator
标志在 CSV 的第一行中显式设置分隔符。某些阅读器需要此才能正确显示 CSV。
如果您有复杂的数据模型,可以使用 $_extract
视图变量来指定每个记录的单独 Hash::extract()
兼容 路径或可调用的函数
public function export() { $posts = $this->Post->find('all'); $_serialize = 'posts'; $_header = ['Post ID', 'Title', 'Created']; $_extract = [ 'id', function ($row) { return $row['title']; }, 'created' ]; $this->viewBuilder()->setClassName('CsvView.Csv'); $this->set(compact('posts', '_serialize', '_header', '_extract')); }
如果您的模型数据中包含一些空值或缺失键,可以使用 $_null
变量,就像使用 $_delimiter
、$_eol
和 $_enclosure
一样,来设置空值在 CSV 中的显示方式。
$_null
默认为 ''
。
您可以使用 Router::extensions()
和 RequestHandlerComponent
自动将 CsvView 类切换如下
// In your routes.php file: Router::extensions('csv'); // In your controller: public $components = [ 'RequestHandler' => [ 'viewClassMap' => ['csv' => 'CsvView.Csv'] ] ]; public function export() { $posts = $this->Post->find('all'); $this->set(compact('post')); if ($this->request->params['_ext'] === 'csv') { $_serialize = 'posts'; $_header = array('Post ID', 'Title', 'Created'); $_extract = array('id', 'title', 'created'); $this->set(compact('_serialize', '_header', '_extract')); } }
访问 /posts/export.csv 以获取数据作为 CSV,并访问 /posts/export 以获取通常的页面。
对于非常复杂的CSV文件,您也可以简单地使用自己的视图文件。为此,您可以不指定$_serialize
,或将其设置为null。视图文件将位于您当前控制器的csv
子目录中
// View used will be in src/Template/Posts/csv/export.ctp public function export() { $posts = $this->Post->find('all'); $_serialize = null; $this->viewBuilder()->setClassName('CsvView.Csv'); $this->set(compact('posts', '_serialize')); }
设置文件的编码
如果您需要在CSV文件中使用不同的编码,您必须设置传递给视图的数据的编码,以及设置您希望CSV文件使用的编码。这可以通过使用_dataEncoding
和_csvEncoding
来实现
默认值如下
_dataEncoding
:UTF-8
_csvEncoding
:UTF-8
** 只有当这两个变量不同时,您的数据才会转换为另一种编码。
CsvView默认使用iconv
扩展来编码数据。您可以通过设置_extension
选项来更改用于编码数据的php扩展
$this->set('_extension', 'mbstring');
当前支持的编码扩展如下
iconv
mbstring
设置下载文件的名称
默认情况下,下载的文件将使用生成它的URL的最后一段命名。例如:使用example.com/my_controller/my_action
会下载my_action.csv
,而使用example.com/my_controller/my_action/first_param
会下载first_param.csv
。
在IE中,您必须设置文件名,否则它将作为文本文件下载。
要设置自定义文件名,请使用Response::download
方法。以下代码段可以用来将下载文件从export.csv
更改为my_file.csv
public function export() { $data = [ ['a', 'b', 'c'], [1, 2, 3], ['you', 'and', 'me'], ]; $_serialize = 'data'; $this->response = $this->response->withDownload('my_file.csv'); // <= setting the file name $this->viewBuilder()->setClassName('CsvView.Csv'); $this->set(compact('data', '_serialize')); }
使用特定的视图构建器
在某些情况下,最好不使用当前模型的视图构建器$this->viewBuilder
,因为对$this->render()
的任何调用都会损害后续的渲染。
例如,在您当前控制器的操作过程中,如果您需要将一些数据作为CSV渲染出来,以便将其简单地保存到服务器上的文件中。
别忘了添加到您的控制器中
use Cake\View\View; use Cake\View\ViewBuilder;
这样您就可以创建一个特定的视图构建器
// Your data array $data = []; // Params $_serialize = 'data'; $_delimiter = ','; $_enclosure = '"'; $_newline = '\r\n'; // Create the builder $builder = new ViewBuilder; $builder->layout = false; $builder->setClassName('CsvView.Csv'); // Then the view $view = $builder->build($data); $view->set(compact('data', '_serialize', '_delimiter', '_enclosure', '_newline')); // And Save the file $file = new File('/full/path/to/file.csv', true, 0644); $file->write($view->render());
许可证
MIT许可证 (MIT)
版权所有 © 2012 Jose Diaz-Gonzalez
特此授予任何获得此软件及其相关文档副本(以下简称“软件”)的人士,免费使用该软件的权利,不受任何限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本的权利,并允许拥有该软件的人士进行上述行为,前提是遵守以下条件
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
该软件按“现状”提供,不提供任何形式的保证,无论是明示的还是暗示的,包括但不限于适销性、特定用途适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论是基于合同、侵权或其他方式引起的,与该软件或其使用或其他交易有关。