如何在qWeb报告中设置PDF名称,Odoo?

时间:2015-05-27 14:28:23

标签: report odoo-8 qweb

我在Odoo 8中使用qWeb进行报告。这些生成的PDF文件以“默认”名称保存。我想为每个生成的文件设置一个特定的名称(不是在保存文件之后,而是在“生成”时间内)。

这可能吗?如果是,怎么做?

提前致谢。

8 个答案:

答案 0 :(得分:3)

在Odoo 8中,您可以修改addons / report / controllers / main.py的方法report_download,如下所示(在FIX START和END之间)。然后,它将在报告操作定义中使用附件属性的代码。由于系统将始终将文件另存为数据库中的附件,因此当attachment_use设置为True时,您可以进一步更改行为以仅保存在数据库中。这样就不需要添加额外的字段并改变视图。

@route(['/report/download'], type='http', auth="user")
def report_download(self, data, token):
    """This function is used by 'qwebactionmanager.js' in order to trigger the download of
    a pdf/controller report.

    :param data: a javascript array JSON.stringified containg report internal url ([0]) and
    type [1]
    :returns: Response with a filetoken cookie and an attachment header
    """
    requestcontent = simplejson.loads(data)
    url, type = requestcontent[0], requestcontent[1]
    try:
        if type == 'qweb-pdf':
            reportname = url.split('/report/pdf/')[1].split('?')[0]

            docids = None
            if '/' in reportname:
                reportname, docids = reportname.split('/')

            if docids:
                # Generic report:
                response = self.report_routes(reportname, docids=docids, converter='pdf')
                ##### FIX START: switch reportname with the evaluated attachment attribute of the action if available
                docids = [int(i) for i in docids.split(',')]
                report_obj = request.registry['report']
                cr, uid, context = request.cr, request.uid, request.context
                report = report_obj._get_report_from_name(cr, uid, reportname)
                if report.attachment:
                    obj = report_obj.pool[report.model].browse(cr, uid, docids[0])
                    reportname=eval(report.attachment, {'object': obj, 'time': time}).split('.pdf')[0]
                ##### FIX END    
            else:
                # Particular report:
                data = url_decode(url.split('?')[1]).items()  # decoding the args represented in JSON
                response = self.report_routes(reportname, converter='pdf', **dict(data))

            response.headers.add('Content-Disposition', 'attachment; filename=%s.pdf;' % reportname)
            response.set_cookie('fileToken', token)
            return response
        elif type =='controller':
            reqheaders = Headers(request.httprequest.headers)
            response = Client(request.httprequest.app, BaseResponse).get(url, headers=reqheaders, follow_redirects=True)
            response.set_cookie('fileToken', token)
            return response
        else:
            return
    except Exception, e:
        se = _serialize_exception(e)
        error = {
            'code': 200,
            'message': "Odoo Server Error",
            'data': se
        }
        return request.make_response(html_escape(simplejson.dumps(error))) 

您可以通过以下方式设置报告操作的附件属性:

<?xml version="1.0" encoding="UTF-8"?>
<openerp>
  <data>
    <!-- rename the file names of the standard rfq report -->
        <record id="purchase.report_purchase_quotation" model="ir.actions.report.xml">
            <field name="attachment">'RFQ_'+object.name+'.pdf'</field>
        </record>    
   </data>
</openerp> 

这是addons / report / report.py中Report对象的_check_attachment补丁,用于修改attachment_use行为:

@api.v7
def _check_attachment_use(self, cr, uid, ids, report):
    """ Check attachment_use field. If set to true and an existing pdf is already saved, load
    this one now. Else, mark save it.
    """
    save_in_attachment = {}
    save_in_attachment['model'] = report.model
    save_in_attachment['loaded_documents'] = {}

    if report.attachment:
        for record_id in ids:
            obj = self.pool[report.model].browse(cr, uid, record_id)
            filename = eval(report.attachment, {'object': obj, 'time': time})

            # If the user has checked 'Reload from Attachment'
            if report.attachment_use:
                alreadyindb = [('datas_fname', '=', filename),
                               ('res_model', '=', report.model),
                               ('res_id', '=', record_id)]
                attach_ids = self.pool['ir.attachment'].search(cr, uid, alreadyindb)
                if attach_ids:
                    # Add the loaded pdf in the loaded_documents list
                    pdf = self.pool['ir.attachment'].browse(cr, uid, attach_ids[0]).datas
                    pdf = base64.decodestring(pdf)
                    save_in_attachment['loaded_documents'][record_id] = pdf
                    _logger.info('The PDF document %s was loaded from the database' % filename)

                    continue  # Do not save this document as we already ignore it

            # FIX START (commenting out below lines and indenting the else clause one level down)
            # If the user has checked 'Save as Attachment Prefix'
            #~ if filename is False:
                #~ # May be false if, for instance, the 'attachment' field contains a condition
                #~ # preventing to save the file.
                #~ continue
                else:
                    save_in_attachment[record_id] = filename  # Mark current document to be saved
            # FIX END
    return save_in_attachment  

答案 1 :(得分:3)

您可以使用'自定义文件名'模块

  1. 下载模块
  2. https://www.odoo.com/apps/modules/8.0/report_custom_filename/
  3. 更改设置中的名称 - &gt;行动 - &gt;报告
  4. 选择您的报告并更改名称..

答案 2 :(得分:2)

在一般Qweb报告菜单中,您可以在Odoo 8.0中打印Qweb报告

<?xml version="1.0" encoding="utf-8"?>
<openerp>
    <data>
        <report 
            id="report_sale_order"
            string="Quotation / Order"
            model="sale.order" 
            report_type="qweb-pdf"
            file="sale.report_saleorder" 
            name="sale.report_saleorder" 
        />
    </data>
