空卡/蛋糕PHP-csvview

为 CakePHP 3.x 定制的 CSV 视图类

安装: 80

依赖者: 0

建议者: 0

安全: 0

星标: 0

关注者: 0

分支: 64

类型:cakephp-plugin

3.2.3 2018-07-13 12:45 UTC

This package is auto-updated.

Last update: 2024-09-06 16:47:55 UTC


README

Build Status Coverage Status Total Downloads Latest Stable Version Software License

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

特此授予任何获得此软件及其相关文档副本(以下简称“软件”)的人士,免费使用该软件的权利,不受任何限制,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本的权利,并允许拥有该软件的人士进行上述行为,前提是遵守以下条件

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

该软件按“现状”提供,不提供任何形式的保证,无论是明示的还是暗示的,包括但不限于适销性、特定用途适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任承担责任,无论是基于合同、侵权或其他方式引起的,与该软件或其使用或其他交易有关。