laravel Excel

1.安装

1>composer 安装 "maatwebsite/excel": "~2.1.0"
2>app/config/app.php,添加服务
    Maatwebsite\Excel\ExcelServiceProvider::class
    设置Facade:
    'Excel' => Maatwebsite\Excel\Facades\Excel::class,
    这样,就将 'excel' 绑定到了laravel的ioc容器
    $excel = App::make('excel');
3>生成配置文件
    php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider"
    将会在 'app/config/' 添加 'excel.php' 文件
4>依赖
    php > 5.3.7
    laravel >= 4.1
    PHPOffice PHPExcel >= 1.8.0
    php_zip(如果需要处理 .xlsx, .ods, .gnumeric 文件,需要此扩展)
    php_xml
    php_gd2(如果需要精确的自动计算列宽,需要此扩展)

2.导入
    1>导入文件

Excel::load('file.xls');
Excel::load('file.xls', function($reader){ 
});
#回调函数可选

   2>ExcelFile injections(注入):应该是参照Laravel5.0的FormRequest注入,Excel提供了ExcelFile注入
        1)ExcelFile类

class UserListImport extends \Maatwebsite\Excel\Files\ExcelFile {
    public function getFile(){
        return storage_path('exports') . '/file.csv';
    }
 
    public function getFilters() {
        return ['chunk'];
    }
}
//getFile() - 返回要导入的excel的文件名及路径。
//getFilters() - 可以启用各种 'filter'(过滤器)
//getFile()如果想动态获取用户上传的文件,可以参考下方:
    public function getFile() {
        // Import a user provided file
        $file = Input::file('report');        // 文件上传
        $filename = $this->doSomethingLikeUpload($file);    // 执行上传,得到上传后路径
 
        // Return it's location
        return $filename;        // 返回上传后路径
    }
}

        2)使用:定义好了ExcelFile注入类,可以注入到 构造方法或其他方法

Class TestController extends Controller {
    // 从这里就很明显知道是个什么意思了    
    // public function __construct(Request $request)
    // 我们经常使用Request请求
    public function __construct(UserListImport $import) {
        // 获取结果
        $results = $import->get();
    }
}

        3)CSV配置:可以定义一些可选的CSV设置项,用类的 'protected' 属性来定义

protected $delimiter  = ',';
protected $enclosure  = '"';
protected $lineEnding = '\r\n';

        4)导入处理:为了完全将Excel导入代码与控制器解耦,可以使用导入处理

public function importUserList(UserListImport $import){
    $import->handleImport();    // 导入处理
}
//上面的 'handleImport()' 方法,将会动态调用一个 '类名'.'Handler' 的处理类(以我们定义的'UserListImport' 为例,就应该是 'UserListImportHandler'),所以我们还得定义 '处理类'
class UserListImportHandler implements \Maatwebsite\Excel\Files\ImportHandler {
    public function handle(UserListImport $import) {
        // 获取结果
        $results = $import->get();
    }
}
//提示:就是将处理结果的方法,又抽离到另一个类中(算是公共方法,而不是仅这个控制器可用)

    3>处理导入结果
        1)获取所有工作表和每个工作表内的所有行
            2种处理方式,都可以:

1.Excel::load('file.xls', function($reader){})->get();
2.Excel::load('file.xls', function($reader){
    // 获取所有结果
    $results = $reader->get();
    // all()方法,是对 get()方法的一个包装,工作一致
    $results = $reader->all();
});
//get()和all(),会返回一个 '工作表集合' 或者 '单个工作表内所有行的集合'(发现只有1张工作表时)
//提示:我们可以通过配置:excel.php -> force_sheets_collection = true,强制,即使单个表,也返回 '工作表集合'

        2)表标题:默认,工作表的第一行为表标题

$row->firstname;
//注意:默认情况下,这些属性会被转换为 'slug'。可以通过配置import.heading来改变默认行为。可选值有:true | false | slugged | ascii | numberic | hashed | trans | original
//true 和 slugged 也会被转换为 'ascii',等同于设置了 'ascii'

        3)集合:工作表(sheets)、行(rows)、单元格(cells)都是集合,只要是通过 'get()' 方法获取后,我们都可以调用 'laravel' 的集合方法

$reader->get()->groupBy();

        4)获取第一张工作表 或 第一行

$reader->first();
//注意:上面也提到了 'force_sheets_collection' 配置,根据这一配置,excel只有单个工作表时,这个获取的可能是 '第一张工作表' 或 '第一行'

        5)工作簿(excel文件)和工作表(sheets)标题

$reader->getTitle();    // excel文件名
foreach($reader as $sheet) {
    $sheetTitle = $sheet->getTitle();    // 工作表名
}

        6)限制文件读取
            1.获取行

$reader->takeRows(10);
$reader->limitRows(10);

           2.跳过行(偏移)