</openerp>

<report>标记中,具有在Qweb中打印报告的不同属性 如果您想更改打印的PDF 的名称,则名称属性对我们来说更为重要。

根据名称属性我们的报告PDF文件名称听到了 一般来说,您应该根据 your_module_name.report_name

设置名称属性。

如果要更改PDF文件的自定义名称,请根据甜蜜的报告名称更改名称属性。

我希望这对你有用..:)

答案 3 :(得分:2)

<强>插件\报告\控制器\ main.py

行:127

response.headers.add('Content-Disposition', 'attachment; filename=%s.pdf;' % reportname)

更改它
invoicename="ma_facture" #create a variable you can add date for example stfftime("%d-%m-%Y")
response.headers.add('Content-Disposition', 'attachment; filename=%s.pdf;' % invoicename)

答案 4 :(得分:2)

我认为这是一个在版本9中修复的错误。只需用此https://github.com/odoo/odoo/blob/9.0/addons/report/controllers/main.py替换addons \ _sport \ _control \ main.py的内容,然后重新启动odoo服务器

答案 5 :(得分:2)

<report 
      id="report_sale_order"
      string="Quotation / Order"
      model="sale.order" 
      report_type="qweb-pdf"
      file="sale.report_saleorder" 
      name="sale.report_saleorder" 
/>

对于字符串名称是正确的是打印PDF名称已完成

答案 6 :(得分:2)

您可以使用配置提供动态报告名称,但在打印一份报告时将适用。

以下是报告中打印自定义名称的示例。创建 ir.actions.report.xml 中的一个字段,在该用户中可以配置报告名称

from openerp import models, fields
class IrActionsReportXml(models.Model):
    _inherit = 'ir.actions.report.xml'

    download_filename = fields.Char(
        'Download filename')

现在你需要创建两个文件。

  1. 报告控制器

    from openerp import http
    from openerp.addons.mail.models import mail_template
    from openerp.addons.report.controllers.main import ReportController
    from openerp.addons.web.controllers.main import content_disposition
    
    
    class ReportController(ReportController):
        @http.route([
            '/report/<path:converter>/<reportname>',
            '/report/<path:converter>/<reportname>/<docids>',
        ])
        def report_routes(self, reportname, docids=None, converter=None, **data):
            response = super(ReportController, self).report_routes(
                reportname, docids=docids, converter=converter, **data)
            if docids:
                docids = [int(i) for i in docids.split(',')]
            report_xml = http.request.session.model('ir.actions.report.xml')
            report_ids = report_xml.search(
                [('report_name', '=', reportname)])
            for report in report_xml.browse(report_ids):
                if not report.download_filename:
                    continue
                objects = http.request.session.model(report.model)\
                    .browse(docids or [])
                generated_filename = mail_template.mako_template_env\
                    .from_string(report.download_filename)\
                    .render({
                        'objects': objects,
                        'o': objects[:1],
                        'object': objects[:1],
                        'ext': report.report_type.replace('qweb-', ''),
                    })
                response.headers['Content-Disposition'] = content_disposition(
                    generated_filename)
            return response
    
        @http.route(['/report/download'])
        def report_download(self, data, token):
            response = super(ReportController, self).report_download(data, token)
            # if we got another content disposition before, ditch the one added
            # by super()
            last_index = None
            for i in range(len(response.headers) - 1, -1, -1):
                if response.headers[i][0] == 'Content-Disposition':
                    if last_index:
                        response.headers.pop(last_index)
                    last_index = i
            return response
    
  2. 2.Report.py

        import json
        from openerp import http
        from openerp.addons.web.controllers import main
        from openerp.addons.mail.models import mail_template
    
    
        class Reports(main.Reports):
            @http.route('/web/report', type='http', auth="user")
            @main.serialize_exception
            def index(self, action, token):
                result = super(Reports, self).index(action, token)
                action = json.loads(action)
                context = dict(http.request.context)
                context.update(action["context"])
                report_xml = http.request.env['ir.actions.report.xml']
                reports = report_xml.search([
                    ('report_name', '=', action['report_name']),
                    ('download_filename', '!=', False)])
                for report in reports:
                    objects = http.request.session.model(context['active_model'])\
                        .browse(context['active_ids'])
                    generated_filename = mail_template.mako_template_env\
                        .from_string(report.download_filename)\
                        .render({
                            'objects': objects,
                            'o': objects[0],
                            'object': objects[0],
                        })
                    result.headers['Content-Disposition'] = main.content_disposition(
                        generated_filename)
                return result
    

    Odoo社区为我们提供报告自定义名称的默认模块。您可以直接安装此模块并设置报告名称,如:$ {o.name}

    这里o表示您的记录。

    以下是V8和V9的odoo社区模块的链接。

    https://www.odoo.com/apps/modules/9.0/report_custom_filename/

    https://www.odoo.com/apps/modules/8.0/report_custom_filename/ 这可能会对你有帮助。

答案 7 :(得分:0)

在Odoo v10中更改报告PDF文件名的简便方法:

只需在编写报告标记的位置添加此代码,并在报告和新添加的记录中同时提供相同的ID。如下所示:

<report id="report_quote_temp" string="Quote Template" model="sale.order" report_type="qweb-pdf"
    file="custom_template.report_quote_custom" name="custom_template.report_quote_custom"
    menu="True" paperformat="custom_template.custom_paperformat" />

<record id="report_quote_temp" model="ir.actions.report.xml">
    <field name="print_report_name">'SALES_'+object.name+'.pdf'</field>
</record>

它会将报告文件打印为SALES_SO004.pdf,其中SO004是您的销售或报价编号。