toporia/docura

High-performance document import/export package for Toporia Framework - PDF, Word, Excel, CSV, HTML

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/toporia/docura

dev-main 2025-12-17 16:05 UTC

This package is auto-updated.

Last update: 2025-12-17 17:03:49 UTC


README

High-Performance Document Import/Export Package for Toporia Framework

PHP Version License

Docura provides a powerful, clean API for importing and exporting documents in various formats including PDF, Excel, Word, CSV, and HTML. Built with performance and memory efficiency in mind, it supports streaming for large datasets and provides a flexible template engine.

Features

  • Multi-format Support: PDF, Excel (xlsx/xls), Word (docx), CSV, HTML
  • Multiple PDF Drivers: DomPDF, TCPDF, mPDF
  • High Performance: Streaming and chunked processing for large files
  • Memory Efficient: Generator-based lazy loading
  • Template Engine: Simple yet powerful templating with loops, conditionals, and filters
  • Clean API: Fluent interface with intuitive methods
  • ORM Integration: Exportable/Importable traits for models
  • Queue Support: Background processing for large exports
  • Zero Config: Works out of the box with sensible defaults

Installation

composer require toporia/docura

Optional Dependencies

Install based on your needs:

# For PDF export (choose one)
composer require dompdf/dompdf        # Recommended for simple HTML to PDF
composer require tecnickcom/tcpdf     # For complex layouts
composer require mpdf/mpdf            # For CJK characters and advanced features

# For Excel export/import
composer require phpoffice/phpspreadsheet

# For Word export/import
composer require phpoffice/phpword

Quick Start

Export Data

use function Toporia\Docura\docura;

// Export to Excel
$path = docura()->export($data, 'xlsx');

// Export to PDF
$path = docura()->export($data, 'pdf', ['title' => 'My Report']);

// Export to CSV
$path = docura()->export($data, 'csv');

// Export to Word
$path = docura()->export($data, 'docx');

Download Export

// Direct download to browser
docura()->download($data, 'report.xlsx', 'xlsx');
docura()->download($data, 'invoice.pdf', 'pdf');

Import Data

// Import from Excel
$data = docura()->import('path/to/file.xlsx');

// Import from CSV
$data = docura()->import('path/to/file.csv');

// Import with chunking for large files
foreach (docura()->importChunked('large-file.xlsx', null, 1000) as $chunk) {
    // Process 1000 rows at a time
    processChunk($chunk);
}

// Lazy import (one row at a time)
foreach (docura()->importLazy('huge-file.csv') as $row) {
    // Process each row
}

Helper Functions

// Export helpers
export_pdf($data, ['title' => 'Report']);
export_excel($data);
export_csv($data);
export_word($data);

// Import helpers
$data = import_excel('file.xlsx');
$data = import_csv('file.csv');

// Download helpers
download_pdf($data, 'report.pdf');
download_excel($data, 'data.xlsx');
download_csv($data, 'export.csv');

Specialized Exporters

PDF Export

$path = docura()->pdf()
    ->template('invoice')
    ->paper('A4', 'portrait')
    ->margins(10, 10, 10, 10)
    ->export($data);

// Using different drivers
$path = docura()->pdf()
    ->using('mpdf')  // or 'dompdf', 'tcpdf'
    ->export($data);

Excel Export

$path = docura()->excel()
    ->withHeaders(['Name', 'Email', 'Amount'])
    ->columnWidths([30, 50, 15])
    ->headerStyles(['bold' => true, 'background' => 'F0F0F0'])
    ->export($data);

// With row callback
$path = docura()->excel()
    ->eachRow(function ($row, $index) {
        $row['amount'] = '$' . number_format($row['amount'], 2);
        return $row;
    })
    ->export($data);

// Streaming for large datasets
$generator = function () {
    for ($i = 0; $i < 1000000; $i++) {
        yield ['id' => $i, 'name' => "Item {$i}"];
    }
};

$path = docura()->excel()->stream($generator(), 'large-export.xlsx');

Word Export

$path = docura()->word()
    ->format('docx')  // or 'odt', 'rtf', 'html'
    ->export($data, [
        'title' => 'My Document',
        'description' => 'Generated by Docura',
    ]);

Template Engine

Create templates in resources/docura/templates/:

<!-- invoice.html -->
<!DOCTYPE html>
<html>
<head>
    <title>{{ title }}</title>
    <style>
        /* Your styles */
    </style>
</head>
<body>
    <h1>{{ company.name }}</h1>
    <p>Invoice #{{ invoice.number }}</p>

    <table>
        <thead>
            <tr>
                <th>#</th>
                <th>Item</th>
                <th>Price</th>
            </tr>
        </thead>
        <tbody>
            @foreach items as item
            <tr>
                <td>{{ loop.iteration }}</td>
                <td>{{ item.name }}</td>
                <td>{{ item.price|currency }}</td>
            </tr>
            @endforeach
        </tbody>
    </table>

    @if notes
    <div class="notes">
        <h3>Notes</h3>
        <p>{{ notes }}</p>
    </div>
    @endif

    <div class="footer">
        Generated on {{ date|datetime }}
    </div>
</body>
</html>

Use the template:

