To save the PDF or Screenshot as a file, you need a Daif\ChromePdfBundle\Processor\ProcessorInterface.
Given an example for a PDF (works the same for Screenshots):
use Daif\ChromePdfBundle\ChromePdfInterface;
use Daif\ChromePdfBundle\Builder\Result\ChromePdfFileResult;
/** [@var](https://github.com/var) ChromePdfInterface $chromePdf */
$chromePdf = /* ... */;
/** [@var](https://github.com/var) ChromePdfFileResult $result */
$result = $chromePdf->html()
// ...
->fileName('my_pdf')
->processor(/* ... */)
->generate()
;
// Either process it with
$result->process(); // return type depends on the Processor used (see below)
// or send a response to the browser:
$result->stream(); // returns a Symfony\Component\HttpFoundation\StreamedResponse
Here is the list of existing Processors:
Daif\ChromePdfBundle\Processor\FileProcessorUseful if you want to store the file in the local filesystem.
use Daif\ChromePdfBundle\ChromePdfInterface;
use Daif\ChromePdfBundle\Processor\FileProcessor;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\Response;
#[Route(path: '/my-pdf', name: 'my_pdf')]
public function pdf(
ChromePdfInterface $chromePdf,
Filesystem $filesystem,
#[Autowire('%kernel.project_dir%/var/pdf')]
string $pdfStorage,
): Response {
return $chromePdf->html()
// ...
->fileName('my_pdf')
->processor(new FileProcessor(
$filesystem,
$pdfStorage,
))
->generate()
->stream()
;
}
This will save the file under %kernel.project_dir%/var/pdf/my_pdf.pdf once the file has been fully streamed to the browser.
use Daif\ChromePdfBundle\ChromePdfInterface;
use Daif\ChromePdfBundle\Processor\FileProcessor;
use Symfony\Component\Filesystem\Filesystem;
class SomeService
{
public function __construct(
private readonly ChromePdfInterface $chromePdf,
#[Autowire('%kernel.project_dir%/var/pdf')]
private readonly string $pdfStorage,
) {}
public function pdf(): \SplFileInfo
{
return $this->chromePdf->html()
//
->fileName('my_pdf')
->processor(new FileProcessor(
new Filesystem(),
$this->pdfStorage,
))
->generate()
->process()
;
}
}
This will return a SplFileInfo of the generated file stored at %kernel.project_dir%/var/pdf/my_pdf.pdf.
Daif\ChromePdfBundle\Processor\NullProcessorEmpty processor. Does nothing. Returns null.
Daif\ChromePdfBundle\Processor\TempfileProcessorCreates a temporary file and dumps all chunks into it. Returns a resource of said tmpfile().
use Daif\ChromePdfBundle\ChromePdfInterface;
use Daif\ChromePdfBundle\Processor\TempfileProcessor;
class SomeService
{
public function __construct(
private readonly ChromePdfInterface $chromePdf,
) {}
/**
* [@return](https://github.com/return) resource
*/
public function pdf(): mixed
{
return $this->chromePdf->html()
//
->fileName('my_pdf')
->processor(new TempfileProcessor())
->generate()
->process()
;
}
}
Daif\ChromePdfBundle\Processor\ChainProcessorApply multiple processors. Each chunk will be sent to each processor sequentially. Returns an array of values returned by chained processors.
use Daif\ChromePdfBundle\ChromePdfInterface;
use Daif\ChromePdfBundle\Processor\ChainProcessor;
use Daif\ChromePdfBundle\Processor\FileProcessor;
use Daif\ChromePdfBundle\Processor\ProcessorInterface;
use Symfony\Component\Filesystem\Filesystem;
/**
* [@implements](https://github.com/implements) ProcessorInterface<int>
*/
class CustomProcessor implements ProcessorInterface
{
public function __invoke(string|null $fileName): \Generator { /* ... */ }
}
class SomeService
{
public function __construct(
private readonly ChromePdfInterface $chromePdf,
#[Autowire('%kernel.project_dir%/var/pdf')]
private readonly string $pdfStorage,
) {}
/**
* [@return](https://github.com/return) array{0: \SplFileInfo, 1: int}
*/
public function pdf(): array
{
return $this->chromePdf->html()
//
->fileName('my_pdf')
->processor(new ChainProcessor([
new FileProcessor(
new Filesystem(),
$this->pdfStorage,
),
new CustomProcessor(),
]))
->generate()
->process()
;
}
}
Daif\ChromePdfBundle\Bridge\LeagueFlysystem\Processor\FlysystemProcessorUpload using the league/flysystem-bundle package. Returns a callable. This callable will return the uploaded content.
use League\Flysystem\FilesystemOperator;
use Daif\ChromePdfBundle\ChromePdfInterface;
use Daif\ChromePdfBundle\Bridge\LeagueFlysystem\Processor\FlysystemProcessor;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
class SomeService
{
public function __construct(
private readonly ChromePdfInterface $chromePdf,
#[Autowire(service: 'pdfs.storage')]
private readonly FilesystemOperator $filesystemOperator,
) {}
/**
* [@return](https://github.com/return) Closure(): string
*/
public function pdf(): Closure
{
return $this->chromePdf->html()
//
->fileName('my_pdf')
->processor(new FlysystemProcessor(
$this->filesystemOperator,
))
->generate()
->process()
;
}
}
Daif\ChromePdfBundle\Bridge\AsyncAws\Processor\AsyncAwsS3MultiPartProcessorUpload using the async-aws/s3 package. Uploads using the multipart upload feature of S3. Returns a AsyncAws\S3\Result\CompleteMultipartUploadOutput object.
use AsyncAws\S3\Result\CompleteMultipartUploadOutput;
use Daif\ChromePdfBundle\Bridge\AsyncAws\Processor\AsyncAwsS3MultiPartProcessor;
use Daif\ChromePdfBundle\ChromePdfInterface;
class SomeService
{
public function __construct(
private readonly ChromePdfInterface $chromePdf,
private readonly S3Client $s3Client,
) {}
public function pdf(): CompleteMultipartUploadOutput
{
return $this->chromePdf->html()
//
->fileName('my_pdf')
->processor(new AsyncAwsS3MultiPartProcessor(
$this->s3Client,
'bucket-name',
))
->generate()
->process()
;
}
}
Daif\ChromePdfBundle\Processor\InMemoryProcessorLoads the full PDF in memory. Should NOT be used in production. This is not memory safe and you might end up with a "Fatal Error: Allowed Memory Size". Consider using one of the other Processors.
use Daif\ChromePdfBundle\ChromePdfInterface;
use Daif\ChromePdfBundle\Processor\InMemoryProcessor;
class SomeService
{
public function __construct(
private readonly ChromePdfInterface $chromePdf,
) {}
public function pdf(): string
{
return $this->chromePdf->html()
//
->fileName('my_pdf')
->processor(new InMemoryProcessor())
->generate()
->process()
;
}
}
A custom processor must implement Daif\ChromePdfBundle\Processor\ProcessorInterface which requires that your __invoke method is a \Generator. To receive a chunk you must assign yield to a variable like so: $chunk = yield.
The basic needed code is the following:
use Daif\ChromePdfBundle\Processor\ProcessorInterface;
/**
* [@implements](https://github.com/implements) ProcessorInterface<YOUR_GENERATOR_RETURN_TYPE>
*/
class CustomProcessor implements ProcessorInterface
{
public function __invoke(string|null $fileName): \Generator
{
do {
$chunk = yield;
// do something with it
} while (!$chunk->isLast());
// rest of your code
}
}
How can I help you explore Laravel packages today?