Enable Dark Mode!
how-to-attach-pdf-excel-reports-to-emails-in-odoo-15.jpg
By: Mohd Ajmal M

How to Attach PDF & Excel Reports to Emails in Odoo 15

Technical Odoo 15

In Odoo, we know that there are different methods to send emails, and generate various reports in Pdf and Excel. But there may be cases of attaching these reports to particular emails sent to the partners.

Here we are going to discuss how the Pdf or Excel reports can be attached to an email template and sent to the particular person’s email id through code.

First of all, let us check how to add a pdf report attachment to an email.

For that, we need an email template in order to send the email. You can refer to Creating E-mail Templates in Odoo 15 for creating email templates.

Attach Pdf report to Email

We have several pdf reports in default in Odoo. Here I take the Invoice report from Odoo as an example.

def send_email_with_pdf_attach(self):
invoice_report_id = self.env.ref('account.account_invoice')
generated_report = invoice_report_id.render_qweb_pdf(self.id)
data_record = base64.b64encode(generated_report[0])
ir_values = {
'name': 'Invoice Report',
'type': 'binary',
'datas': data_record,
'store_fname': data_record,
'mimetype': 'application/pdf',
'res_model': 'account.move',
}
report_attachment = self.env['ir.attachment'].sudo().create(ir_values)
email_template = self.env.ref('module_name.email_template_id')
if email_template:
email_values = {
'email_to': self.partner_id.email,
'email_from': self.env.user.email,
}
email_template.attachment_ids = [(4, report_attachment.id)]
email_template.send_mail(self.id, email_values=email_values,
force_send=True)
email_template.attachment_ids = [(5, 0, 0)]

In the above example, send_email_with_pdf_attach(self) method sends an email with the pdf report of the corresponding invoice to the invoiced partner. First, we need to generate a pdf report by

invoice_report_id = self.env.ref(account.account_invoices)
generated_report = invoice_report_id._render_qweb_pdf(self.id)

Where in invoice_report_id, we get the template for the pdf report, and on generated_report, we will have the generated pdf report. In self, we have the current invoice to be attached.

After this, we need to convert the generated report into binary so as to create an attachment. We can use

data_record = base64.b64encode(generated_report[0])

By the following code, we are creating an attachment for the email.

ir_values = {'name': 'Invoice Report','type': 'binary','datas': data_record,'store_fname': data_record,'mimetype': 'application/pdf','res_model': 'account.move',}report_attachment = self.env['ir.attachment'].sudo().create(ir_values)	

Where report_attachment is the newly created attachment using the ir_values passed. In the ir_values dict, ‘name’ specifies the name for attachment, ‘datas’ have the binary format of generated pdf report to attach, and ‘mime type’ is pdf.

The next flow is to add the attachment to the email template and send it to the particular customer.

For that, first, we take the email template and store it in a variable.

email_template = self.env.ref('module_name.email_template_id')

Where ‘module_name’ is the module where the email template is created, and ‘email_template_id’ specifies the id of the email template.

email_values = {
'email_to': self.partner_id.email,
'email_from': self.env.user.email
}
email_template.attachment_ids = [(4, report_attachment.id)]
email_template.send_mail(self.id, email_values=email_values, force_send=True)
email_template.attachment_ids = [(5, 0, 0)]

From the above code lines, we are attaching the generated pdf attachment with the email. In ‘email_values’, we can specify the values for the email to be sent like the from and to email address, carbon copies, scheduling date, etc. Then we will attach the generated attachment to the email by [(4, id of the attachment)].

And using the send_mail method, we're gonna send the mail.

At last, by [(5,0,0)], we unlink the attachment from the email template as the email is already sent. Otherwise, we will have all the attachments to be sent to each email. To avoid this, we unlink the current attachment from the template after sending each mail.

Now we can move to the part of attaching excel reports to the email template and send the particular mail.

Attach excel report to email

As with the pdf attachment, we need to create an excel attachment, and for that, we need to generate an excel report. But unfortunately, Odoo has no default methods to generate an excel file. Because of this, we use the report_xlsx module to generate an excel file and an attachment in order to send the email.

We need an excel report to add an attachment. So, first, let us check how to create an excel report using the report_xlsx module.

class ExcelReport(models.AbstractModel):
_name = 'report.module_name.report_xlsx'
_inherit = 'report.report_xlsx.abstract'
_description = 'Report Xlsx'
def generate_xlsx_report(self, workbook, data, objs):
sheet = workbook.add_worksheet('Report')
head_format = workbook.add_format({
'align': 'center',
'bold': True,
'font_size': '10px',
})
data_format = workbook.add_format({
'font_size': '10px',
})
# set up the headers for the excel report
# for example,
# sheet.write(0, 1, 'INVOICE REF', head_format)
# sheet.write(0, 2, 'INVOICE DATE', head_format)
# next fetch the details to be added to excel report
# loop through the fetched data and pass it to excel
# for example,
# j = 1
# assume data contains all the fetched records
# for i in range(0, len(data)):
# sheet.write(j, 0, data1, data_format)
# sheet.write(j, 1, data2, data_format)
# sheet.write(j, 2, data3, data_format)
# j += 1

Next, we need to create an action for the excel report to be generated.

<record id="action_report_xlsx" model="ir.actions.report">
    <field name="name">Report Xlsx</field>
    <field name="model">account.move</field>
    <field name="report_type">xlsx</field>
    <field name="report_name">module_name.report_xlsx</field>
    <field name="report_file">module_name.report_xlsx</field>
    <field name="print_report_name">'Report Xlsx'</field>
</record>

As we have set up the excel report, we can move to attach this excel report to our email template.

def send_email_with_excel_attach(self):
report = self.env.ref('module_name.action_report_xlsx')
generated_report = report._render_xlsx(self.id)
data_record = base64.b64encode(generated_report[0])
ir_values = {
'name': 'Invoice Report',
'type': 'binary',
'datas': data_record,
'store_fname': data_record,
'mimetype': 'application/vnd.ms-excel',
'res_model': 'account.move',
}
attachment = self.env['ir.attachment'].sudo().create(ir_values)
email_template = self.env.ref('module_name.email_template')
if email_template:
email_values = {
'email_to': self.partner_id.email,
'email_from': self.env.user.email,
}
email_template.attachment_ids = [(4, attachment.id)]
email_template.send_mail(self.id, email_values=email_values)
email_template.attachment_ids = [(5, 0, 0)]

In this send_email_with_excel_attach() method, we use the same flow as for attaching a pdf file to the email template. But for generating the excel report we used the _render_xlsx() method from the report_xlsx module. And also in ir_values, the mime type will be of type ms-excel.

And that's how we attach pdf or excel files to our email templates to send emails to particular partners in Odoo 15.


If you need any assistance in odoo, we are online, please chat with us.



1
Comments

pete

What about CSV?

04/01/2023

-

10:09PM



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message