Customize Magento PDF Invoice and Packingslip

This article explains how to customize Magento’s default PDF Invoice or Packingslip, so you will be able to change the layout, customize fonts and other elements.
First, we create a new simple module. The only purpose of this is to rewrite core classes that are responsible for the PDF generation.
Our config.xml will contain the following rewriting directives:

<models>
...
    <sales>
        <rewrite>                    
        	<order_pdf_invoice>Atwix_Printedorders_Model_Invoice</order_pdf_invoice>
        </rewrite>
    </sales>
...
</models>

Create appropriate model (Model/Invoice.php). Atwix_Printedorders_Model_Invoice extends Mage_Sales_Model_Order_Pdf_Invoice. Take a look at the core Mage_Sales_Model_Order_Pdf_Invoice class. Copy getPDF function to the newly created Invoice.php. Now you are ready to make changes. Start with commenting out the line:

//$this->insertLogo($page, $invoice->getStore());

As you can see, there is no logo at the PDF invoice anymore.
Use the same approach if you need to delete other blocks from PDF.
Adding custom information is also simple, Zend_Pdf guide will help you with PDF drawing.
Also, most likely, you would need to define a couple of functions from app/code/core/Mage/Sales/Model/Order/Pdf/Abstract.php such as _setFontRegular, _drawItem.
Here you can adjust font size and family.

protected function _setFontRegular($object, $size = 10)
    {
        $font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);
        $object->setFont($font, $size);
        return $font;
    }

Finally, take a look at some practical examples below. All actions happen in getPdf.

1.

Screenshot practical examples getPdf

Code that reproduces it:

$this->y = 800;
$x = 30;
$this->_setFontBold($page, 10);
$page->drawText('Customer:', $x, $this->y, 'UTF-8');
$this->_setFontRegular($page, 10);
$x=10;

$billingAddress = $this->_formatAddress($order->getBillingAddress()->format('pdf'));
foreach ($billingAddress as $key => $value) {
    if ($value !== '') {
        $page->drawText($value, $x + 80, $this->y, 'UTF-8');
        $this->y -= 12;
    }
}
$x = 30;

$this->_setFontBold($page, 10);
$page->drawText('Telephone Number:', $x, $this->y - 5, 'UTF-8');
$page->drawText('E-Mail Address:', $x, $this->y - 17, 'UTF-8');
$this->_setFontRegular($page, 10);
$page->drawText($order->getShippingAddress()->getTelephone(), $x + 100, $this->y - 5, 'UTF-8');
$page->drawText($order->getShippingAddress()->getEmail(), $x + 100, $this->y - 17, 'UTF-8');

2.

Screenshot Magento Invoice PDF

Code that reproduces it:

$x = 35;
$this->_setFontBold($page, 9);
$page->drawRectangle(30, $this->y - 8, $page->getWidth()-30, $this->y + 12, Zend_Pdf_Page::SHAPE_DRAW_STROKE);
$page->drawText('Date Added', $x + 15, $this->y, 'UTF-8');
$page->drawText('Customer Notified', $x + 110, $this->y, 'UTF-8');
$page->drawText('Status', $x + 225, $this->y, 'UTF-8');
$page->drawText('Comments', $x + 310, $this->y, 'UTF-8');

$page->drawLine($x + 90, $this->y + 12, $x + 90, $this->y - 8);
$page->drawLine($x + 208, $this->y + 12, $x + 208, $this->y - 8);
$page->drawLine($x + 290, $this->y + 12, $x + 290, $this->y - 8);

$this->y -= 20;
$this->_setFontRegular($page, 9);

foreach ($order->getStatusHistoryCollection(true) as $_item) {
    $page->drawRectangle(30, $this->y - 8, $page->getWidth()-30, $this->y + 12, Zend_Pdf_Page::SHAPE_DRAW_STROKE);
    $page->drawLine($x + 90, $this->y + 12, $x + 90, $this->y - 8);
    $page->drawLine($x + 208, $this->y + 12, $x + 208, $this->y - 8);
    $page->drawLine($x + 290, $this->y + 12, $x + 290, $this->y - 8);
    $page->drawText(Mage::helper('core')->formatDate($_item->getCreatedAtDate(), 'medium') . " " . Mage::helper('core')->formatTime($_item->getCreatedAtDate(), 'medium'), 35, $this->y, 'UTF-8');

    if ($_item->isCustomerNotificationNotApplicable()) {
        $page->drawText(Mage::helper('sales')->__('Notification Not Applicable'), $x + 100, $this->y, 'UTF-8');
    } elseif ($_item->getIsCustomerNotified()) {
        $page->drawText(Mage::helper('sales')->__('Notified'), $x + 100, $this->y, 'UTF-8');
    } else {
        $page->drawText(Mage::helper('sales')->__('Not Notified'), $x + 100, $this->y, 'UTF-8');
    }

    $page->drawText($_item->getStatusLabel(), $x + 218, $this->y, 'UTF-8');

    if ($_item->getComment()) {
        $text = html_entity_decode(Mage::helper('core')->escapeHtml($_item->getComment(), array('b', 'br', 'strong', 'i', 'u')));
            $page->drawText($text, $x + 295, $this->y, 'UTF-8');

    }
    $this->y -= 20;
}

Similarly, you can rewrite Mage_Sales_Model_Order_Pdf_Shipment class to change Packingslip PDF.

And what changes for the layout you’d suggest?

You may also want to read: