Hello everyone! Today I’ll show you how to add custom attribute to Magento’s generated PDF invoice in just a few steps. Since this article is pretty straight-forward, here we go.
One of my recent tasks was to create a custom attribute for products called inchoo_warehouse_location, and output it when click on “Print” (invoice in admin section) occurs. Since PDF generation is Magento’s core functionality, we’ll have to rewrite it a bit.
Step 1
Create the following three files in your Magento’s installation:
app/code/local/Inchoo/Invoice/Model/Order/Pdf/Items/Invoice/Default.php
app/code/local/Inchoo/Invoice/Model/Order/Pdf/Invoice.php
app/code/local/Inchoo/Invoice/etc/config.xml
Those will be used for our extension that will modify Magento’s core functionality.
Step 2
Fill in the data to according files:
config.xml
<?xml version="1.0"?>
<config>
<modules>
<Inchoo_Invoice>
<version>0.1.0</version>
</Inchoo_Invoice>
</modules>
<global>
<models>
<sales>
<rewrite>
<order_pdf_invoice>Inchoo_Invoice_Model_Order_Pdf_Invoice</order_pdf_invoice>
<order_pdf_items_invoice_default>Inchoo_Invoice_Model_Order_Pdf_Items_Invoice_Default</order_pdf_items_invoice_default>
</rewrite>
</sales>
</models>
</global>
</config>
Default.php
<?php
/**
* Inchoo PDF rewrite for custom attribute
* Attribute "inchoo_warehouse_location" has to be set manually
* Original: Sales Order Invoice Pdf default items renderer
*
* @category Inchoo
* @package Inhoo_Invoice
* @author Mladen Lotar - Inchoo <mladen.lotar@inchoo.net>
*/
class Inchoo_Invoice_Model_Order_Pdf_Items_Invoice_Default extends Mage_Sales_Model_Order_Pdf_Items_Invoice_Default
{
/**
* Draw item line
**/
public function draw()
{
$order = $this->getOrder();
$item = $this->getItem();
$pdf = $this->getPdf();
$page = $this->getPage();
$lines = array();
//Inchoo - Added custom attribute to PDF, first get it if exists
$WarehouseLocation = $this->getWarehouseLocationValue($item);
// draw Product name
$lines[0] = array(array(
'text' => Mage::helper('core/string')->str_split($item->getName(), 60, true, true),
'feed' => 35,
));
//Inchoo - Added custom attribute
//draw Warehouse Location
$lines[0][] = array(
'text' => Mage::helper('core/string')->str_split($WarehouseLocation, 25),
'feed' => 245
);
// draw SKU
$lines[0][] = array(
'text' => Mage::helper('core/string')->str_split($this->getSku($item), 25),
'feed' => 325
);
// draw QTY
$lines[0][] = array(
'text' => $item->getQty()*1,
'feed' => 435
);
// draw Price
$lines[0][] = array(
'text' => $order->formatPriceTxt($item->getPrice()),
'feed' => 395,
'font' => 'bold',
'align' => 'right'
);
// draw Tax
$lines[0][] = array(
'text' => $order->formatPriceTxt($item->getTaxAmount()),
'feed' => 495,
'font' => 'bold',
'align' => 'right'
);
// draw Subtotal
$lines[0][] = array(
'text' => $order->formatPriceTxt($item->getRowTotal()),
'feed' => 565,
'font' => 'bold',
'align' => 'right'
);
// custom options
$options = $this->getItemOptions();
if ($options) {
foreach ($options as $option) {
// draw options label
$lines[][] = array(
'text' => Mage::helper('core/string')->str_split(strip_tags($option['label']), 70, true, true),
'font' => 'italic',
'feed' => 35
);
if ($option['value']) {
$_printValue = isset($option['print_value']) ? $option['print_value'] : strip_tags($option['value']);
$values = explode(', ', $_printValue);
foreach ($values as $value) {
$lines[][] = array(
'text' => Mage::helper('core/string')->str_split($value, 50, true, true),
'feed' => 40
);
}
}
}
}
$lineBlock = array(
'lines' => $lines,
'height' => 10
);
$page = $pdf->drawLineBlocks($page, array($lineBlock), array('table_header' => true));
$this->setPage($page);
}
/*
* Return Value of custom attribute
* */
private function getWarehouseLocationValue($item)
{
$prod = Mage::getModel('catalog/product')->load($item->getProductId());
if(!($return_location = $prod->getInchooWarehouseLocation()))
return 'N/A';
else
return $return_location;
}
}
And finally Invoice.php
<?php
/**
* Inchoo PDF rewrite for custom attribute
* * Attribute "inchoo_warehouse_location" has to be set manually
* Original: Sales Order Invoice PDF model
*
* @category Inchoo
* @package Inhoo_Invoice
* @author Mladen Lotar - Inchoo <mladen.lotar@inchoo.net>
*/
class Inchoo_Invoice_Model_Order_Pdf_Invoice extends Mage_Sales_Model_Order_Pdf_Invoice
{
public function getPdf($invoices = array())
{
$this->_beforeGetPdf();
$this->_initRenderer('invoice');
$pdf = new Zend_Pdf();
$this->_setPdf($pdf);
$style = new Zend_Pdf_Style();
$this->_setFontBold($style, 10);
foreach ($invoices as $invoice) {
if ($invoice->getStoreId()) {
Mage::app()->getLocale()->emulate($invoice->getStoreId());
}
$page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
$pdf->pages[] = $page;
$order = $invoice->getOrder();
/* Add image */
$this->insertLogo($page, $invoice->getStore());
/* Add address */
$this->insertAddress($page, $invoice->getStore());
/* Add head */
$this->insertOrder($page, $order, Mage::getStoreConfigFlag(self::XML_PATH_SALES_PDF_INVOICE_PUT_ORDER_ID, $order->getStoreId()));
$page->setFillColor(new Zend_Pdf_Color_GrayScale(1));
$this->_setFontRegular($page);
$page->drawText(Mage::helper('sales')->__('Invoice # ') . $invoice->getIncrementId(), 35, 780, 'UTF-8');
/* Add table */
$page->setFillColor(new Zend_Pdf_Color_RGB(0.93, 0.92, 0.92));
$page->setLineColor(new Zend_Pdf_Color_GrayScale(0.5));
$page->setLineWidth(0.5);
$page->drawRectangle(25, $this->y, 570, $this->y -15);
$this->y -=10;
/* Add table head */
$page->setFillColor(new Zend_Pdf_Color_RGB(0.4, 0.4, 0.4));
$page->drawText(Mage::helper('sales')->__('Products'), 35, $this->y, 'UTF-8');
//Added for custom attribute "inchoo_warehouse_location"
$page->drawText(Mage::helper('sales')->__('Warehouse Location'), 245, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('SKU'), 325, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Price'), 380, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Qty'), 430, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Tax'), 480, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Subtotal'), 535, $this->y, 'UTF-8');
$this->y -=15;
$page->setFillColor(new Zend_Pdf_Color_GrayScale(0));
/* Add body */
foreach ($invoice->getAllItems() as $item){
if ($item->getOrderItem()->getParentItem()) {
continue;
}
if ($this->y < 15) {
$page = $this->newPage(array('table_header' => true));
}
/* Draw item */
$page = $this->_drawItem($item, $page, $order);
}
/* Add totals */
$page = $this->insertTotals($page, $invoice);
if ($invoice->getStoreId()) {
Mage::app()->getLocale()->revert();
}
}
$this->_afterGetPdf();
return $pdf;
}
public function newPage(array $settings = array())
{
/* Add new table head */
$page = $this->_getPdf()->newPage(Zend_Pdf_Page::SIZE_A4);
$this->_getPdf()->pages[] = $page;
$this->y = 800;
if (!empty($settings['table_header'])) {
$this->_setFontRegular($page);
$page->setFillColor(new Zend_Pdf_Color_RGB(0.93, 0.92, 0.92));
$page->setLineColor(new Zend_Pdf_Color_GrayScale(0.5));
$page->setLineWidth(0.5);
$page->drawRectangle(25, $this->y, 570, $this->y-15);
$this->y -=10;
$page->setFillColor(new Zend_Pdf_Color_RGB(0.4, 0.4, 0.4));
$page->drawText(Mage::helper('sales')->__('Product'), 35, $this->y, 'UTF-8');
//Added for custom attribute "inchoo_warehouse_location"
$page->drawText(Mage::helper('sales')->__('Warehouse Location'), 245, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('SKU'), 325, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Price'), 380, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Qty'), 430, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Tax'), 480, $this->y, 'UTF-8');
$page->drawText(Mage::helper('sales')->__('Subtotal'), 535, $this->y, 'UTF-8');
$page->setFillColor(new Zend_Pdf_Color_GrayScale(0));
$this->y -=20;
}
return $page;
}
}
Step 3
Now, you’ve done it. Test it out by going to “Sales->Invoices->(View any of them)->Print”. You shoud be asked to download PDF, and when you do, it should contain “Warehouse Location” by each of order items.
All you have to do is test it out and / or change it according to your needs!
I hope this was of help to someone!
Cheers!





