orkestra/pdf-bundle

提供 Symphony 和 PDF 生成库之间的集成

安装次数: 1,500

依赖者: 1

建议者: 0

安全性: 0

星标: 2

关注者: 5

分支: 2

开放性问题: 1

类型:symfony-bundle

0.9.2 2013-10-08 21:25 UTC

This package is not auto-updated.

Last update: 2024-09-11 10:22:55 UTC


README

Build Status

抽象不同的 PDF 生成库。目前支持 TCPDF、Zend PDF 和 wkhtmltopdf。

此组件处于积极开发中,容易出现向后兼容性中断。

安装

使用 composer,在项目的根目录下

composer require "orkestra/pdf-bundle 1.0.x-dev"

更新 AppKernel。

// app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        // ...
        new Orkestra\Bundle\PdfBundle\OrkestraPdfBundle(),
        // ...
    );
}

此外,根据需要,您应将 TCPDFZend PDF 添加到您的项目中。

如果计划使用 wkhtmltopdf,请确保它已安装到您的系统上。

配置

除非您想更改默认设置,否则无需配置。

配置默认值参考

# config.yml
orkestra_pdf:

  # Main cache directory
  cache_dir:  %kernel.cache_dir%/orkestra_pdf

  tcpdf:
    # Path to the tcpdf installation
    root_dir:   %kernel.root_dir%/../vendor/tecnick.com/tcpdf

    # Path to tcpdf fonts
    fonts_dir:  %kernel.root_dir%/../vendor/tecnick.com/tcpdf/fonts

    # Path to tcpdf images
    image_dir:  %kernel.root_dir%/../vendor/tecnick.com/tcpdf/images

  wkhtmltopdf:
    # Path to the wkhtmltopdf binary
    binary_path:  wkhtmltopdf

使用

此组件的目标是提供一个统一的 API,用于使用不同的生成工具生成 PDF。

目前支持:TCPDF、Zend PDF 和 wkhtmltopdf。

生成器

此组件的基础是称为 "生成器" 的服务。生成器知道如何获取某些输入,例如实体和其他数据,并返回一个可用于发送到浏览器、保存到文件系统等的 PDF。

所有生成器都应实现 PdfGeneratorInterface。此外,还包括一个名为 AbstractPdfGenerator 的基类。本文档详细说明了如何扩展 AbstractPdfGenerator

创建发票生成器

要实现的主要方法是:doGeneratesetDefaultParameters

实现 doGenerate 方法

此方法实际上执行 PDF 生成。它接受两个参数,$parameters$options

  • $parameters 是发送到模板引擎的数据数组。
  • $options 是传递给底层 PDF 库的选项数组。
实现 setDefaultParameters 方法

此方法配置一个 OptionsResolver,并允许指定生成器支持的必需和可用参数。

注意:还有一个 setDefaultOptions 方法。参数旨在传递给模板引擎,例如实体和集合。选项旨在允许在运行时配置生成器。

示例实现:InvoiceGenerator

在此示例中,我们使用 WkPdf 适配器和内置模板引擎来渲染 PDF。

<?php

namespace MyBundle\PdfGenerator;

use Orkestra\Bundle\PdfBundle\Generator\AbstractPdfGenerator;
use Symfony\Component\OptionsResolver\OptionsResolver;

class InvoiceGenerator extends AbstractPdfGenerator
{
    /**
     * Performs the PDF generation
     *
     * @param array $parameters An array of parameters to be used to render the PDF
     * @param array $options    An array of options to be passed to the underlying PdfFactory
     *
     * @return \Orkestra\Bundle\PdfBundle\Pdf\PdfInterface
     */
    protected function doGenerate(array $parameters, array $options)
    {
        // Use the createPdf method to create the desired type of PDF
        $pdf = $this->createPdf('wkpdf', $options);

        // Call any native methods on the underlying library object
        $builder = $pdf->getNativeObject();
        $builder->useTemporaryFile();
        $builder->setInput($this->render('MyBundle:Pdf/Invoice:template.html.twig', $parameters));

        // Return the original PDF, calling getContents to retrieve the rendered content
        return $pdf;
    }

    /**
     * Configure the parameters OptionsResolver.
     *
     * Use this method to specify default and required options
     *
     * @param \Symfony\Component\OptionsResolver\OptionsResolver $resolver
     */
    protected function setDefaultParameters(OptionsResolver $resolver)
    {
        $resolver->setRequired(array(
            'invoice',
        ));
        $resolver->setAllowedTypes(array(
            'invoice' => 'MyBundle\Entity\Invoice',
        ));
    }
}
有用的方法

