PHP code example of businessg / laravel-excel
1. Go to this page and download the library: Download businessg/laravel-excel library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
businessg / laravel-excel example snippets
return [
/*
|----------------------------------------------------------------------
| default — 默认驱动名称
|----------------------------------------------------------------------
| 对应下方 drivers 数组中的 key。目前仅支持 xlswriter。
*/
'default' => 'xlswriter',
/*
|----------------------------------------------------------------------
| drivers — 驱动配置
|----------------------------------------------------------------------
| class : 驱动实现类
| disk : 文件系统磁盘名,对应 config/filesystems.php 中的 disks key
| exportDir : 导出文件存放子目录(相对于 disk 根路径)
| tempDir : 临时文件目录,null 则使用 sys_get_temp_dir()
*/
'drivers' => [
'xlswriter' => [
'class' => \BusinessG\BaseExcel\Driver\XlsWriterDriver::class,
'disk' => 'local',
'exportDir' => 'export',
'tempDir' => null,
],
],
/*
|----------------------------------------------------------------------
| logging — 日志配置
|----------------------------------------------------------------------
| channel : 日志通道名称,对应 config/logging.php 中的 channels key
*/
'logging' => [
'channel' => 'stack',
],
/*
|----------------------------------------------------------------------
| queue — 异步队列配置
|----------------------------------------------------------------------
| 仅当 ExportConfig/ImportConfig 中 isAsync = true 时生效。
|
| connection : 队列连接名,对应 config/queue.php 中的 connections key
| channel : 队列名称(Laravel 的 onQueue)
*/
'queue' => [
'connection' => 'default',
'channel' => 'default',
],
/*
|----------------------------------------------------------------------
| progress — Redis 进度追踪配置
|----------------------------------------------------------------------
| enabled : 是否启用进度追踪
| prefix : Redis key 前缀,最终格式 {prefix}:progress:{token}
| ttl : 进度数据过期时间(秒)
| connection : Redis 连接名,对应 config/database.php 中 redis.connections 的 key
*/
'progress' => [
'enabled' => true,
'prefix' => 'LaravelExcel',
'ttl' => 3600,
'connection' => 'default',
],
/*
|----------------------------------------------------------------------
| dbLog — 数据库日志配置
|----------------------------------------------------------------------
| enabled : 是否启用数据库日志记录
| model : Eloquent Model 类名
*/
'dbLog' => [
'enabled' => true,
'model' => \BusinessG\LaravelExcel\Db\Model\ExcelLog::class,
],
/*
|----------------------------------------------------------------------
| 事件监听器(Laravel Event)
|----------------------------------------------------------------------
| 内置默认(始终启用,无需重复声明):
| - ProgressListener 进度追踪(受 progress.enabled 控制)
| - ExcelLogDbListener 数据库日志(受 dbLog.enabled 控制)
|
| 本项为**追加**监听器:
| - 未配置或 []:仅使用默认
| - 配置类名:在默认之后追加注册,自动按序去重
|
| 自定义监听器需继承 \BusinessG\BaseExcel\Listener\AbstractBaseListener。
*/
'listeners' => [
// \BusinessG\BaseExcel\Listener\ExcelLogListener::class,
],
/*
|----------------------------------------------------------------------
| cleanup — 临时文件自动清理
|----------------------------------------------------------------------
| enabled : 是否启用
| maxAge : 文件最大存活时间(秒)
| interval : 清理任务执行间隔(秒)
*/
'cleanup' => [
'enabled' => true,
'maxAge' => 1800,
'interval' => 3600,
],
/*
|----------------------------------------------------------------------
| http — HTTP 接口与响应配置
|----------------------------------------------------------------------
|
| 路由注册(enabled = true 时生效):
| 自动注册 {prefix}/excel/* 路由组,无需手写 Controller 和路由文件。
|
| enabled : 是否自动注册路由
| prefix : 路由前缀,如 'api' → api/excel/export
| middleware : 中间件数组,应用到整个路由组
| domain : 项目域名(含协议),用于 info 接口拼接动态模板 URL
|
| fieldNaming : 接口返回 JSON 的字段命名风格
| 'camel'(默认)— 驼峰,如 sheetListProgress、isEnd、templateUrl
| 'snake' — 下划线,如 sheet_list_progress、is_end、template_url
|
| response — 统一响应体构建(闭包):
| responseCallback : (可选)根据执行结果组装 HTTP 响应数组的闭包。
| 签名: function(ResponseContext $context): array
| ResponseContext 属性:
| - isSuccess (bool) — 本次调用是否成功
| - code (int|string) — 组件错误码(成功时为 ExcelErrorCode::SUCCESS,即 0)
| - data (mixed) — 载荷
| - message (string) — 提示文案
| 返回值经 JSON 编码即为接口响应体(或与框架包装配合)。
| 未配置时使用默认闭包,返回 ['code' => $context->code, 'data' => $context->data, 'message' => $context->message]。
| 若需对齐既有 API 规范,可在闭包中改写字段名或嵌套结构,例如:
| return ['errno' => $context->code, 'result' => $context->data, 'msg' => $context->message];
|
| upload — 文件上传配置:
| disk : 文件系统磁盘名,对应 config/filesystems.php 中的 disks key
| dir : 导入文件存放目录(相对于 disk 根路径)
*/
'http' => [
'enabled' => false,
'prefix' => 'api',
'middleware' => ['api'],
'domain' => env('APP_URL', 'http://localhost'),
'fieldNaming' => 'camel',
'response' => [
// 自定义响应构建闭包(可选,未配置时使用默认闭包)
// 'responseCallback' => function(\BusinessG\BaseExcel\Data\ResponseContext $context): array {
// return ['code' => $context->code, 'data' => $context->data, 'message' => $context->message];
// },
],
'upload' => [
'disk' => 'local',
'dir' => 'excel-import',
],
],
];
'listeners' => [
\BusinessG\BaseExcel\Listener\ExcelLogListener::class,
],
use BusinessG\BaseExcel\Event\AfterExport;
use BusinessG\BaseExcel\Listener\AbstractBaseListener;
class MyExportListener extends AbstractBaseListener
{
public function listen(): array
{
return [AfterExport::class];
}
public function afterExport(AfterExport $event): void
{
// $event->config 即当前导出配置
}
}
'export' => [
/*
| key(如 'orderExport')即为 business_id,
| 调用接口时传入此值触发对应的导出逻辑。
|
| config : ExportConfig 子类的完整类名(必填)
*/
'orderExport' => [
'config' => \App\Excel\OrderExportConfig::class,
],
],
'import' => [
/*
| key(如 'orderImport')即为 business_id。
|
| config : ImportConfig 子类的完整类名(必填)
| info : 可选,附加信息。前端通过 GET /excel/info?business_id=xxx 获取。
|
| info.templateBusinessId — 动态模板(推荐)
| 值为一个导出 business_id。info 接口会自动拼接为完整 URL:
| {http.domain}/{http.prefix}/excel/export?business_id={templateBusinessId}
| 对应的导出配置必须满足: isAsync=false + outPutType='out'
|
| info.templateUrl — 静态模板
| 值为完整的 URL 地址,info 接口直接返回。
|
| 两者二选一。如同时配置,templateUrl 优先。
*/
'orderImport' => [
'config' => \App\Excel\OrderImportConfig::class,
'info' => [
'templateBusinessId' => 'orderImportTemplate',
],
],
],
'http' => [
'enabled' => true,
'prefix' => 'api',
'middleware' => ['api'],
'domain' => env('APP_URL', 'http://localhost'),
// ...
],
declare(strict_types=1);
namespace App\Excel;
use App\Models\Order;
use BusinessG\BaseExcel\Data\Export\Column;
use BusinessG\BaseExcel\Data\Export\ExportCallbackParam;
use BusinessG\BaseExcel\Data\Export\ExportConfig;
use BusinessG\BaseExcel\Data\Export\Sheet;
class OrderExportConfig extends ExportConfig
{
public string $serviceName = '订单导出';
public bool $isAsync = false;
public string $outPutType = self::OUT_PUT_TYPE_UPLOAD;
public function getSheets(): array
{
$this->setSheets([
new Sheet([
'name' => '订单列表',
'columns' => [
new Column(['title' => '订单号', 'field' => 'order_no', 'width' => 20]),
new Column(['title' => '客户名称', 'field' => 'customer_name']),
new Column(['title' => '金额', 'field' => 'amount']),
new Column(['title' => '状态', 'field' => 'status_text']),
new Column(['title' => '创建时间', 'field' => 'created_at']),
],
'count' => $this->getDataCount(),
'data' => [$this, 'getData'],
'pageSize' => 1000,
]),
]);
return $this->sheets;
}
public function getDataCount(): int
{
return Order::count();
}
public function getData(ExportCallbackParam $param): array
{
return Order::query()
->offset(($param->page - 1) * $param->pageSize)
->limit($param->pageSize)
->get()
->map(fn ($order) => [
'order_no' => $order->order_no,
'customer_name' => $order->customer_name,
'amount' => $order->amount,
'status_text' => $order->status === 1 ? '已完成' : '待处理',
'created_at' => $order->created_at->format('Y-m-d H:i:s'),
])
->toArray();
}
}
'export' => [
'orderExport' => [
'config' => \App\Excel\OrderExportConfig::class,
],
],
declare(strict_types=1);
namespace App\Excel;
use BusinessG\BaseExcel\Data\Export\Column;
use BusinessG\BaseExcel\Data\Export\ExportConfig;
use BusinessG\BaseExcel\Data\Export\Sheet;
use BusinessG\BaseExcel\Data\Export\Style;
class OrderImportTemplateConfig extends ExportConfig
{
public string $serviceName = '订单导入模板';
public bool $isAsync = false;
public string $outPutType = self::OUT_PUT_TYPE_OUT;
public function getSheets(): array
{
$this->setSheets([
new Sheet([
'name' => 'sheet1',
'columns' => [
new Column([
'title' => implode("\n", [
'1、订单号:必填',
'2、金额:必填,数字类型',
'3、请按照模板格式填写',
]),
'field' => 'order_no',
'height' => 58,
'headerStyle' => new Style([
'wrap' => true,
'fontColor' => 0x2972F4,
'fontSize' => 10,
'bold' => true,
'align' => [Style::FORMAT_ALIGN_LEFT, Style::FORMAT_ALIGN_VERTICAL_CENTER],
]),
'children' => [
new Column(['title' => '订单号', 'field' => 'order_no', 'width' => 30]),
new Column(['title' => '金额', 'field' => 'amount', 'width' => 20]),
],
]),
],
'count' => 0,
'data' => [],
'pageSize' => 1,
]),
]);
return $this->sheets;
}
}
declare(strict_types=1);
namespace App\Excel;
use App\Models\Order;
use BusinessG\BaseExcel\Data\Import\Column;
use BusinessG\BaseExcel\Data\Import\ImportConfig;
use BusinessG\BaseExcel\Data\Import\ImportRowCallbackParam;
use BusinessG\BaseExcel\Data\Import\Sheet;
use BusinessG\BaseExcel\Exception\ExcelException;
use BusinessG\BaseExcel\ExcelFunctions;
class OrderImportConfig extends ImportConfig
{
public string $serviceName = '订单导入';
public bool $isAsync = false;
public function getSheets(): array
{
$this->setSheets([
new Sheet([
'name' => 'sheet1',
'headerIndex' => 2,
'columns' => [
new Column(['title' => '订单号', 'field' => 'order_no']),
new Column(['title' => '金额', 'field' => 'amount']),
],
'callback' => [$this, 'rowCallback'],
]),
]);
return $this->sheets;
}
public function rowCallback(ImportRowCallbackParam $param): void
{
if (empty($param->row)) {
return;
}
$rowNum = $param->rowIndex + 3;
$orderNo = $param->row['order_no'] ?? '';
$amount = $param->row['amount'] ?? '';
if (empty($orderNo)) {
throw new ExcelException("第{$rowNum}行: 订单号不能为空");
}
Order::create([
'order_no' => $orderNo,
'amount' => (float) $amount,
]);
if (ExcelFunctions::hasContainer()) {
ExcelFunctions::progressPushMessage(
$param->config->getToken(),
"第{$rowNum}行: 订单 {$orderNo} 导入成功"
);
}
}
}
'export' => [
// ...
'orderImportTemplate' => [
'config' => \App\Excel\OrderImportTemplateConfig::class,
],
],
'import' => [
'orderImport' => [
'config' => \App\Excel\OrderImportConfig::class,
'info' => [
'templateBusinessId' => 'orderImportTemplate',
],
],
],
'connections' => [
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'default',
'retry_after' => 90,
],
],
'queue' => [
'connection' => 'redis',
'channel' => 'excel',
],
class OrderAsyncExportConfig extends ExportConfig
{
public bool $isAsync = true; // 开启异步
public string $outPutType = self::OUT_PUT_TYPE_UPLOAD; // 异步必须用 UPLOAD
// ...
}
public function getSheets(): array
{
$this->setSheets([ new Sheet([...]) ]);
return $this->sheets;
}
new Column([
'title' => "1、姓名:必填\n2、邮箱:必填",
'field' => 'name',
'height' => 58,
'headerStyle' => new Style([
'wrap' => true,
'fontColor' => 0x2972F4,
'fontSize' => 10,
'bold' => true,
'align' => [Style::FORMAT_ALIGN_LEFT, Style::FORMAT_ALIGN_VERTICAL_CENTER],
]),
'children' => [
new Column(['title' => '姓名', 'field' => 'name', 'width' => 20]),
new Column(['title' => '邮箱', 'field' => 'email', 'width' => 30]),
],
])
use BusinessG\BaseExcel\Data\Export\Style;
$headerStyle = new Style([
'bold' => true,
'fontSize' => 12,
'fontColor' => 0x2972F4,
'backgroundColor' => 0xF2F2F2,
'backgroundStyle' => Style::PATTERN_SOLID,
'border' => Style::BORDER_THIN,
'align' => [Style::FORMAT_ALIGN_CENTER, Style::FORMAT_ALIGN_VERTICAL_CENTER],
]);
new Column([
'title' => '备注',
'field' => 'remark',
'width' => 40,
'headerStyle' => $headerStyle,
'style' => new Style(['border' => Style::BORDER_THIN, 'wrap' => true]),
])
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
],
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
],
// config/queue.php
'connections' => [
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => 'default',
'retry_after' => 90,
],
],
bash
php artisan vendor:publish --tag=excel-config
bash
php artisan migrate
bash
php artisan excel:export "App\Excel\OrderExportConfig"
bash
php artisan queue:work redis --queue=excel