ambengers/eloquent-word

Laravel package for creating Word documents with Eloquent ORM dependencies.

5.0 2023-10-27 23:18 UTC

This package is auto-updated.

Last update: 2024-04-28 00:21:48 UTC


README

This package provides an elegant way to generate Word documents with Eloquent Models. Uses PHPOffice/PHPWord package to generate Word documents and Laravel Medialibrary to associate Word documents as eloquent model media.

CircleCI StyleCI

Spatie Media Library Version Compatibility

Version Medialibrary
v1.* ~ 7.20
v2.* ^ 8.0
v3.* ^ 9.0
v4.* ^ 10.0
v5.* ^ 10.0

Installation

Via Composer

$ composer require ambengers/eloquent-word

Optionally, you can publish the config file by running the following command.

php artisan vendor:publish --tag=eloquent-word-config

Usage

Eloquent Word class

You can generate your Eloquent Word class using the command

$ php artisan make:eloquent-word PostWord

Optionally, you can pass a --view option to also generate a view template file.

$ php artisan make:eloquent-word PostWord --view=posts.word

By default, the class will be located at App\Word namespace. You can customize this in the config file.

Your Eloquent Word class will contain 2 methods:

  • getData() provides the data to be used on the view
  • getView() the name of the view file as word template
namespace App\Word;

use Ambengers\EloquentWord\AbstractEloquentWord;

class PostWord extends AbstractEloquentWord
{
    public function getData() : array
    {
        return [
            'title' => $this->model->title,
            'body'  => $this->model->body,
        ];
    }

    public function getView() : string
    {
        return 'posts.word';
    }
}

View Template

Unlike PDF templates that uses html, Word templates are created using php scripts. So in your view template file, you can utilize the @php blade tags like so...

@php
// You automatically have access to $word within your view template,
// which is an instance of \PhpOffice\PhpWord\PhpWord::class...
$section = $word->addSection();

$section->addTitle($title);

$section->addTextBreak();

$section->addText($body);
@endphp

Within your view template, you automatically have access to $word variable which will give you an instance of PhpOffice\PhpWord\PhpWord class. This will allow you to get started formatting your Word document.

You can learn more by visiting the PHPWord official documentation.

You can now use the Eloquent Word class from your controller (or anywhere in your application).

Downloading Word

return app(PostWord::class)
    ->model($post)
    ->handle();

Eloquent Word with Medialibrary

This package also offers an elegant way to associate Word document to the Eloquent Model using Medialibrary package. To do that, you will need to use a trait on your Eloquent Word class.

use Ambengers\EloquentWord\InteractsWithMediaLibrary;

class PostWord extends AbstractEloquentWord
{
    use InteractsWithMediaLibrary;
}

Then on your controller, much like how you would do with medialibrary, just provide the collection name in which the Word document will be associated with.

return app(PostWord::class)
    ->model($post)
    ->toMediaCollection('reports')
    ->handle();

For additional convenience you can also chain other medialibrary methods.

return app(PostWord::class)
    ->model($post)
    ->toMediaCollection('reports')
    ->withCustomProperties(['foo' => 'bar'])
    ->withAttributes(['creator_id' => auth()->id()])
    ->handle();

Behind the scenes, Eloquent Word will forward these method calls to the medialibrary FileAdder::class so you can further take advantage of its features.

Customizations

If you need to customize the default filename or extension, you can chain some setter methods when you call your Eloquent Word class.

return app(PostWord::class)
    ->model($post)
    ->filename('some-cool-filename')
    ->extension('odt')
    ->toMediaCollection('reports')
    ->handle();

Security

If you discover any security related issues, please send the author an email instead of using the issue tracker.

License

Please see the license file for more information.