$path = docura()->pdf()
    ->template('invoice')
    ->export([
        'title' => 'Invoice',
        'company' => ['name' => 'Acme Inc'],
        'invoice' => ['number' => 'INV-001'],
        'items' => [
            ['name' => 'Product A', 'price' => 99.99],
            ['name' => 'Product B', 'price' => 149.99],
        ],
        'notes' => 'Thank you for your business!',
        'date' => new DateTime(),
    ]);

Template Features

Variables:

{{ variable }}
{{ object.property }}
{{ array.key }}

Filters:

{{ name|upper }}
{{ name|lower }}
{{ text|escape }}
{{ amount|currency }}
{{ amount|number }}
{{ date|date }}
{{ date|datetime }}
{{ html|nl2br }}
{{ items|count }}

Loops:

@foreach items as item
    {{ item.name }} - {{ loop.iteration }} of {{ loop.count }}
    @if loop.first
        (First item)
    @endif
@endforeach

Conditionals:

@if active
    Active
@elseif pending
    Pending
@else
    Inactive
@endif

@if count > 10
    Many items
@endif

@if !disabled
    Enabled
@endif

Includes:

@include('partials/header')
@include('partials/footer', ['year' => 2024])

ORM Integration

Exportable Trait

use Toporia\Docura\Concerns\Exportable;

class User extends Model
{
    use Exportable;

    protected static array $fillable = ['name', 'email', 'created_at'];
}

// Usage
$users = User::where('active', true)->get();
$path = $users->toExcel();
$users->downloadAsPdf('users.pdf');

Importable Trait

use Toporia\Docura\Concerns\Importable;

class Product extends Model
{
    use Importable;

    protected static function getImportColumnMap(): array
    {
        return [
            'Product Name' => 'name',
            'SKU' => 'sku',
            'Price' => 'price',
        ];
    }
}

// Usage
$products = Product::importFromExcel('products.xlsx');

// With chunking for large files
Product::importChunked('huge-file.xlsx', 1000, function ($models, $total) {
    echo "Imported {$total} products so far\n";
});

Console Commands

# Export data
php console docura:export data.json output.xlsx --format=xlsx
php console docura:export data.json output.pdf --format=pdf --title="My Report"

# Import data
php console docura:import file.xlsx --output=json
php console docura:import file.csv --output=table --limit=10

# Manage templates
php console docura:template create invoice --type=pdf
php console docura:template list
php console docura:template preview invoice --data='{"title":"Test"}'

Configuration

Publish the configuration:

php console vendor:publish --tag=docura-config

Configuration options (config/docura.php):

return [
    'pdf_driver' => env('DOCURA_PDF_DRIVER', 'dompdf'),
    'excel_driver' => env('DOCURA_EXCEL_DRIVER', 'phpspreadsheet'),

    'storage' => [
        'temp_path' => 'storage/docura/temp',
        'export_path' => 'storage/docura/exports',
        'import_path' => 'storage/docura/imports',
        'template_path' => 'resources/docura/templates',
    ],

    'pdf' => [
        'default_paper_size' => 'A4',
        'default_orientation' => 'portrait',
        'default_font' => 'DejaVu Sans',
        'enable_remote_images' => true,
    ],

    'excel' => [
        'default_format' => 'xlsx',
        'chunk_size' => 1000,
        'use_streaming' => true,
    ],

    'performance' => [
        'chunk_size' => 1000,
        'memory_limit' => '512M',
        'use_queue' => false,
    ],
];

Advanced Usage

Validation Before Import

$errors = docura()->validateImport('file.xlsx', null, [
    'email' => 'required|email',
    'amount' => 'required|numeric|min:0',
]);

if (empty($errors)) {
    $data = docura()->import('file.xlsx');
}

Process Each Row

docura()->each('large-file.csv', function ($row, $index) {
    // Process each row
    User::create($row);
}, 'csv');

Get File Headers

$headers = docura()->headers('file.xlsx');
// ['Name', 'Email', 'Phone', ...]

Check Driver Availability

$drivers = docura()->getAvailableDrivers();
// ['dompdf' => true, 'tcpdf' => false, 'mpdf' => true, ...]

if (docura()->isDriverAvailable('mpdf')) {
    // Use mPDF
}

Performance Tips

  1. Use streaming for large exports: Instead of loading all data into memory, use generators.

  2. Import in chunks: Process large files in batches to avoid memory issues.

  3. Use native CSV driver: For CSV files, the native driver is faster than PhpSpreadsheet.

  4. Enable caching: Template caching reduces parsing overhead.

  5. Choose the right PDF driver:

    • DomPDF: Simple HTML, fast
    • TCPDF: Complex layouts, Asian fonts
    • mPDF: Best CSS support, CJK characters

API Reference

DocuraManager

Method Description
export($data, $format, $options) Export data to file
download($data, $filename, $format, $options) Download export directly
store($data, $path, $format, $options) Save export to specific path
stream($generator, $path, $format, $options) Stream large exports
raw($data, $format, $options) Get raw export content
import($path, $format, $options) Import data from file
importChunked($path, $format, $chunkSize, $options) Import in chunks
importLazy($path, $format, $options) Import lazily (generator)
each($path, $callback, $format, $options) Process each row
headers($path, $format, $options) Get file headers
validateImport($path, $format, $rules, $options) Validate before import
pdf() Get PDF exporter
excel() Get Excel exporter
csv() Get CSV exporter
word() Get Word exporter
template($name) Set template for export

License

MIT License. See LICENSE for details.

Credits

Developed by TMP DEV for the Toporia Framework.