laravel dcat admin的导入导出excel插件dcat/easy-excel使用文档
2021-06-14 admin php laravel 2349
Easy Excel是一个基于 box/spout 封装的Excel读写工具,可以帮助开发者更快速更轻松的读写Excel文件, 并且无论读取多大的文件只需占用极少的内存。
由于box/spout只支持读写xlsx、csv、ods等类型文件,所以本项目目前也仅支持读写这三种类型的文件。安装:
composer require dcat/easy-excel
一、导入Excel
Easy Excel 会根据传入的文件名后缀自动判断需要读取的文件类型。
use Dcat\EasyExcel\Excel;
// 导入xlsx
$allSheets = Excel::import('/tmp/users.xlsx')->toArray();
// 导入csv
$allSheets = Excel::import('/tmp/users.csv')->toArray();
// 导入ods
$allSheets = Excel::import('/tmp/users.ods')->toArray();
Laravel 和 Symfony 框架中可以直接导入浏览器上传的文件:
use Dcat\EasyExcel\Excel;
use Illuminate\Http\Request;
class IndexController
{
public function upload(Request $request)
{
// 直接读取前端上传的文件
$allSheets = Excel::import($request->file('user_data'))->toArray();
}
}
Easy Excel 默认会把Excel表格中的第一行数据当做标题,然后合并到读取的数据行中(作为数据行的key使用)。如果开发者想使用自定义标题,则可以以下方式设置:
use Dcat\EasyExcel\Excel;
$headings = ['id', 'email', 'name'];
// 导入xlsx
$allSheets = Excel::import('/tmp/users.xlsx')->headings($headings)->toArray();
var_dump($allSheets);
将得到如下结果
[
'Sheet1' => [
2 => ['id' => 1, 'email' => 'treutel@eg.com', 'name' => 'Brakus'],
3 => ['id' => 2, 'email' => 'josefa@eg.com', 'name' => 'Eichmann'],
],
];
如果标题不在第一行,则可以通过以下方法轻松的指定标题所在的行
use Dcat\EasyExcel\Excel;
$headings = ['id', 'email', 'name'];
// 指定第二行为标题行
$allSheets = Excel::import('/tmp/users.xlsx')
->headings($headings)
->headingRow(2)
->toArray();
// 也可以传闭包
$allSheets = Excel::import('/tmp/users.xlsx')
->headings($headings)
->headingRow(function (int $line, array $row) {
// $line 为数据行在excel表中的行号,$row 为数据行内容
return $line == 2;
})
->toArray();
var_dump($allSheets);
禁用标题可用以下方式:
use Dcat\EasyExcel\Excel;
// 导入xlsx
$allSheets = Excel::import('/tmp/users.xlsx')->headings(false)->toArray();
var_dump($allSheets);
把所有表格数据转化为数组
use Dcat\EasyExcel\Excel;
// 导入xlsx
$allSheets = Excel::import('/tmp/users.xlsx')->toArray();
var_dump($allSheets);
把所有表格数据转化为 SheetCollection 对象:
use Dcat\EasyExcel\Excel;
// 导入xlsx
$allSheetsCollection = Excel::import('/tmp/users.xlsx')->collect();
循环读取excel的所有sheet
use Dcat\EasyExcel\Excel;
use Dcat\EasyExcel\Contracts\Sheet as SheetInterface;
Excel::import('/tmp/users.xlsx')->each(function (SheetInterface $sheet) {
// 单独处理每个表格内容
$sheetArray = $sheet->toArray();
// 获取表格名称,如果是csv文件,则此方法返回空字符串
$sheetName = $sheet->getName();
// 表格序号,从 0 开始
$sheetIndex = $sheet->getIndex();
var_dump($sheetArray);
})
只读取第一个表格内容
use Dcat\EasyExcel\Excel;
// Dcat\EasyExcel\Contracts\Sheet
$sheet = Excel::import('/tmp/users.xlsx')->first();
// 表格名称
$sheetName = $sheet->getName();
var_dump($sheet->toArray());
根据表格名称或位置索引读取指定表格内容,默认的表格名称通常为 Sheet1。
use Dcat\EasyExcel\Excel;
// 根据表格名称读取表格内容
$sheet1 = Excel::import('/tmp/users.xlsx')->sheet('Sheet1');
// 根据表格的位置索引读取指定表格内容
$firstSheet = Excel::import('/tmp/users.xlsx')->sheet(0);
分块读取所有表格:
use Dcat\EasyExcel\Excel;
use Dcat\EasyExcel\Contracts\Sheet as SheetInterface;
use Dcat\EasyExcel\Support\SheetCollection;
Excel::import('/tmp/users.xlsx')->each(function (SheetInterface $sheet) {
// 每100行数据为一批数据进行读取
$chunkSize = 100;
$sheet->chunk($chunkSize, function (SheetCollection $collection) {
// 此处的数组下标依然是excel表中数据行的行号
$rows = $collection->toArray();
...
});
})
分块读取单个表格:
use Dcat\EasyExcel\Excel;
use Dcat\EasyExcel\Contracts\Sheet as SheetInterface;
use Dcat\EasyExcel\Support\SheetCollection;
// 每100行数据为一批数据进行读取
$chunkSize = 100;
Excel::import('/tmp/users.xlsx')
->first()
->chunk($chunkSize, function (SheetCollection $collection) {
// 此处的数组下标依然是excel表中数据行的行号
$rows = $collection->toArray();
...
});
二、导出
Exporter::download方法可以通过浏览器下载导出的文件,该方法会根据文件名后缀自动判断导出的文件类型。
use Dcat\EasyExcel\Excel;
$array = [
['id' => 1, 'name' => 'Brakus', 'email' => 'treutel@eg.com', 'created_at' => '...'],
...
];
// 导出xlsx类型文件
Excel::export($array)->download('users.xlsx');
Excel::xlsx($array)->download('users.xlsx');
// 导出csv类型文件
Excel::export($array)->download('users.csv');
Excel::csv($array)->download('users.csv');
// 导出ods类型文件
Excel::export($array)->download('users.ods');
Excel::ods($array)->download('users.ods');
Exporter::store方法可以保存导出的文件到服务器,该方法会根据文件名后缀自动判断导出的文件类型。
use Dcat\EasyExcel\Excel;
$array = [
['id' => 1, 'name' => 'Brakus', 'email' => 'treutel@eg.com', 'created_at' => '...'],
...
];
// 导出xlsx类型文件
Excel::export($array)->store('users.xlsx');
Excel::xlsx($array)->store('users.xlsx');
// 导出csv类型文件
Excel::export($array)->store('users.csv');
Excel::csv($array)->store('users.csv');
// 导出ods类型文件
Excel::export($array)->store('users.ods');
Excel::ods($array)->store('users.ods');
Easy Excel 对 league/flysystem 提供了支持,通过 Filesystem 可以轻松的把文件保存到任意服务器,比如阿里云OSS。这里只为演示用法,如需保存到第三方云存储服务器,则找到相应的adapter实现包即可
use Dcat\EasyExcel\Excel;
use League\Flysystem\Adapter\Local;
use League\Flysystem\Filesystem;
$array = [...];
$adapter = new Local(__DIR__);
$filesystem = new Filesystem($adapter);
Excel::export($array)->disk($filesystem)->store('users.xlsx');
设置导出数据,数组:
use Dcat\EasyExcel\Excel;
$array = [
['id' => 1, 'name' => 'Brakus', 'email' => 'treutel@eg.com', 'created_at' => '...'],
...
];
$exporter = Excel::export($array);
分块获取
此功能的实现原理是使用while循环获取匿名函数返回的值,如果匿名函数返回的结果不为空则循环会一直进行下去,所以需要注意不能让匿名函数的返回值一直不为空。
use Dcat\EasyExcel\Excel;
use App\User;
Excel::export()
->chunk(function (int $times) { // $times 表示循环次数,从1开始,可以当做查询页数实用
// 每次获取1000条数据导入
$chunkSize = 1000;
// 只查询前10页数据
if ($times > 10) {
return;
}
// 当数据库查不到值时会停止执行闭包内的逻辑
return User::query()->forPage($times, $chunkSize)->get();
})
->download('users.xlsx');
导出数据到多个表格
use Dcat\EasyExcel\Excel;
$sheetArray1 = [
['id' => 1, 'name' => 'Brakus', 'email' => 'treutel@eg.com', 'created_at' => '...'],
...
];
$sheetArray2 = [...];
$sheets = [
'sheet名称1' => $sheetArray1,
'sheet名称2' => $sheetArray2,
...
];
Excel::export($sheets)->store('users.xlsx');
设置标题
Exporter::headings 方法可以直接设置要导出的文件的标题,并且可以根据标题控制列的排序。
use Dcat\EasyExcel\Excel;
$array = [
['id' => 1, 'name' => 'Brakus', 'email' => 'treutel@eg.com', 'created_at' => '...'],
...
];
// 设置标题,丢弃created_at字段,并更改列的先后顺序,
$headings = [
'id' => 'ID',
'email' => '邮箱',
'name' => '名称',
];
// 最后导出的列只有 id、email、name
Excel::export($array)->headings($headings)->download('users.xlsx');
如果不想导出的文件中带有标题行,可以通过以下方式禁用标题行。
use Dcat\EasyExcel\Excel;
$array = [
['id' => 1, 'name' => 'Brakus', 'email' => 'treutel@eg.com', 'created_at' => '...'],
...
];
// 传入 false 即可
Excel::export($array)->headings(false)->download('users.xlsx');
标题样式,参考文档box/spout。
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Common\Entity\Style\Color;
use Dcat\EasyExcel\Excel;
$array = [
['id' => 1, 'name' => 'Brakus', 'email' => 'treutel@eg.com', 'created_at' => '...'],
];
Excel::export($array)
->headings(function () {
$headings = [
'id' => 'ID',
'email' => '邮箱',
'name' => '名称',
];
// 定义样式
$style = (new StyleBuilder())
->setFontBold()
->setFontSize(15)
->setFontColor(Color::BLUE)
->setShouldWrapText()
->setBackgroundColor(Color::YELLOW)
->build();
return [$headings, $style];
})
->download('users.xlsx');
给每个表格设置不同的标题
use Dcat\EasyExcel\Excel;
use App\User;
// 创建多个sheet,并设置不同的标题
$user1 = User::query()->forPage(1, 50)->get();
$sheet1 = Excel::createSheet($user1, 'sheet名称1')->headings([...]);
$user2 = User::query()->forPage(2, 50)->get();
$sheet2 = Excel::createSheet($user2, 'sheet名称2')->headings([...]);
Excel::export([$sheet1, $sheet2])->download('users.xlsx');
设置内容样式
use Box\Spout\Writer\Common\Creator\WriterEntityFactory;
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Common\Entity\Style\Color;
use Dcat\EasyExcel\Excel;
$array = [
['id' => 1, 'name' => 'Brakus', 'email' => 'treutel@eg.com', 'created_at' => '2019-10-19 00:37:22'],
['id' => 2, 'name' => 'Eichmann', 'email' => 'josefa@eg.com', 'created_at' => '2019-10-19 00:37:22'],
];
Excel::export($array)
->row(function (array $row) {
// 直接返回原数组,什么也不改变
if ($row['id'] > 1) {
return $row;
}
// 设置样式
$style = (new StyleBuilder())
->setFontSize(13)
->setFontColor(Color::LIGHT_BLUE)
->setShouldWrapText()
->build();
return WriterEntityFactory::createRowFromArray($row, $style);
})
->download('users.xlsx');
设置默认样式
use Box\Spout\Writer\Common\Creator\Style\StyleBuilder;
use Box\Spout\Common\Entity\Style\Color;
use Dcat\EasyExcel\Excel;
$array = [
['id' => 1, 'name' => 'Brakus', 'email' => 'treutel@eg.com', 'created_at' => '2019-10-19 00:37:22'],
...
];
Excel::export($array)
->option(function ($writer) {
// 设置样式
$style = (new StyleBuilder())
->setFontSize(13)
->setFontColor(Color::LIGHT_BLUE)
->setShouldWrapText()
->build();
$writer->setDefaultRowStyle($style);
})
->download('users.xlsx');
抄录结束。