AbstractPdfGenerator->createPdf($type, $options) 包装 PDF 工厂注册表。作为第一个参数,传递 PDF 类型及其配置选项。支持的 PDF 类型:tcpdfwkpdfzendpdf

AbstractPdfGenerator->render($template, array $parameters = array()) 使用应用程序的模板引擎来渲染模板,用于生成 PDF 的内容。

注册您的生成器

在 services.yml 中

my_bundle.invoice_pdf_generator:
  class: MyBundle\PdfGenerator\InvoiceGenerator
  arguments: [ @orkestra.pdf.factory_registry, @templating ]

AbstractPdfGenerator 默认情况下,接受一个 PDF 工厂注册表和模板服务。您可能需要根据您的实现添加更多依赖项。

使用您的服务

从您的一个控制器中

class MyController extends Controller
{
    // ...
    public function someAction()
    {
        // Fetch the invoice from somewhere
        $invoice = $this->getInvoice();

        $generator = $this->get('my_bundle.invoice_pdf_generator');

        $pdf = $generator->generate(array('invoice' => $invoice));

        // Write the PDF to a file
        file_put_contents('/some/path/to.pdf', $pdf->getContents());

        // Output the PDF to the browser
        return new Response($pdf->getContents(), 200, array('Content-type' => 'application/pdf'));
    }
}

策略

使用 TCPDF 渲染模板片段

TCPDF 使用起来可能比较困难,尤其是在渲染 HTML 时。通常,最简单的方法是将页面上的不同较小部分定位到一起,在 TCPDF 对象上多次调用 writeHTMLwriteHTMLCell

这里是一个之前发票生成器的例子。

class InvoiceGenerator extends AbstractPdfGenerator
{
    protected function doGenerate(array $parameters, array $options)
    {
        $pdf = $this->createPdf('tcpdf', $options);

        /** @var \TCPDF $builder */
        $builder = $pdf->getNativeObject();

        $builder->addPage();

        $builder->writeHtmlCell(0, 0, 0, 20, $this->render('MyBundle:Pdf/Invoice:invoiceHead.html.twig', $parameters));
        $builder->writeHtmlCell(0, 0, 20, 43, $this->render('MyBundle:Pdf/Invoice:invoiceIntro.html.twig', $parameters));
        $builder->writeHtmlCell(0, 0, 20, 66, $this->render('MyBundle:Pdf/Invoice:invoiceBody.html.twig', $parameters));
        $builder->writeHtmlCell(0, 0, 20, 165, $this->render('MyBundle:Pdf/Invoice:invoiceFooter.html.twig', $parameters));

        $builder->line(0, 190.5, 215.9, 190.5, array('dash' => 3));

        $builder->writeHtmlCell(0, 0, 21, 200, $this->render('MyBundle:Pdf/Invoice/Detachment:detachmentCompany.html.twig', $parameters));
        $builder->writeHtmlCell(0, 0, 0, 200, $this->render('MyBundle:Pdf/Invoice/Detachment:detachmentHead.html.twig', $parameters));
        $builder->writeHtmlCell(0, 0, 19.5, 230, $this->render('MyBundle:Pdf/Invoice/Detachment:detachmentInfo.html.twig', $parameters));
        $builder->writeHtmlCell(0, 0, 22, 210, $this->render('MyBundle:Pdf/Invoice/Detachment:detachmentDetails.html.twig', $parameters));

        return $pdf;
    }
}

有关更多详情,请参阅TCPDF文档。

使用TCPDF的自定义子类

TCPDF提供了直接扩展TCPDF类的能力,例如实现页面页眉和页脚。

默认的TcPdfFactory允许你在创建PDF时通过指定'className'选项来指定自定义子类。例如

class MySpecialGenerator extends AbstractPdfGenerator
{
    protected function doGenerate(array $parameters, array $options)
    {
        $options['className'] = 'My\Bundle\CustomTcpdf';
        $pdf = $this->createPdf('tcpdf', $options);

        /** @var \My\Bundle\CustomTcpdf $builder */
        $builder = $pdf->getNativeObject();

        // Use your custom subclass as necessary...

        return $pdf;
    }
}

注意上面例子中的$builder是一个My\Bundle\CustomTcpdf的实例。