Создание pdf в Laravel 10+. Новый пакет laravel-pdf от Spatie.

Создание pdf в Laravel 10+. Новый пакет laravel-pdf от Spatie.

Генерация PDF файлов на Laravel 10 в 2024 году

Был выпущен новый пакет под названием spatie/laravel-pdf , пакет для создания PDF-файлов в приложениях Laravel. Внутри он использует Chromium для создания PDF-файлов из представлений Blade. Вы можете использовать современные функции CSS, такие как grid, flexbox и даже такие ui-фрейморки, как Tailwind, для создания красивых PDF-файлов.

В этом посте я хотел бы представить и продемонстрировать пакет.

Создание PDF файла

После установки пакета вы можете использовать PDFфасад для создания PDF-файлов. Основой для создания PDF-файлов является HTML, а самый простой способ создания HTML в приложении Laravel — использовать представление.

Вот пример создания PDF-файла из представления Blade.

use Spatie\LaravelPdf\Facades\Pdf; 
Pdf::view('pdf.invoice')->save('/some/directory/invoice.pdf');

Под капотом пакет через Browsershot запустит экземпляр Chrome, загрузит ваш HTML и позволит Chrome сохранить PDF-файл. Поскольку Chrome имеет современный механизм рендеринга, вы сможете использовать современные функции CSS для создания PDF-файла.

В качестве второго параметра вы можете передать массив данных, которые будут доступны в представлении. Вы можете использовать это для передачи модели Eloquent, например счета, в представление.

use Spatie\LaravelPdf\Facades\Pdf;
Pdf::view('pdf.invoice', ['invoice' => $invoice])->save('/some/directory/invoice.pdf');

Помимо локального сохранения, вы можете сохранить PDF-файл на любом из настроенных вами дисков .

Вот пример сохранения PDF-файла на s3диск.

use Spatie\LaravelPdf\Facades\Pdf; 
Pdf::view('invoice')->disk('s3')->save('invoice-april-2022.pdf');

Вместо использования представления Blade вы также можете создать PDF-файл из строки HTML.

use Spatie\LaravelPdf\Facades\Pdf; 
Pdf::html('<h1>Hello world!!</h1>')->save('/some/directory/invoice.pdf');

Ответ с помощью PDF файла в Laravel

В контроллере вы можете создать и вернуть PDF-файл, используя эту pdf()функцию.

use function Spatie\LaravelPdf\Support\pdf; 
class DownloadInvoiceController 
{ 
 public function __invoke(Invoice $invoice) 
 { 
    return pdf()->view('pdf.invoice', compact('invoice'))->name('invoice-2023-04-10.pdf'); 
 } 
}

По умолчанию PDF-файл будет встроен в браузер. Это означает, что PDF-файл будет отображаться в браузере, если браузер его поддерживает. Если пользователь попытается загрузить PDF-файл, он будет называться «invoice-2023-04-10.pdf». Мы рекомендуем всегда давать PDF-файлам имя.

Вы можете использовать этот download()метод для принудительной загрузки PDF-файла.

use function Spatie\LaravelPdf\Support\pdf; 
class DownloadInvoiceController 
{ 
 public function __invoke(Invoice $invoice) 
 {
  return pdf()->view('pdf.invoice', compact('invoice'))->name('invoice-2023-04-10.pdf')->download(); 
 } 
}

Использование JavaScript в PDF файлах на Laravel

JavaScript в вашем HTML будет выполняться Chrome при создании PDF-файла. Вы можете использовать это, чтобы библиотека диаграмм JavaScript отображала диаграмму.

Вот простой пример. Если у вас есть этот вид Блэйда…

<div id="target"></div> 
<script> document.getElementById('target').innerHTML = 'hello'; </script>

… и визуализируем его с помощью этого кода…

use Spatie\LaravelPdf\Facades\Pdf; 
Pdf::view('your-view')->save($pathToPdf);

