承接 osama-98/laravel-exports 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

osama-98/laravel-exports

Composer 安装命令:

composer require osama-98/laravel-exports

包简介

A Laravel package for exporting data in batches and chunks with support for CSV and XLSX formats

README 文档

README

Latest Version on Packagist Total Downloads License

A powerful Laravel package for exporting large datasets in batches and chunks with support for CSV and XLSX formats. This package provides a clean, fluent API for handling exports efficiently.

Features

  • Batch & Chunk Processing - Handle large datasets efficiently with configurable chunk sizes
  • Queue-Based Exports - Process exports asynchronously using Laravel queues
  • Multiple Formats - Export to both CSV and XLSX formats
  • Column Mapping - Customize column names and labels
  • Progress Tracking - Monitor export progress with detailed status information
  • Query Builder Support - Works with both Eloquent Builder and Query Builder
  • Fluent API - Laravel-style fluent interface for easy configuration
  • Relationship Support - Export related model data with aggregations
  • Custom Formatting - Format dates, numbers, and custom values
  • Storage Flexibility - Support for local, S3, and custom storage disks
  • Event System - Listen to export completion events

Requirements

  • PHP 8.1 or higher
  • Laravel 10.0, 11.0, or 12.0
  • Queue driver configured (database, redis, sqs, etc.)

Installation

Install the package via Composer:

composer require osama-98/laravel-exports

Publish and run the migrations:

# Publish the package migrations
php artisan vendor:publish --tag=laravel-exports-migrations

# Publish Laravel's queue migrations (required for job batching)
php artisan queue:batches-table
php artisan migrate

Note: The job_batches table is required for queue batching functionality. If you're using the database queue driver, you'll also need the jobs and failed_jobs tables:

php artisan queue:table
php artisan queue:failed-table
php artisan migrate

The package will automatically register its service provider.

Quick Start

1. Create an Exporter

Create an exporter class that extends Osama\LaravelExports\Exports\Exporter:

<?php

namespace App\Exports;

use App\Models\User;
use Carbon\Carbon;
use Osama\LaravelExports\Exports\ExportColumn;
use Osama\LaravelExports\Exports\Exporter;
use Osama\LaravelExports\Exports\Models\Export;

class UserExporter extends Exporter
{
    public static function getModel(): string
    {
        return User::class;
    }

    public static function getColumns(): array
    {
        return [
            ExportColumn::make('id')
                ->label('ID'),

            ExportColumn::make('name')
                ->label('Full Name'),

            ExportColumn::make('email')
                ->label('Email Address'),

            ExportColumn::make('created_at')
                ->label('Created At')
                ->formatStateUsing(fn ($state) => $state ? Carbon::parse($state)->format('Y-m-d H:i:s') : null),
        ];
    }

    public static function getCompletedNotificationBody(Export $export): string
    {
        return "Your user export has completed with {$export->successful_rows} rows exported.";
    }
}

2. Start an Export

Using the Facade

use App\Exports\UserExporter;
use App\Models\User;
use Osama\LaravelExports\Facades\Export as ExportFacade;
use Osama\LaravelExports\Exports\Enums\ExportFormat;

// Basic export to XLSX
$export = ExportFacade::exporter(UserExporter::class)
    ->formats([ExportFormat::Xlsx])
    ->start(User::query(), creator: auth()->user());

// Export to both CSV and XLSX
$export = ExportFacade::exporter(UserExporter::class)
    ->formats([ExportFormat::Csv, ExportFormat::Xlsx])
    ->chunkSize(500)
    ->start(User::query(), creator: auth()->user());

Using Dependency Injection

use App\Exports\UserExporter;
use App\Models\User;
use Osama\LaravelExports\Exports\ExportManager;
use Osama\LaravelExports\Exports\Enums\ExportFormat;

public function exportUsers(ExportManager $exportManager)
{
    $export = $exportManager
        ->exporter(UserExporter::class)
        ->chunkSize(500)
        ->formats([ExportFormat::Csv, ExportFormat::Xlsx])
        ->start(User::query(), creator: auth()->user());

    return response()->json([
        'export_id' => $export->id,
        'status' => $export->status->value,
        'total_rows' => $export->total_rows,
    ]);
}

3. Check Export Status

use Osama\LaravelExports\Exports\Models\Export;
use Osama\LaravelExports\Exports\Enums\ExportStatus;

$export = Export::find($exportId);

// Check status
if ($export->status === ExportStatus::Completed) {
    // Export is ready
}

// Get progress percentage
$progress = $export->progressPercentage();

4. Download Export File

use Osama\LaravelExports\Exports\Models\Export;
use Osama\LaravelExports\Exports\Enums\ExportStatus;

public function downloadExport(Export $export, string $format = 'xlsx')
{
    if ($export->status !== ExportStatus::Completed) {
        abort(400, 'Export is not completed yet');
    }

    return $export->download($format);
}

