So, you have to follow this Steps to Display Product Image in Invoice Pdf Attachment:
- Create This File : app/code/Vendorname/Modulename/Model/Magento/Sales/Order/Pdf/Invoice.php
<?php
namespace Vendorname\Modulename\Model\Magento\Sales\Order\Pdf;
class Invoice extends \Magento\Sales\Model\Order\Pdf\Invoice
{
protected function _drawHeader(\Zend_Pdf_Page $page)
{
/* Add table head */
$this->_setFontRegular($page, 10);
$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, 0, 0));
//columns headers
$lines[0][] = ['text' => __('Products'), 'feed' => 35];
$lines[0][] = ['text' => __('Product Image'), 'feed' => 200]; // Add this line
$lines[0][] = ['text' => __('SKU'), 'feed' => 370, 'align' => 'right'];
$lines[0][] = ['text' => __('Qty'), 'feed' => 475, 'align' => 'right'];
$lines[0][] = ['text' => __('Price'), 'feed' => 425, 'align' => 'right'];
$lines[0][] = ['text' => __('Tax'), 'feed' => 515, 'align' => 'right'];
$lines[0][] = ['text' => __('Subtotal'), 'feed' => 565, 'align' => 'right'];
$lineBlock = ['lines' => $lines, 'height' => 5];
$this->drawLineBlocks($page, [$lineBlock], ['table_header' => true]);
$page->setFillColor(new \Zend_Pdf_Color_GrayScale(0));
$this->y -= 20;
}
/**
* Return PDF document
*
* @param array|Collection $invoices
* @return \Zend_Pdf
*/
public function getPdf($invoices = [])
{
$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()) {
$this->_localeResolver->emulate($invoice->getStoreId());
$this->_storeManager->setCurrentStore($invoice->getStoreId());
}
$page = $this->newPage();
$order = $invoice->getOrder();
/* Add image */
$this->insertLogo($page, $invoice->getStore());
/* Add address */
$this->insertAddress($page, $invoice->getStore());
/* Add head */
$this->insertOrder(
$page,
$order,
$this->_scopeConfig->isSetFlag(
self::XML_PATH_SALES_PDF_INVOICE_PUT_ORDER_ID,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE,
$order->getStoreId()
)
);
/* Add document text and number */
$this->insertDocumentNumber($page, __('Invoice # ') . $invoice->getIncrementId());
/* Add table */
$this->_drawHeader($page);
/* Add body */
foreach ($invoice->getAllItems() as $item) {
if ($item->getOrderItem()->getParentItem()) {
continue;
}
/* Draw item */
$this->_drawItem($item, $page, $order);
$page = end($pdf->pages);
}
/* Add totals */
$this->insertTotals($page, $invoice);
if ($invoice->getStoreId()) {
$this->_localeResolver->revert();
}
}
$this->_afterGetPdf();
return $pdf;
}
public function drawLineBlocks(\Zend_Pdf_Page $page, array $draw, array $pageSettings = [], $flag = 0)
{
foreach ($draw as $itemsProp) {
if (!isset($itemsProp['lines']) || !is_array($itemsProp['lines'])) {
throw new \Magento\Framework\Exception\LocalizedException(
__('We don\'t recognize the draw line data. Please define the "lines" array.')
);
}
$lines = $itemsProp['lines'];
$height = isset($itemsProp['height']) ? $itemsProp['height'] : 10;
if (empty($itemsProp['shift'])) {
$shift = 0;
foreach ($lines as $line) {
$maxHeight = 0;
foreach ($line as $column) {
$lineSpacing = !empty($column['height']) ? $column['height'] : $height;
if (!is_array($column['text'])) {
$column['text'] = [$column['text']];
}
$top = 0;
foreach ($column['text'] as $part) {
$top += $lineSpacing;
}
$maxHeight = $top > $maxHeight ? $top : $maxHeight;
}
$shift += $maxHeight;
}
$itemsProp['shift'] = $shift;
}
if ($this->y - $itemsProp['shift'] < 15) { $page = $this->newPage($pageSettings);
}
foreach ($lines as $line) {
$maxHeight = 0;
$i = 0;
if (($this->y - 100) < 15) { $page = $this->newPage($pageSettings);
}
foreach ($line as $column) {
if($i == 1 && $flag){
$i++;
if(array_key_exists('is_image', $column) && !is_null($column['text'])){
$image = \Zend_Pdf_Image::imageWithPath($column['text']);
$feed = $column['feed'];
$page->drawImage($image, $feed, $this->y, $feed+70, $this->y-80);
$maxHeight = 100;
}
continue 1;
}
$i++;
$fontSize = empty($column['font_size']) ? 10 : $column['font_size'];
if (!empty($column['font_file'])) {
$font = \Zend_Pdf_Font::fontWithPath($column['font_file']);
$page->setFont($font, $fontSize);
} else {
$fontStyle = empty($column['font']) ? 'regular' : $column['font'];
switch ($fontStyle) {
case 'bold':
$font = $this->_setFontBold($page, $fontSize);
break;
case 'italic':
$font = $this->_setFontItalic($page, $fontSize);
break;
default:
$font = $this->_setFontRegular($page, $fontSize);
break;
}
}
if (!is_array($column['text'])) {
$column['text'] = [$column['text']];
}
$lineSpacing = !empty($column['height']) ? $column['height'] : $height;
$top = 0;
foreach ($column['text'] as $part) {
if ($this->y - $lineSpacing < 15) { $page = $this->newPage($pageSettings);
}
$feed = $column['feed'];
$textAlign = empty($column['align']) ? 'left' : $column['align'];
$width = empty($column['width']) ? 0 : $column['width'];
switch ($textAlign) {
case 'right':
if ($width) {
$feed = $this->getAlignRight($part, $feed, $width, $font, $fontSize);
} else {
$feed = $feed - $this->widthForStringUsingFontSize($part, $font, $fontSize);
}
break;
case 'center':
if ($width) {
$feed = $this->getAlignCenter($part, $feed, $width, $font, $fontSize);
}
break;
default:
break;
}
$page->drawText($part, $feed, $this->y - $top, 'UTF-8');
$top += $lineSpacing;
}
//$maxHeight = 100;
$maxHeight = $top > $maxHeight ? $top : $maxHeight;
}
$this->y -= $maxHeight;
}
}
return $page;
}
}
- Responsible Vendor File For Invoice Pdf Product Data :
vendor/magento/module-sales/Model/Order/Pdf/Items/Invoice/DefaultInvoice.php
- Override in your custom module like this :
Vendorname\Modulename\Model\Magento\Sales\Order\Pdf\Items\Invoice\DefaultInvoice.php
- Define in DI file [di.xml] :
<preference for="Magento\Sales\Model\Order\Pdf\Items\Invoice\DefaultInvoice" type="Vendorname\Modulename\Model\Magento\Sales\Order\Pdf\Items\Invoice\DefaultInvoice"/>
Now you Need to add some code in draw() function and make custom getProductImage() function in your Custom DefaultInvoice.php file
<?php
namespace Vendorname\Modulename\Model\Magento\Sales\Order\Pdf\Items\Invoice;
use Vendorname\Modulename\Model\Magento\Sales\Order\Pdf\Invoice;
use Magento\Framework\App\Filesystem\DirectoryList;
class DefaultInvoice extends \Magento\Sales\Model\Order\Pdf\Items\Invoice\DefaultInvoice
{
public function draw()
{
$order = $this->getOrder();
$item = $this->getItem();
$pdf = $this->getPdf();
$page = $this->getPage();
$lines = [];
// draw Product image // Step 1
$productImage = $this->getProductImage($item, $page);
// draw Product name
$lines[0] = [['text' => $this->string->split($item->getName(), 35, true, true), 'feed' => 35]];
// draw Product image // Step 2
$lines[0][] = array(
'text' => '',
'feed' => 35,
'is_image' => true,
'image' => $productImage,
);
// draw SKU
$lines[0][] = [
'text' => $this->string->split($this->getSku($item), 17),
'feed' => 370,
'align' => 'right',
];
// draw QTY
$lines[0][] = ['text' => $item->getQty() * 1, 'feed' => 475, 'align' => 'right'];
// draw item Prices
$i = 0;
$prices = $this->getItemPricesForDisplay();
$feedPrice = 425;
$feedSubtotal = $feedPrice + 140;
foreach ($prices as $priceData) {
if (isset($priceData['label'])) {
// draw Price label
$lines[$i][] = ['text' => $priceData['label'], 'feed' => $feedPrice, 'align' => 'right'];
// draw Subtotal label
$lines[$i][] = ['text' => $priceData['label'], 'feed' => $feedSubtotal, 'align' => 'right'];
$i++;
}
// draw Price
$lines[$i][] = [
'text' => $priceData['price'],
'feed' => $feedPrice,
'font' => 'bold',
'align' => 'right',
];
// draw Subtotal
$lines[$i][] = [
'text' => $priceData['subtotal'],
'feed' => $feedSubtotal,
'font' => 'bold',
'align' => 'right',
];
$i++;
}
// draw Tax
$lines[0][] = [
'text' => $order->formatPriceTxt($item->getTaxAmount()),
'feed' => 515,
'font' => 'bold',
'align' => 'right',
];
// custom options
$options = $this->getItemOptions();
if ($options) {
foreach ($options as $option) {
// draw options label
$lines[][] = [
'text' => $this->string->split($this->filterManager->stripTags($option['label']), 40, true, true),
'font' => 'italic',
'feed' => 35,
];
if ($option['value']) {
if (isset($option['print_value'])) {
$printValue = $option['print_value'];
} else {
$printValue = $this->filterManager->stripTags($option['value']);
}
$values = explode(', ', $printValue);
foreach ($values as $value) {
$lines[][] = ['text' => $this->string->split($value, 30, true, true), 'feed' => 40];
}
}
}
}
$lineBlock = ['lines' => $lines, 'height' => 20];
$page = $pdf->drawLineBlocks($page, [$lineBlock], ['table_header' => true],1);
$this->setPage($page);
}
/*
* Return Value of custom attribute // Step 3
* */
private function getProductImage($item, &$page)
{
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productId = $item->getOrderItem()->getProductId();
$image = $objectManager->get('Magento\Catalog\Model\Product')->load($productId)->getSmallImage();
if ($image) {
try {
$mediaDirectory = $objectManager->get('Magento\Framework\Filesystem')->getDirectoryRead(DirectoryList::MEDIA);
$imagePath = $mediaDirectory->getAbsolutePath('/catalog/product' . $image);
if ($mediaDirectory->isFile($imagePath)) {
$image = \Zend_Pdf_Image::imageWithPath($imagePath);
$imageWidth = 50; // set image width to 50 pixels
$imageHeight = 50; // set image height to 50 pixels
$top = 450;
$left = 30;
$bottom = $top - $imageHeight;
$right = $left + $imageWidth;
$page->drawImage($image, $left, $bottom, $right, $top);
}
} catch (Exception $e) {
return false;
}
}
}
}
Now Run All the Required Terminal Commands and check Invoice Pdf Attachment :
- Admin Login
- Go to Sales -> Invoices -> View -> Send Email
- Check Customer Email
Before :
After :
I hope it helps!