zend_pdf组件源码_使用Zend_Pdf生成发票

zend_pdf组件源码

The PDF format is currently the most used format to exchange documents. If you provide your website users with printable versions of invoices, event tickets and other similar documents, you’ll most likely want to generate them as PDFs on the fly. In this article you will see how you can use Zend_Pdf to auto-generate PDF invoices.

PDF格式是当前最常用的文档交换格式。 如果您为网站用户提供发票,活动票和其他类似文档的可打印版本,则您很可能希望即时将其生成为PDF。 在本文中,您将看到如何使用Zend_Pdf自动生成PDF发票。

入门 (Getting Started)

Zend_Pdf allows you to create new PDF documents or load existing ones and modify them. While creating a new document isn’t that difficult, it makes more sense to create a template of the invoice with the information that doesn’t change (company name, address, logo, etc.). It’s better to design your invoice in a program like Microsoft Word or LibreOffice Writer and export it as a PDF. Then you can update the PDF with Zend_Pdf with customer and transaction-specific information. You’ll save coding time because you don’t have to position every element, and it will take less time for the PDF to be generated.

Zend_Pdf允许您创建新的PDF文档或加载现有的PDF文档并进行修改。 尽管创建新文档并不难,但是使用不更改的信息(公司名称,地址,徽标等)创建发票模板更有意义。 最好在Microsoft Word或LibreOffice Writer之类的程序中设计发票并将其导出为PDF。 然后,您可以使用Zend_Pdf更新包含客户和交易特定信息的PDF。 因为不必定位每个元素,所以可以节省编码时间,并且生成PDF所需的时间更少。

This is what the invoice template I will be using in this article looks like. Your invoice can look different depending on your needs, but the concepts in this article will remain the same.

这就是我将在本文中使用的发票模板。 您的发票可能会根据您的需要而有所不同,但是本文中的概念将保持不变。

invoice template

If this is the first time you’re using Zend Framework, download the latest version from www.zendframework.com, upload and unpack the compressed file on your server, and use the following lines at the top of your script to configure the class autoloader. The autoloader will let you create new objects without having to explicitly include all the required files in your code.

如果这是您第一次使用Zend Framework,请从www.zendframework.com下载最新版本,将压缩文件上传并解压缩到服务器上,然后使用脚本顶部的以下几行来配置类自动加载器。 自动加载器使您可以创建新对象,而不必在代码中明确包含所有必需的文件。

<?php
define("ZF_PATH", realpath("/path/to/zf/library/"));
set_include_path(get_include_path() . PATH_SEPARATOR . ZF_PATH);
require_once "Zend/Loader/Autoloader.php";
$loader = Zend_Loader_Autoloader::getInstance();

Remember to change the value of the ZF_PATH constant to the path where you uploaded the copy of the Zend Framework library.

请记住,将ZF_PATH常量的值更改为上载Zend Framework库副本的路径。

Editor Note Oct 14 2012: The accompanying code on GitHub has been updated to use Composer for installing Zend Framework. As ZF2 is not backwards compatible with ZF1, the version has been locked at 1.11.11. Please refer to the code for suitable ZF_PATH.

编者注2012年10月14日: GitHub上的随附代码已更新为使用Composer来安装Zend Framework。 由于ZF2与ZF1不向后兼容,因此该版本已锁定为1.11.11。 请参考代码以获取合适的ZF_PATH。

加载PDF模板 (Loading the PDF Template)

Zend_Pdf allows you to load an existing PDF document with the static load() method.

Zend_Pdf允许您使用static load()方法加载现有的PDF文档。

<?php
// load the invoice
$invoice = Zend_Pdf::load("/path/to/invoice-template.pdf");

The load() method reads the file at the given path and returns an instance of a Zend_Pdf object which manages everything related to the PDF.

load()方法在给定路径下读取文件,并返回Zend_Pdf对象的实例,该对象管理与PDF相关的所有内容。

Zend_Pdf represents each page of the PDF as instances of the Zend_Pdf_Page object. Its public field pages is an array of the objects in the same order the pages are found in the document. You can benefit from this behavior if you have a PDF document with many pages and you want to reorder its pages; whichever order the Zend_Pdf_Page objects are in the pages array, that is the order the pages will be rendered in the final document.

Zend_Pdf将PDF的每个页面表示为Zend_Pdf_Page对象的实例。 它的公共字段pages是对象的数组,其顺序与在文档中找到页面的顺序相同。 如果您有一个包含许多页面的PDF文档,并且想要对其页面进行重新排序,则可以从这种行为中受益。 Zend_Pdf_Page对象在pages数组中的顺序,即页面在最终文档中的呈现顺序。