Usage Examples

Export with Custom Column Mapping

$export = ExportFacade::exporter(UserExporter::class)
    ->formats([ExportFormat::Xlsx])
    ->start(
        User::query(),
        columnMap: [
            'id' => 'User ID',
            'name' => 'Full Name',
            'email' => 'Email Address',
            'created_at' => 'Registration Date',
        ],
        creator: auth()->user()
    );

Export with Query Modification

$export = ExportFacade::exporter(UserExporter::class)
    ->modifyQueryUsing(function ($query, $options) {
        // Filter users created in the last 30 days
        return $query->where('created_at', '>=', now()->subDays(30));
    })
    ->formats([ExportFormat::Csv])
    ->start(User::query(), creator: auth()->user());

Export Specific Records by IDs

$userIds = User::take(100)->pluck('id')->toArray();

$export = ExportFacade::exporter(UserExporter::class)
    ->formats([ExportFormat::Csv])
    ->start(User::query(), records: $userIds, creator: auth()->user());

Export with Max Rows Limit

$export = ExportFacade::exporter(UserExporter::class)
    ->maxRows(1000)
    ->chunkSize(200)
    ->formats([ExportFormat::Csv])
    ->start(User::query(), creator: auth()->user());

Export with Custom Options

$export = ExportFacade::exporter(UserExporter::class)
    ->options([
        'date_format' => 'Y-m-d',
        'timezone' => 'UTC',
    ])
    ->fileDisk('local')
    ->fileName('custom-users-export')
    ->formats([ExportFormat::Xlsx])
    ->start(User::query(), creator: auth()->user());

Export Using Query Builder

use Illuminate\Support\Facades\DB;

$export = ExportFacade::exporter(UserExporter::class)
    ->formats([ExportFormat::Csv])
    ->start(DB::table('users')->where('active', true), creator: auth()->user());

Export to S3

$export = ExportFacade::exporter(UserExporter::class)
    ->fileDisk('s3') // Make sure 's3' disk is configured in config/filesystems.php
    ->formats([ExportFormat::Xlsx])
    ->start(User::query()->limit(1000), creator: auth()->user());

Advanced Features

Custom Column State

Customize how column values are extracted:

ExportColumn::make('full_name')
    ->label('Full Name')
    ->getStateUsing(function ($user) {
        return "{$user->first_name} {$user->last_name}";
    });

// Use dot notation for relationships
ExportColumn::make('profile.bio')
    ->label('Biography');

// Use default value
ExportColumn::make('status')
    ->default('active');

Column Formatting

Format dates, numbers, and add prefixes/suffixes:

ExportColumn::make('price')
    ->label('Price')
    ->prefix('$')
    ->formatStateUsing(fn ($state) => number_format($state, 2));

ExportColumn::make('created_at')
    ->label('Created At')
    ->formatStateUsing(fn ($state) => $state ? Carbon::parse($state)->format('Y-m-d H:i:s') : null);

ExportColumn::make('description')
    ->label('Description')
    ->limit(100); // Limit text length

Relationship Aggregations

Export aggregated data from relationships:

ExportColumn::make('orders_count')
    ->label('Total Orders')
    ->counts('orders');

ExportColumn::make('orders_avg_amount')
    ->label('Average Order Amount')
    ->avg('orders', 'amount');

ExportColumn::make('orders_sum_amount')
    ->label('Total Order Amount')
    ->sum('orders', 'amount');

ExportColumn::make('has_orders')
    ->label('Has Orders')
    ->exists('orders');

Query Modification in Exporter

Modify queries directly in your exporter class:

class UserExporter extends Exporter
{
    public static function modifyQuery($query)
    {
        return $query->where('active', true)
            ->with('profile');
    }
}

XLSX Styling

Customize XLSX cell styles:

use OpenSpout\Common\Entity\Style\Style;
use OpenSpout\Common\Entity\Style\Color;
use OpenSpout\Common\Entity\Style\CellAlignment;

class UserExporter extends Exporter
{
    public function getXlsxCellStyle(): ?Style
    {
        return (new Style())
            ->setFontSize(12)
            ->setFontColor(Color::BLACK);
    }

    public function getXlsxHeaderCellStyle(): ?Style
    {
        return (new Style())
            ->setFontSize(14)
            ->setFontBold()
            ->setFontColor(Color::WHITE)
            ->setBackgroundColor(Color::BLUE)
            ->setCellAlignment(CellAlignment::CENTER);
    }
}

Events

ExportCompleted Event

The ExportCompleted event is dispatched when an export finishes processing. Listen to this event to send notifications or perform post-export actions.

Example Listener:

// In your EventServiceProvider
use Osama\LaravelExports\Exports\Events\ExportCompleted;
use Illuminate\Support\Facades\Event;

