Hello, I need to output a file on the server so that users can download it on their machines. How can I do this in Odoo?
Odoo is the world's easiest all-in-one management software.
It includes hundreds of business apps:
- CRM
- e-Commerce
- Accounting
- Inventory
- PoS
- Project management
- MRP
This question has been flagged
Probably the best solution is to create it server side, base64 encode it, and attach it to relevant document...
For simplicity here is example..
Let's say you want some xml report...
1. you generate the xml_string then you pass it to a method like this:
def _attach_xml_file(self, cr, uid, ids, xml_string, context=None):
import base64
assert len(ids) == 1, "Only one ID accepted"
model_obj= self.pool.get('your.model') # the model of record you want file attached
record_obj= model_obj.browse(cr, uid, ids[0]) # actual record to wich you attach file
file_name = 'name_your_file_here.xml'
attach_name = file_name
attach_obj = self.pool.get('ir.attachment')
context.update({'default_res_id': ids[0],
'default_res_model': 'your.model'})
attach_id = attach_obj.create(cr, uid, {'name': attach_name,
'datas': base64.encodestring(xml_string),
'datas_fname': file_name}, context=context)
return attach_id
2. now yout file is attached to "record_obj" of "your.model"
Example: you need some additional conditions in xml form attached to sale order then your.model = sale.order, and record_obj is the id of selected order...
3. File is accesible for download to client via Attachment button (top of order view)
hope it helps...
Thank you for your reply. In my case I wanted to stay away from the ir.attachments model, but all i needed to do was read the file I created into a string variable. Then pass the string into the base64.encodestring(string_variable). Now I am able to download the file from the new model that I created. Thank you for your help
First I added these two lines in the top of my python file
import io # used to output a file with exported data
import base64 # used to encode the contents of the exported file in binary form. this is used to download the file once its created
Fields Added in _columns { } on the python file:
"file_name": fields.char( "File Name" )
"file_binary": fields.binary( "Binary File" )
Code written in create()
I used the create method to save the new record with the binary data
def create(self, cr, uid, vals, context=None):
# code goes in here...
Create the file:
Then I created the file like this in write mode
file_obj = open( "c:\Users\name_of_file.txt", "w")
file_obj.write( "some sample text..." )
file_obj.close()
Read file and encode with base64
# Re open the file_obj in read mode
file_obj = open( "c:\Users\name_of_file.txt", "r")
file_string = file_obj.read()
vals[ "file_binary" ] = base64.encodestring( file_string ) # Assuming this is in the create() and using the vals{ } to save the data
file_obj.close()
Create record with the filename and binary file data
new_id = super(current_model_used, self).create(cr, uid, vals, context)
XML form and tree views
Add the new fields on the form and tree views like this. This way when you download the file, then the file name will be used.
< field name="file_name" />
< field name="file_binary" filename="file_name" /> <!-- notice the filename attribute. Use this to set the file name with "file_name" field-->
The end. Hope this helps!
Probably the best solution is to create it server side, base64 encode it, and attach it to relevant document...
For simplicity here is example..
Let's say you want some xml report...
1. you generate the xml_string then you pass it to a method like this:
def _attach_xml_file(self, cr, uid, ids, xml_string, context=None):
import base64
assert len(ids) == 1, "Only one ID accepted"
model_obj= self.pool.get('your.model') # the model of record you want file attached
record_obj= model_obj.browse(cr, uid, ids[0]) # actual record to wich you attach file
file_name = 'name_your_file_here.xml'
attach_name = file_name
attach_obj = self.pool.get('ir.attachment')
context.update({'default_res_id': ids[0],
'default_res_model': 'your.model'})
attach_id = attach_obj.create(cr, uid, {'name': attach_name,
'datas': base64.encodestring(xml_string),
'datas_fname': file_name}, context=context)
return attach_id
I hope you are looking this: http://learnopenerp.blogspot.com/2020/06/write-binary-data-nto-zip-file-and-downlaod-it-on-button-click-in-odoo.html