<?php
// access the first page
$page = $invoice->pages[0];

指定字体和颜色 (Specifying Fonts and Colors)

When you write text to the PDF page, you are actually drawing shapes that looks like text, and these shapes are defined by the chosen font. So before writing/drawing text, you must specify which font you want to use. The Zend_Pdf_Font class is used to create a font resource which you then use to specify the font used when placing text.

当您将文本写入PDF页面时,实际上是在绘制看起来像文本的形状,并且这些形状由所选字体定义。 因此,在编写/绘制文本之前,必须指定要使用的字体。 Zend_Pdf_Font类用于创建字体资源,然后您可以使用该字体资源指定放置文本时使用的字体。

There are two ways to load a font. The first is to use the static method fontWithName() and provide one of the following constants that represent the 14 standard fonts that all PDF viewers support:

有两种加载字体的方法。 第一种是使用静态方法fontWithName()并提供以下常量之一,这些常量代表所有PDF查看器都支持的14种标准字体:

  • Zend_Pdf_Font::FONT_COURIER (_BOLD, _ITALIC, _BOLD_ITALIC)

    Zend_Pdf_Font::FONT_COURIER ( _BOLD_ITALIC_BOLD_ITALIC )

  • Zend_Pdf_Font::FONT_HELVETICA (_BOLD, _ITALIC, _BOLD_ITALIC)

    Zend_Pdf_Font::FONT_HELVETICA ( _BOLD_ITALIC_BOLD_ITALIC )

  • Zend_Pdf_Font::FONT_TIMES (_BOLD, _ITALIC, _BOLD_ITALIC)

    Zend_Pdf_Font::FONT_TIMES ( _BOLD_ITALIC_BOLD_ITALIC )

  • Zend_Pdf_Font::FONT_SYMBOL

    Zend_Pdf_Font::FONT_SYMBOL

  • Zend_Pdf_Font::FONT_ZAPFDINGBATS

    Zend_Pdf_Font::FONT_ZAPFDINGBATS

The second way is to provide the path to the font file that resides on your file system to the static method fontWithPath(). Make sure that the font is a TrueType font or else fontWithPath() will throw a Zend_Pdf_Exception.

第二种方法是将驻留在文件系统上的字体文件的路径提供给静态方法fontWithPath() 。 确保字体是TrueType字体,否则fontWithPath()将抛出Zend_Pdf_Exception

<?php
//loading a font by its name
$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_TIMES_BOLD);

//load font from file system
$font = Zend_Pdf_Font::fontWithPath("/path/to/myfont.ttf");

The font resource is then passed to the Zend_Pdf_Page‘s setFont() instance method as the first parameter, and the font size measured in points as the second parameter (1 point = 1/72 inches). The represented font will then be used whenever text is drawn to that page.

然后,将字体资源传递给Zend_Pdf_PagesetFont()实例方法作为第一个参数,并以为单位作为第二个参数(1点= 1/72英寸)的字体大小。 每当将文本绘制到该页面时,就会使用所表示的字体。

<?php
$page->setFont($font, 12);

It’s not mandatory to set a color for text before drawing it; black will be used by default if none is specified. But if do you want to use a certain color, you can specify one with one of the Zend_Pdf_Color* objects. Zend_Pdf supports three different color spaces; you can use Gray Scale, RGB, or CMYK. Also, you can specify colors using HTML-style notation.

在绘制文本之前不必为文本设置颜色; 如果未指定,默认情况下将使用黑色。 但是,如果要使用某种颜色,则可以使用Zend_Pdf_Color*对象之一指定一种颜色。 Zend_Pdf支持三种不同的色彩空间。 您可以使用灰度,RGB或CMYK。 另外,您可以使用HTML样式符号指定颜色。

<?php
// Gray Scale colors range from 0.0 (black) to 1.0 (white)
$color = new Zend_Pdf_Color_GrayScale(0.7);

// RGB uses 3 float values from 0.0 to 1.0 for each color component
$color = new Zend_Pdf_Color_Rgb($r,$g,$b);

// CMYK uses 4 float values from 0.0 to 1.0 for each color component
$color = new Zend_Pdf_Color_Cmyk($c,$m,$y,$k);

// HTML uses any valid color name or hex notation
$color = new Zend_Pdf_Color_HTML("blue");
$color = new Zend_Pdf_Color_HTML("#FF52ED");

The color is then passed to the setFillColor() method of the Zend_Pdf_Page instance.

然后将颜色传递给Zend_Pdf_Page实例的setFillColor()方法。

<?php
$page->setFillColor($color)

添加内容 (Adding Content)

