Enable Dark Mode!
how-to-create-microsoft-word-documents-in-a-zip-in-odoo-16.jpg
By: Sruthi M Kumar

How to Create Microsoft Word Documents in a Zip in Odoo 16

Technical Odoo 16

Reports are crucial to business since they provide information about how the company is performing and being reflected. They allow us to check the success and failure rates of the business. Odoo offers a platform for generating reports and analyzing business developments.

You can generate PDF reports for custom modules because Odoo, by default, supports PDF reports. Also, we can generate Excel reports in Odoo, which will be very helpful for your company's business executives. Sometimes, we may also require reports in other formats, such as Microsoft Word (.docx).

In this blog, we are going to discuss how to create a Microsoft Word (.docx) report in a custom module and how to download multiple documents in one zip. Installing the Python library python-docx is required to produce the report in Microsoft Word (.docx) format. Microsoft Word (.docx) files will be created and updated using the python-docx library.

It's easy to install. Using the following piece of code, you may install Python-docx:

pip install python-docx

Open the terminal and install python-docx.

Next, we'll discuss creating Microsoft Word (.docx) documents within zip files in Odoo 16. The following code shows the Python file of the sample doc.report to be implemented

from odoo import models, fields
class TestDoc(models.Model):
   _name = 'doc.report'
   name = fields.Char(String='Name', help="Customer Name", required=True)
   def print_pdf(self):
       return {'type': 'ir.actions.act_url',
               'url': '/web/binary/download_docx_report',
               'target': 'self',
               'res_id': self.id,
               }

Here is a method for the print button that returns the URL - /web/binary/download_docx_report. Moreover, we need to define a controller for it. The view of the sample doc.report is shown in the figure below,

how-to-create-microsoft-word-documents-in-a-zip-in-odoo-16-1-cybrosys

The controller for the root /web/binary/download_docx_report is defined as follows,

import io, os, base64, zipfile
from odoo import http, _
from docx import Document
from odoo.http import request
from docx.shared import Inches
class Binary(http.Controller):
   @http.route('/web/binary/download_docx_report', type='http', auth="public")
   def download_function_descriptions(self):
       stream = io.BytesIO()
       zip_archive = zipfile.ZipFile(stream, 'w', compression=zipfile.ZIP_DEFLATED)
       document1 = Document()
       section = document1.sections[0]
       sec_header = section.header
       company = request.env.company
       file_path = os.path.join(os.getcwd(), 'logo.png')
       # Add logo image to document1
       if company.logo:
           image_data = base64.b64decode(company.logo)
           with open(file_path, 'wb') as f:
               f.write(image_data)
           header_paragraph1 = sec_header.paragraphs[0]
           run1 = header_paragraph1.add_run()
           run1.add_picture(file_path, width=Inches(1.25))
       document1.add_paragraph('Test Paragraph for FIRST document')
       document1_file_name = "test1.docx"
       document1.save(document1_file_name)
       zip_archive.write(document1_file_name)
       document2 = Document()
       section = document2.sections[0]
       sec_header = section.header
       # Add logo image to document2
       if company.logo:
           header_paragraph2 = sec_header.paragraphs[0]
           run2 = header_paragraph2.add_run()
           run2.add_picture(file_path, width=Inches(1.25))
       document2.add_paragraph('Test Paragraph for SECOND document')
       document2_file_name = "test2.docx"
       document2.save(document2_file_name)
       zip_archive.write(document2_file_name)
       zip_archive.close()
       bytes_of_zipfile = stream.getvalue()
       return request.make_response(bytes_of_zipfile,
                                    [('Content-Type', 'application/zip'),
                                     ('Content-Disposition', 'attachment')])

Let's look at each component of the above code in detail:

stream = io.BytesIO() 

//To store data as bytes in the memory buffer.

zip_archive = zipfile.ZipFile(stream, 'w', compression=zipfile.ZIP_DEFLATED)

 // Create zip 

 document1 = Document()

// For the first document, open it. Here, numerous documents have been created and downloaded as a ZIP file, thus the name document1.

header_paragraph1 = sec_header.paragraphs[0]

run1 = header_paragraph1.add_run()

run1.add_picture(file_path, width=Inches(1.25))

//Which will add the paragraph and insert the logo image into the header of the document.

 document1.add_paragraph('Test Paragraph for FIRST document') 

// To insert a paragraph into the text, we must first define the element add_paragraph, to which the paragraph will be added and shown.Tables, headers, and many other features can all be added to the content. To learn more, please go through the python-docx documentation.

document1_file_name = "test1.docx"

// Set a name for the document; in this case, test1.docx will serve as an example. If you need to create several documents and your name needs to be based on the document, you can also use other techniques to create the name.

 document1.save(document1_file_name)

// Save the generated document with file name test1.docx

 zip_archive.write(document1_file_name)

// Added the generated document to the generated ZIP file.

 document2 = Document()

 document2.add_paragraph('Test Paragraph for SECOND document')

 document2_file_name = "test2.docx"

 document2.save(document2_file_name)

 zip_archive.write(document2_file_name)

Similarly, the process repeats itself to generate a second document that you can loop around as per the customer's needs

zip_archive.close()

// Close the zip

 bytes_of_zipfile = stream.getvalue()

Now in stream, we have data as bytes, and we use the function getvalue() to get value from the stream.

return request.make_response(bytes_of_zipfile,[('Content-Type', 'application/zip'),

                                  ('Content-Disposition', 'attachment')])

// Return the request with the associated response. Use the make_response method to create a response using the generated ZIP file.

Let's check how it works. When you click the print button, it redirects to the corresponding URL defined, so the controllers return the response with the documents in a ZIP file.

how-to-create-microsoft-word-documents-in-a-zip-in-odoo-16-2-cybrosys

The document report will be downloaded as a zip file by clicking the print button. The system's local storage shows the downloaded ZIP file.

how-to-create-microsoft-word-documents-in-a-zip-in-odoo-16-3-cybrosys

Using an external ZIP Extractor program, you can extract the ZIP file to get the specific field that is embedded within it.

how-to-create-microsoft-word-documents-in-a-zip-in-odoo-16-4-cybrosys

The generated report will depict the extraction of the ZIP file.

how-to-create-microsoft-word-documents-in-a-zip-in-odoo-16-5-cybrosys

When you open the extracted folder, you can find the generated documents.

Open each document or attached file to view the contents.

Document 1:

how-to-create-microsoft-word-documents-in-a-zip-in-odoo-16-6-cybrosys

Document 2 :

how-to-create-microsoft-word-documents-in-a-zip-in-odoo-16-7-cybrosys

In this way, you can generate word reports that are inside a ZIP file in Odoo 16, which can be further extracted to local storage.

To read more about generating Microsoft Word documents in a zip in Odoo 15, refer to our blog How To Generate Microsoft Word Documents in a Zip In Odoo 15


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



0
Comments



Leave a comment



whatsapp
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