生成Odoo可下载的CSV报告

时间:2017-02-03 10:45:50

标签: export-to-csv odoo-8

我需要在销售订单表格视图中提供一个按钮,将订单行导出为具有特定格式的CSV。我搜索了很多,但我发现自定义模块不能满足解决方案,因为用户不必选择字段。

更新:解决方案

我最终做了以下解决方案,感谢@ phillip-stack和his answer

模型

# -*- coding: utf-8 -*-
from openerp import http
from openerp.http import request
from openerp.addons.web.controllers.main import serialize_exception,content_disposition

class SaleOrderController(http.Controller):
    @http.route('/csv/download/sale_order/<int:order_id>/supplier_name/<string:supplier_name>', auth='user')
    def sale_order_lines_csv_download(self, order_id, supplier_name, **kw):
        if supplier_name:
            csv = http.request.env['sale.order']._csv_download({'order_id': order_id, 'supplier_name':supplier_name})
        else:
            csv = http.request.env['sale.order']._csv_download({'order_id': order_id, 'supplier_name': False})
        filename = 'order_lines_%s_%s.csv'%(order_id,supplier_name)

        return request.make_response(csv,
                                        [('Content-Type', 'application/octet-stream'),
                                         ('Content-Disposition', 'attachment; filename="%s"'%(filename))])

控制器

    //here myLabel is the object of UILabel
    //added this from @warly's answer
    //set font of attributedText
    let attributedText = NSMutableAttributedString(attributedString: myLabel!.attributedText!)
    attributedText.addAttributes([NSFontAttributeName: myLabel!.font], range: NSMakeRange(0, (myLabel!.attributedText?.string.characters.count)!))

    // Create instances of NSLayoutManager, NSTextContainer and NSTextStorage
    let layoutManager = NSLayoutManager()
    let textContainer = NSTextContainer(size: CGSize(width: (myLabel?.frame.width)!, height: (myLabel?.frame.height)!+100))
    let textStorage = NSTextStorage(attributedString: attributedText)

    // Configure layoutManager and textStorage
    layoutManager.addTextContainer(textContainer)
    textStorage.addLayoutManager(layoutManager)

    // Configure textContainer
    textContainer.lineFragmentPadding = 0.0
    textContainer.lineBreakMode = myLabel!.lineBreakMode
    textContainer.maximumNumberOfLines = myLabel!.numberOfLines
    let labelSize = myLabel!.bounds.size
    textContainer.size = labelSize

    // get the index of character where user tapped
    let indexOfCharacter = layoutManager.characterIndex(for: tapLocation, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

1 个答案:

答案 0 :(得分:3)

我可能不应该承认这一点。但我使用控制器技术并添加表单链接。可以修改控制器以根据您的选择进行自定义安全检查,然后您可以使用sudo()绕过对相关模型的字段限制。然后以您选择的格式返回csv。

当然......一个例子!

CONTROLLER

@http.route('/csv/download/<int:rec_id>/', auth='user', website=True)
def csvdownload(self, rec_id, **kw):
    return http.request.env['your_addon.your_model']._csv_download({'rec_id': rec_id})

模型方法

def _get_csv_url(self):
    self.csv_url = "/csv/download/{}/".format(self.id)

csv_url = fields.Char(compute=_get_csv_url)

@api.model
def _csv_download(self,vals):
    sql = """SELECT 
                 quote_nullable(field_1),
                 quote_nullable(field_2),
                 quote_nullable(field_3),
                 quote_nullable(field_4)
             FROM
                 table_name
             WHERE id={}""".format(vals.get(rec_id))
    self.env.cr.execute(sql)
    rows = self.env.cr.fetchall()
    csv = """'Field 1','Field 2','Field 3','Field 4'\n"""
    if rows:
        for row in rows:
            csv_row = ""
            for item in row:
                csv_row+= "{},".format(item)
            csv+="{}\n".format(csv_row[:-1])
    return csv   

在您的表单中有一个指向您的控制器的链接

<a id="csv_download" href="#" target="_blank" download="file.csv"/>

<div id="csv_url_div" style="display:none"><field name="csv_url"/></div>

<script>
$(document).ready(function(){
    var csv_url = $("#csv_url_div").text();
    $("#csv_download").attr("href", csv_url);
});
</script> 

我承认这里正在发生的hackyness程度。我相信如果我花更多的时间在上面,我可以做一些漂亮的Odoo小部件,这将是相当不错的。但它对我有用。