柔晶美网络工作室

柔晶美网络工作室,倾心于web技术的博客站点

关注我 微信公众号

您现在的位置是: 首页 > 博客日记

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');

抄录结束。

文章评论


需要 登录 才能发表评论
热门评论
0条评论

暂时没有评论!