$reader->skipRows(10);            // 跳过10行
$reader->limitRows(false, 10);    // 跳过10行,但不进行行限制,读取剩余所有行    
$reader->skipRows(10)->takeRows(10);    // 跳过10行,并读取10行

            3.获取列

$reader->takeColumns(10);
$reader->limitColumns(10);

            4.跳过列(偏移)

$reader->skipColumns(10);            // 跳过10列
$reader->limitColumns(false, 10);    // 跳过10列,但不进行列限制,读取剩余所有列    
$reader->skipColumns(10)->takeColumns(10);    // 跳过10列,并读取10列

        7)结果转换
            默认获取的是一个集合
            1)转换为数组

$reader->toArray();

            2)转换为对象

$reader->toObject();

        8)打印结果

$reader->dump();    // 打印结果
$reader->dd();        // 打印结果,并退出

        9)迭代结果

$reader->each(function($sheet){        // 循环所有工作表
    $sheet->each(function($row){    // 循环单个工作表,所有行
    });
});
//提示:也可使用 foreach() 来循环结果集

    4>选择工作表和列
        1)选择指定的工作表

Excel::selectSheets('sheet1')->load();

        2)选择多个工作表           

 Excel::selectSheets('sheet1', 'sheet2')->load();    // 也可以传递一个数组 ['sheet1', 'sheet2']

        3)通过下标选择工作表(index 从 0 开始)

Excel::selectSheetsByIndex(0)->load();
Excel::selectSheetsByIndex(0, 1)->load();

        4)选择列

1.$reader->select(['firstname', 'lastname'])->get();
2.$reader->get(['firstname', 'lastname']);
//注意:所有的获取结果方法(例如:all(), first(), dump(), toArray(), ...),都接收一个 '列数组' 参数

    5>日期
        默认情况下,日期将被解析为一个 'Carbon' 对象(这个可以了解下,是composer的一个日期处理包).
        可配置 dates.enabled = false,禁用日期格式(对整个项目生效)
        1)单个导入,开启/禁用日期格式化,使用 '->formatDates($boolean, $format)'            

$reader->formatDates(true);        // 启用
$reader->formatDates(false);    // 禁用
$reader->formatDates(true, 'Y-m-d');    // 启用,并设置日期格式

        2)日期格式
            默认,日期并未格式化,但是返回一个 'Carbon' 对象,我们有2种方式,来格式化日期:
            1.先用过 'get()' 等方法获取结果后,再格式化

$rows->each(function($row){
    $created_at = $row->created_at->format('Y-m-d');    // 获取到的$row->created_at,已经是一个 'Carbon' 对象
});

            2.设置一个默认的日期格式
                1>在 excel.php 配置文件中,设置日期格式,则不会再返回 'Carbon' 对象
                2>或者,我们仅在本次导入设置日期格式,$reader->setDateFormat('Y-m-d');
        3)设置自定义日期列
            不是Excel格式日期的单元格不会被解析为日期。我们可以设置哪些字段,来手动格式化为日期格式。
            $reader->setDateColumns(['created_at', 'updated_at'])->get();
    6>计算公式
        默认情况下,文件内的公式会被计算,并返回结果。
        可配置 import.calculate 来改变默认行为。
        1)import.calculate = false
        2)仅在单次导入时,设置
            $reader->calculate([fals]);    // 禁用
            $reader->calculate(true);    // 启用
    7>自定义单元格值(例如:统一添加前缀,替换敏感词为 '*'等,处理单元格的值)
        看文档
    8>缓存和单元格缓存
        1)单元格缓存
            在 excel.php 中,配置 '单元格缓存'。默认开启缓存,并使用 '内存缓存'
        2)缓存excel文件结果集
            记录结果集,可使用 remember($minutes) 方法。下次载入同样文件时(如果它还在缓存中),将返回缓存的结果
            $results = $reader->remember(10)->get();    // 缓存10分钟
    9>分块导入
        1)当导入大文件时,最好的解决方法是 '分块导入'。可通过 filter('chunk') 来开启;并且使用 'chunk($size, $callback)' 来代替 'get()' 获取结果集。

 Excel::filter('chunk')->load('file.csv')->chunk(250, function($results) {
    // 处理结果集
    foreach($results as $row){
    }
});

        2)ExcelFile 注入实例:

class UserListImport extends \Maatwebsite\Excel\Files\ExcelFile {
    public function getFile() {
        return storage_path('exports') . '/file.csv';
    }
    public function getFilters() {
        return [
            'chunk'        // 使用 'chunk' 过滤器
        ];
    }
}

public function importUserList(UserListImport $import)     // 注入 ExcelFile
{
    $import->chunk(250, function($results){});
}

未完待续:http://www.maatwebsite.nl/laravel-excel/docs/reference-guide

你可能感兴趣的:(PHP)