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