If we upgeade magento to its latest version, will this code be overwritten or cause issues? Thanks.
Would this same method work for the packing slips?
Nice
But i will need something like display product image on PDF , how can i do it ?!
How can I add the product descriptions to the pdf?
I Attempt add products images to pdf.
but Defeated. Because not is array
how can i do it? thx
This is great – but where is the Warehouse location info coming from? Is this a another module?
@Chris: It’s an attribute.
@Toni thanks – so how could i add the delivery address to the footer of the invoice? using this method?
Hello everyone, just a quick update:
there’s an extension for product images on PDF invoice here http://inchoo.net/ecommerce/magento/magento-pdf-invoice-with-product-images-extension/
quite a few people asked for it, so… xD
Cheers!
I have a question you might know the answer for.
I am trying to get the pdf show RTL. i know how to change the font. but no way i can find how to get it to show right to left. any chance someone might know how it can be done?
I installed your module as instructed but i don’t get ware house location attribute in my invoice.
Magento version 1.4.2
runing on local machine.
Hi! some one help me how can take the shipment tracking number from shipment tables & store it in another table……
Can i do the same for magento 1.5?
Got it working for every attribute I need, however, it shows the ID (“10″ instead of “Nike”) of the value instead of the value as text.
What should be added or changed to get this to work?
Great guide, i am having problems with the custom options spanning across the page instead of appearing in a list. Anyone know how to fix this in Magento 1.5.1.0?
I’m trying to find the code to call the PO Number data from the database. Does anyone know what that might be? Any feedback would be much appreciated!
How would you go about adding a custom item (like a texarea) to Sales > PDF Print-outs and then using it in the invoice?
Thanks
Any one know how to add the shipping address at the bottom so I can use intergrated labels, maybe with a PPI impression?
Thanks x
@Tiffany I’ll give you a hint. Take a look at file app/code/core/Mage/Sales/Model/Order/Pdf/Invoice.php … In method getPdf($invoices = array()) after the line:
you can call:
N.B.
Please don’t override core files and wrap your idea in Magento extension.
@Alan, From next article you can learn how to create custom configuration fields in Magento: http://www.ecomdev.org/2010/10/27/custom-configuration-fields-in-magento.html
In your case you will need to change:
After that to retrieve the value of your custom configuration field, just call somewhere in the code:
$text = Mage::getStoreConfig('mycustom_section/mycustom_group/mycustom_field')Cheers!
@Amanda, do you mean to move, the shipping address at the bottom, not to add it? What do you mean with “… so I can use intergrated labels, maybe with a PPI impression?” … do you mean to put some logo / image near to the shipping address?
On the Magento wiki there is also a great tutorial about how to customize the pdf in Megento – http://www.magentocommerce.com/wiki/5_-_modules_and_development/orders/editing_an_invoice_pdf
@jeff b
In inchoo product image extension he get the product with
Mage::getModel('catalog/product')->load($productId);and on this object you can get all the product info – try writing
$product = Mage::getModel('catalog/product')->load($productId); print_r($product->getData());and see all the variables you can use…
An alternative is to use our new extension http://ext4mage.com/html2pdf-magento-extension.html
I am not a developer I am just the persona in charge of the web, I am trying to make changes in the invoice. The go thru the magento panel or i need my programer to do any change???
Using this method you need a developer
That is excellent what i need now, thank you very much Mr. Lotar
@Amanda I know exactly what you mean, I print several hundred orders a week on integrated labels and it saves literally hours every day.
I made an extension to allow this to work well with Magento PDFs, you can fine-tune the position of each label to fit in the label space: http://www.moogento.com/magento-pickpack-picklist.html
Hi, I’m coming crazy to add the date into pdf invoice and pdf credit memo.
Please someone can help me?
Thanks.
Hey @Cesko give us more hints …
What exactly you don’t know?
You don’t know how to extract the date or you don’t know how to position / draw text in pdf documents?
What is the context of your changes? I which file you want to apply your changes?
Thanks for your sharing !
I have tried to get it working on 1.6.1 and no luck.
Nothing s happening when i click opn the print button in the back office. it charges the old pdf invoice. any idea. ?
How do i display a new columm with the Vat rate and a custom attribute called price_kg.
Many thanks for your help
Hi I have solved. I just add the following code:
$page->drawText(Mage::helper('sales')->__('Invoice Date: ') . Mage::helper('core')->formatDate($invoice->getCreatedAtDate(), 'medium', false), 35, 770, 'UTF-8');in app\code\local\Mage\Sales\Model\Order\Pdf\invoice.php.
Thanks anyway for help.
@laurent, I have checked the invoice.php and Abstract.php in 1.6.1 and appear same 1.6.2 where I’m working.
Did you copy the code in app\code\local\Mage\Sales\Model\Order\Pdf\invoice.php?
Also You will need to change some x,y coordinates of some objects inside invoice.php and Abstract.php files, otherwise the invoice date will appear overlying the order date.
@cesko
Thanks for your quick help. I am a newbie but there is something I don’t understand. If you use a new inchoo module, why do you get the invoice.php from the mage directory instead of the newly created inchoo one. I thought this module was supposed to overwrite it ? Am I wrong ?
Thanks for the tips. I ll have another go and let you know
@laurent, I think there is a missunderstanding. I didn’t use the inchoo module, only I wrote here to get help to modify something in pdf invoice.
If You are using this inchoo module, I think that You have to modify the file app/code/local/Inchoo/Invoice/Model/Order/Pdf/Invoice.php and app/code/local/Inchoo/Invoice/Model/Order/Pdf/Abstract.php.
@Cesko. Sorry for the misunderstanding . As i couldn’t get it working, I looked deeper in the code on the default.php.I ve got my module working now for two customs attributes but I am being stuck “how to display the tax rate in a column klike the sku qty. I can get the taxe rate id but can’t display the value. As i have been looking for a solution, I am getting blind.Any idea how to do this ?
Just a simple question – I am trying to line up the shipping address to fit the integrated label statioery and all i need to do is move the top section up a little and the bottom section down a little. Nowhere can I find an explanation how to do this. Does anyone know?
I was trying to use this method to call another attribute in magento ce 1.7.0.2 and nothing worked… I am not sure how it is suppose to be now with the new edition of Magento. Please comment or maybe re post this for a new version. Thank you
Does anyone have an idea on how to add an attribute to the Invoice and print it out? I need to add a text field to describe the order on the invoice. Thanks
@Simon you can use $page->drawText(‘My attribute text’, ‘x coordinate’, ‘y coordinate’, ‘UTF-8′) to display the attribute in the invoice PDF. If you want to get familiar with PDF creating functions, please take a look here: http://devzone.zend.com/1064/zend_pdf-tutorial/
What attribute do you want to display in the invoice page? Is it order data or you want to use some text field, which will be populated in admin panel?
Hello Sir,
i have a problem with magento 1.7.0.2 …
when i am creating invoice pdf ..from admin ..
at the top of invoice pdf there are no invoice date ..there are only invoice no. or order date. ..but i want order no. with this …
sorry invoice date…