Drawing text on a page is done using Zend_Pdf_Page‘s drawText() instance method. It takes a string of text, and the X and Y coordinates where you want the text to be placed. The coordinates are measured in points, and the origin 0,0 is placed at the bottom-left corner of the page. An increasing X value moves the position towards the right, and an increasing Y value moves the position up.

使用Zend_Pdf_PagedrawText()实例方法在页面上绘制文本。 它需要一个字符串,并在X和Y坐标上放置文本。 坐标以点为单位,原点0,0放置在页面的左下角。 X值增加将位置向右移动,而Y值增加将位置向上移动。

PDF X,Y coords

Typically you’ll retrieve and calculate information to put on the invoice from a database, but for the sake of example I’ve come up with the following:

通常,您将从数据库中检索和计算要放入发票的信息,但是为了举例说明,我提出了以下内容:

<?php
$customerName = "Angelina Jolie";
$invoiceId = "DF-00025786423";

// items in the array are product description,
// quantity purchased, unit price, and total price
$items = array(array("Golden Globe Polish", 1, 25.50, 25.50),
               array("Trophy Shelf", 2, 180.00, 360.00),
               array("DIY Tattoo Kit", 1, 149.99, 149.99));

$subtotal = 535.49;
$discount = 10;
$amountDue = 481.94;

The trickiest part is finding the correct location to place the text on the page and you may require some trial and error even if you’ve meticulously measured your distances. The good news is that since the template elements are static, once you know what coordinates to use they won’t change.

最棘手的部分是找到将文本放置在页面上的正确位置,即使您仔细测量了距离,也可能需要反复试验。 好消息是,由于模板元素是静态的,因此一旦知道要使用的坐标,它们就不会改变。

<?php
// specify font
$fontBold = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_TIMES_BOLD);
$page->setFont($fontBold, 12);

// specify color
$color = new Zend_Pdf_Color_HTML("navy");
$page->setFillColor($color);

$page->drawText($customerName, 110,641);
// another font
$fontNormal = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_TIMES);
$page->setFont($fontNormal, 12);

// invoice information
$page->drawText($invoiceId, 420,642);
$page->drawText(date("M d, Y"), 420,628);
$page->drawText('$' . number_format($subtotal, 2), 510,143);
$page->drawText($discount . "%", 510,123);
$page->drawText('$' . number_format($amountDue, 2), 510,103);

// purchase items
$posY = 560;
foreach ($itmes as $item) {
    $page->drawText($item[0], 50, $posY);
    $page->drawText($item[1], 350, $posY);
    $page->drawText(number_format($item[2], 2), 430, $posY);
    $page->drawText(number_format($item[3], 2), 510, $posY);
    $posY -= 22.7;
}

呈现发票 (Rendering the Invoice)

After adding the information to the template, you can either save it to a different file (be careful not to overwrite your template!) or send it to the browser. To save it, you use Zend_Pdf‘s instance method save().

将信息添加到模板后,您可以将其保存到其他文件中(请注意不要覆盖您的模板!)或将其发送到浏览器。 要保存它,请使用Zend_Pdf的实例方法save()

<?php
$invoice->save($pathToFile);

Using the instance method render() will return the PDF document as a string. This is probably what you want if you are generating a document on the fly and want the user to download it without saving copy of the document on your server first. You can output the correct HTTP headers so the browser will know how to handle the file, and then send the document string.

使用实例方法render()将以字符串形式返回PDF文档。 如果您正在动态生成文档,并且希望用户下载文档而不先将文档的副本保存在服务器上,那么这可能就是您想要的。 您可以输出正确的HTTP标头,以便浏览器知道如何处理文件,然后发送文档字符串。

<?php
// instruct browser to download the PDF
header("Content-Type: application/x-pdf");
header("Content-Disposition: attachment; filename=invoice-". date("Y-m-d-H-i") . ".pdf");
header("Cache-Control: no-cache, must-revalidate");

// output the PDF
echo $invoice->render();

摘要 (Summary)

Now you know the basics of using Zend_PDF to create PDF documents, though there are still many more features available than the ones I’ve mentioned in this article. The source code for this article is available on GitHub if you’d like to clone it and experiment. And of course, feel free to leave comments with any problems you encounter.

现在,您已经知道使用Zend_PDF创建PDF文档的基础知识,尽管仍然有比我在本文中提到的功能更多的功能。 如果您想克隆并进行实验,可以在GitHub上获得本文源代码 。 当然,如果遇到任何问题,请随时发表评论。

Image via Christina DeRidder / Shutterstock

图片来自Christina DeRidder / Shutterstock

翻译自: https://www.sitepoint.com/generating-invoices-with-zend_pdf/

zend_pdf组件源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值