How To Attach PDF File To Invoice Email in Magento 2 Programmatically

Sometimes, you need to attach a PDF file to Magento 2 invoice email. However, manually attaching files is not feasible.

So in this article, we will show you how to programmatically attach a PDF file in your email!

Let’s learn it now!

How To Attach PDF File To Magento 2 Invoice Email Programmatically

Magento 2 uses the TransportBuilder class to send emails, but it doesn’t support file attachments.​​​​​​​ 

So to add email attachments programmatically, first of all, you need to create the new TransportBuilder class in app/code/Vendor/Module /Mail/Template/ TransportBuilder.php

<?php

namespace Vendor\Module\Mail\Template;

class TransportBuilder extends \Magento\Framework\Mail\Template\TransportBuilder
{
   /**
    * addAttachment
    *
    * @param mixed $body
    * @param string $filename
    * @param mixed $mimeType
    * @param mixed $disposition
    * @param mixed $encoding
    * @return object
    */
    public function addAttachment(
        $body,
        $filename = null,
        $mimeType = \Zend_Mime::TYPE_OCTETSTREAM,
        $disposition = \Zend_Mime::DISPOSITION_ATTACHMENT,
        $encoding = \Zend_Mime::ENCODING_BASE64
    ) {
        $attachmentPart = new \Zend\Mime\Part();
        $attachmentPart->setContent($body)
            ->setType($mimeType)
            ->setFileName($filename)
            ->setEncoding($encoding)
            ->setDisposition($disposition);

        return $attachmentPart;
    }
}

Then create the SenderBuilder class to add attachment files. With this class, you can add PDF, image, or calendar files with email.

Add the SenderBuilder file in app/code/Vendor/Module/Model/Sales/Order/Email/SenderBuilder.php

<?php

namespace Vendor\Module\Model\Sales\Order\Email;

use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Mail\Template\TransportBuilderByStore;
use Magento\Sales\Model\Order\Email\Container\IdentityInterface;
use Magento\Sales\Model\Order\Email\Container\Template;

/**
 * Email sender builder for attachments
 */
class SenderBuilder extends \Magento\Sales\Model\Order\Email\SenderBuilder
{
    /**
     * @param Template $templateContainer
     * @param IdentityInterface $identityContainer
     * @param TransportBuilder $transportBuilder
     * @param TransportBuilderByStore $transportBuilderByStore
     * @param \Magento\Framework\Filesystem\Driver\File $reader
     */
    public function __construct(
        Template $templateContainer,
        IdentityInterface $identityContainer,
        TransportBuilder $transportBuilder,
        TransportBuilderByStore $transportBuilderByStore = null,
        \Vendor\Module\Helper\Data $helper,
        \Magento\Framework\Filesystem\Driver\File $reader
    ) {
        parent::__construct(
            $templateContainer,
            $identityContainer,
            $transportBuilder
        );
        $this->helper = $helper;
        $this->reader = $reader;
    }
    /**
     * Prepare and send email message
     *
     * @return void
     */
    public function send()
    {
        $this->configureEmailTemplate();

        $this->transportBuilder->addTo(
            $this->identityContainer->getCustomerEmail(),
            $this->identityContainer->getCustomerName()
        );

        $copyTo = $this->identityContainer->getEmailCopyTo();
        if (!empty($copyTo) && $this->identityContainer->getCopyMethod() == 'bcc') {
            foreach ($copyTo as $email) {
                $this->transportBuilder->addBcc($email);
            }
        }

        /* to attach events in invoice email */
        $templateVars = $this->templateContainer->getTemplateVars();
        $transport = $this->transportBuilder->getTransport();
        if (!empty($templateVars['order'])) {
            $order = $templateVars['order'];
            foreach ($order->getAllItems() as $item) {
                $data = $this->helper->createPdfFile($item, $order->getId());
                if (!empty($data) && !empty($data['filename']) && !empty($data['pdfFile'])) {
                    // adds attachment in mail
                    $attachmentPart = $this->transportBuilder->addAttachment(
                        $this->reader->fileGetContents($data['pdfFile']),
                        $data['filename'],
                        'application/pdf'
                    );

                    $message = $transport->getMessage();
                    $body = \Zend\Mail\Message::fromString($message->getRawMessage())->getBody();
                    $body = \Zend_Mime_Decode::decodeQuotedPrintable($body);
                    $html = '';

                    if ($body instanceof \Zend\Mime\Message) {
                        $html = $body->generateMessage(\Zend\Mail\Headers::EOL);
                    } elseif ($body instanceof \Magento\Framework\Mail\MimeMessage) {
                        $html = (string) $body->getMessage();
                    } elseif ($body instanceof \Magento\Framework\Mail\EmailMessage) {
                        $html = (string) $body->getBodyText();
                    } else {
                        $html = (string) $body;
                    }

                    $htmlPart = new \Zend\Mime\Part($html);
                    $htmlPart->setCharset('utf-8');
                    $htmlPart->setEncoding(\Zend_Mime::ENCODING_QUOTEDPRINTABLE);
                    $htmlPart->setDisposition(\Zend_Mime::DISPOSITION_INLINE);
                    $htmlPart->setType(\Zend_Mime::TYPE_HTML);
                    $parts = [$htmlPart, $attachmentPart];

                    $bodyPart = new \Zend\Mime\Message();
                    $bodyPart->setParts($parts);
                    $message->setBody($bodyPart);
                }
            }
        }

        $transport->sendMessage();
    }
}

Finally, you add the following code in app/code/Vendor/Module/etc/di.xml to use the new TransportBuilder class of your module.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
  <preference for="\Magento\Framework\Mail\Template\TransportBuilder" type="Vendor\Module\Model\Mail\TransportBuilder" />
</config>

The Best Solution To Attach PDF File To Invoice Email

Even though you can programmatically attach a PDF file to your invoice emails, it’s not ideal to do so. And code can be very confusing to most people.

So hereby, we want to introduce you to the best solution to attach PDF file to Magento 2 invoice emails:

Magento 2 Auto Invoice by BSS

magento-2-auto-invoice

Unlike most other modules that require you to install another third-party PDF invoice extension, this module already has a built-in PDF file to your invoice and shipment email.

Moreover, it helps you generate invoices and shipment automatically right after a customer finishes placing the order. This feature will save you a lot of time and effort, and enhance customer satisfaction.

This extension also supports many payment methods (COD, check/money order, credit card, PayPal, etc.)

Highlight features:

  • Automatically generate invoice and shipment based on payment methods for orders with a “new” order state
  • Automatically send invoice and shipment emails to customer
  • Apply automatic invoice and shipment for multiple payment methods

Conclusion

In this article, we have shown you how to programmatically attach a PDF file in your emails. 

We also introduced the easiest way to attach the file using Magento 2 extension.

We hope this blog is helpful and good luck to you!

BSS Commerce is one of the leading Magento extension providers and web development services in the world. With experienced and certified Magento developers, we commit to bringing high-quality products and services to optimize your business effectively. Furthermore, we offer FREE Installation – FREE 1-year Support and FREE Lifetime Update for every Magento extension.

CONTACT NOW to let us know your problems. We are willing to support you every time.

Posts

Writing is a part of my life and I'm living for it.

Write A Comment

Name