… текст helloбудет виден в PDF.

Тестирование PDF файлов

Создание PDF-файла может быть медленным, поскольку необходимо запустить весь экземпляр Chrome. В ваших тестах эта медлительность может раздражать. Вот почему в комплект поставки входит подделка в формате PDF. При использовании этой подделки не будет генерироваться PDF-файл, и ваши тесты будут выполняться быстрее.

// in your test 
use Spatie\LaravelPdf\Facades\Pdf; 
beforeEach(function () { Pdf::fake(); });

Если генерация PDF-файла подделана, вы можете использовать некоторые мощные методы проверки.

Вы можете использовать этот assertSavedметод, чтобы подтвердить, что PDF-файл был сохранен с определенными свойствами. Вы должны передать ему вызываемый объект, который получит экземпляр Spatie\LaravelPdf\PdfBuilder. Если вызываемый объект возвращает true, утверждение пройдет.

use Spatie\LaravelPdf\Facades\Pdf; 
use Spatie\LaravelPdf\PdfBuilder; 
Pdf::assertSaved(function (PdfBuilder $pdf) { 
 return $pdf->downloadName === 'invoice.pdf' && str_contains($pdf->html, 'Your total for April is $10.00')); 
});

Этот assertRespondedWithPdfметод можно использовать для подтверждения того, что PDF-файл был создан и возвращен в качестве ответа.

Представьте, что у вас есть этот маршрут:

use Spatie\LaravelPdf\Facades\Pdf; 
Route::get('download-invoice', function () { return pdf('pdf.invoice')->download('invoice-for-april-2022.pdf'); });

В тесте для этого маршрута вы можете использовать , assertRespondedWithPdfчтобы убедиться, что PDF-файл был создан и возвращен в качестве загрузки. Вы даже можете делать утверждения о содержании PDF-файла.

use Spatie\LaravelPdf\Facades\Pdf; 
use Spatie\LaravelPdf\PdfBuilder; 
it('can download an invoice', function () { 
 $this->get('download-invoice')->assertOk(); 
 Pdf::assertRespondedWithPdf(function (PdfBuilder $pdf) { 
  return $pdf->downloadName === 'invoice-for-april-2022.pdf' && $pdf->isDownload() && str_contains($pdf->html, 'Your total for April is $10.00')); 
 }); 
});

Создание PDF файлов на AWS Lambda

Локальное создание PDF-файлов может оказаться ресурсоемким. Если вам необходимо создать много PDF-файлов или у вас возникли проблемы с установкой необходимых зависимостей на вашем сервере, вы можете рассмотреть возможность использования AWS Lambda для создания PDF-файлов.

Чтобы создавать PDF-файлы в AWS Lambda, вам необходимо установить эти два пакета в свое приложение.

  • Hammerstone/sidecar : это позволяет вам выполнять функции AWS Lambda из вашего приложения Laravel.
  • wnx/sidecar-browsershot : этот пакет содержит версию Browsershot, которую можно запустить на AWS Lambda через Sidecar.

Установив эти два пакета, вы можете создавать PDF-файлы на AWS Lambda следующим образом:

Pdf::view('pdf.invoice', $data)->generateOnLambda()->save('invoice.pdf');

Если вы хотите создавать все PDF-файлы в своем приложении на Lambda, вы можете установить его по умолчанию следующим образом:

// typically, in a service provider 
Pdf::default()->generateOnLambda();
Никита Ив
Никита Ив

Меня зовут Никита, я являюсь автором этой статьи. Занимаюсь веб-разработкой более 5-ти лет на стеке Laravel + Vue. Делюсь своим опытом, шишками и головной болью. Пишу полезные статьи, такие как эта. Подписывайтесь на наш телеграм канал, чтобы узнавать о появлении новых статей первыми, либо подпишитесь на рассылку, оставив почту в нашем боте ниже.

Другие записи по теме: Блог