Event::listen(ExportCompleted::class, function (ExportCompleted $event) {
    $export = $event->export;
    
    // Send notification to user
    if ($export->creator) {
        $export->creator->notify(
            new ExportReadyNotification($export)
        );
    }
    
    // Or log the completion
    Log::info("Export {$export->id} completed with {$export->successful_rows} rows");
});

Example Listener Class:

namespace App\Listeners;

use Osama\LaravelExports\Exports\Events\ExportCompleted;
use Illuminate\Support\Facades\Notification;

class SendExportCompletionNotification
{
    public function handle(ExportCompleted $event): void
    {
        $export = $event->export;
        
        if ($export->creator) {
            $export->creator->notify(
                new ExportReadyNotification($export)
            );
        }
    }
}

Register it in EventServiceProvider:

protected $listen = [
    \Osama\LaravelExports\Exports\Events\ExportCompleted::class => [
        \App\Listeners\SendExportCompletionNotification::class,
    ],
];

Queue Configuration

The package uses Laravel's queue batching system for processing exports. Make sure your queue is properly configured.

Required Database Tables

If you're using the database queue driver, you need the following tables:

  1. job_batches - Required for batch processing (used by this package)
  2. jobs - Required for queue jobs
  3. failed_jobs - Required for failed job tracking

Create these tables:

php artisan queue:batches-table
php artisan queue:table
php artisan queue:failed-table
php artisan migrate

Configure Queue Driver

Configure queue in .env:

QUEUE_CONNECTION=database
# or
QUEUE_CONNECTION=redis

Run queue worker:

php artisan queue:work

For production, use a process manager like Supervisor to keep the queue worker running.

API Reference

ExportManager Methods

Method Description Example
exporter(string $exporter) Set the exporter class ->exporter(UserExporter::class)
start(Builder|QueryBuilder|null $query, ?array $records, ?array $columnMap, $creator) Start the export ->start(User::query(), creator: auth()->user())
chunkSize(int $size) Set chunk size (default: 100) ->chunkSize(500)
maxRows(?int $rows) Set maximum rows limit ->maxRows(10000)
formats(array $formats) Set export formats ->formats([ExportFormat::Csv, ExportFormat::Xlsx])
fileDisk(?string $disk) Set storage disk ->fileDisk('s3')
fileName(?string $name) Set custom file name ->fileName('my-export')
modifyQueryUsing(?Closure $callback) Modify query before export ->modifyQueryUsing(fn($q) => $q->where('active', true))
options(array $options) Set export options ->options(['date_format' => 'Y-m-d'])

ExportColumn Methods

Method Description Example
make(string $name) Create a new column ExportColumn::make('name')
label(string $label) Set column label ->label('Full Name')
getStateUsing(Closure|string $callback) Custom state extraction ->getStateUsing(fn($r) => $r->name)
formatStateUsing(Closure $callback) Format the state value ->formatStateUsing(fn($s) => ucfirst($s))
enabled(bool $enabled) Enable/disable by default ->enabled(false)
default($value) Set default value ->default('N/A')
prefix(string $prefix) Add prefix to value ->prefix('$')
suffix(string $suffix) Add suffix to value ->suffix(' USD')
limit(int $limit) Limit text length ->limit(100)
counts(string $relationship) Count relationship records ->counts('orders')
sum(string $relationship, string $column) Sum relationship column ->sum('orders', 'amount')
avg(string $relationship, string $column) Average relationship column ->avg('orders', 'amount')

Export Model Properties

Property Type Description
id int Export ID
exporter string Exporter class name
status ExportStatus Export status (Pending, Processing, Completed, Failed)
total_rows int Total number of rows to export
processed_rows int Number of rows processed
successful_rows int Number of rows successfully exported
file_name string Export file name
file_disk string Storage disk name
completed_at Carbon|null Completion timestamp
creator Model|null User who created the export (morphTo)

Export Model Methods

Method Description Example
download(string $format) Download export file $export->download('xlsx')
getFileDirectory() Get file directory path $export->getFileDirectory()
getFileDisk() Get Filesystem instance $export->getFileDisk()
getFailedRowsCount() Get count of failed rows $export->getFailedRowsCount()
progressPercentage() Get progress percentage (0-100) $export->progressPercentage()

Testing

Run the test suite:

composer test

Run tests with coverage:

composer test-coverage

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This package is open-sourced software licensed under the MIT license.

Support

For issues, questions, or contributions, please visit the GitHub repository.

Credits

Developed with ❤️ for the Laravel community.

osama-98/laravel-exports 适用场景与选型建议

osama-98/laravel-exports 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 6, 最近一次更新时间为 2026 年 01 月 14 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「excel」 「xlsx」 「csv」 「export」 「laravel」 「batch」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 osama-98/laravel-exports 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 osama-98/laravel-exports 我们能提供哪些服务?
定制开发 / 二次开发

基于 osama-98/laravel-exports 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 6
  • 点击次数: 28
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 6
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-01-14