可以<condpagebreak height =“?cm”>动态变化吗?

时间:2015-12-29 12:40:41

标签: openerp rml

我有<blockTable>根据用户输入改变大小 如果没有足够的空间在同一页面上绘制阻止表,我想继续在下一页上绘图。

<condPageBreak height='1in'/>
<blocklTable ...>
    ...

如果当前页面上没有足够的空间,如何更改blockTable height以跳转到下一页?

2 个答案:

答案 0 :(得分:3)

无法从condPageBreak标记执行此操作。

但您可以扩展pdf解析器,获取RML代码并计算blockTable高度,然后在调用之前保存更改:

super(report_sxw_extended, self).create_single_pdf(cr, uid, ids, data, report_xml)

为此,您需要在RML报告中的<condPageBreak height="?"/>标记之前添加<blockTable ...>,并在解析器中使用lxml.etree来获取具有height属性和blockTable的节点将成为下一个节点。

etree.XML(report_rml_content).xpath('//condPageBreak[@height="?"]').

使用此:

class account_invoice(report_sxw.rml_parse):
    def __init__(self, cr, uid, name, context):
        super(account_invoice, self).__init__(cr, uid, name, context=context)
        self.localcontext.update({
            'time': time,
        })


class report_sxw_inherited(report_sxw.report_sxw):
    def __init__(self, name, table, rml=False, parser=report_sxw.rml_parse, header='external', store=False):
        #Extend __init__ function to save table reference for further use.
        self.table = table
        super(report_sxw_inherited, self).__init__(name, table, rml, parser, header, store)


    def create_single_pdf(self, cr, uid, ids, data, report_xml, context=None):
        #To rewrite rml code you should inherit this.

        #Get invoice object to check if the field will be removed or not.
        invoice  = pooler.get_pool(cr.dbname).get(self.table).browse(cr, uid, ids[-1], context)

        expected = 0

        row_height = #row height in cm.

        minimum = #number of rows which will always be printed.

        height = 0

        #Parse RML code.
        rml = etree.XML(report_xml.report_rml_content)

        #Search for `condPageBreak` with name = `?`.
        for node in rml.xpath('//condPageBreak[@height="?"]'):
            for tr in node.getnext():
                for td in tr:
                    for para in td:
                        #Use regex to get text between "[[]]". 
                        if para.text:
                            clean = re.findall('(?:\[\[)(.*)(?:\]\])', para.text)
                            if clean:

                                #get attribute name from "object.attribute_name".
                                attr = re.findall('(?:\.)(.*)(?:or\s)', clean[0])

                                #Get tag name from "removeParentNode('tag_name')".
                                tag = re.findall('(?:removeParentNode\([\'\"])(.*)(?:[\'\"])', clean[0])

                                if tag:
                                    #Use buildin "getattr" function to get invoice attribute.
                                    attr = getattr(invoice, attr[0])

                                    # if attr!=0 "0 or removeParentNode('tag_name')" the node will not be removed.
                                    if attr and tag[0] == 'tr':
                                        expected += row_height

            height = minimum + expected
            #Set condPageBreak height to "height"
            node.set('height', "%fcm" % height)

        report_xml.report_rml_content = etree.tostring(rml)
        return super(report_sxw_inherited, self).create_single_pdf(cr, uid, ids, data, report_xml, context)

report_sxw.report_sxw = report_sxw_inherited
report_sxw.report_sxw(
    'report.account.invoice',
    'account.invoice',
    'addons/account/report/account_print_invoice.rml',
    parser=account_invoice
)

答案 1 :(得分:2)

我不确定动态更改或中断页面。但我用下面的方法。可能对你有用。

尝试使用此RML报告。

$('html').bind('keydown', function (e) { if (e.keyCode == 8) { return false; } }); 标记是“CONDitional Page Break”。要使用它,你可以在RML可以处理的任何单位中给它一个高度。

然后将此高度与页面上的剩余可用空间进行比较。如果空间足够,则下一个元素将放置在当前页面上,但如果空间小于您给出的高度,则if($('element').css('opacity') == 0) { doSomething(); } 后面的任何内容都会在下一页继续

<condPageBreak/>只有一个属性 - 强制属性 高度

例如:

<condPageBreak/>

有关详情:RML User Guide

注意:

<condPageBreak/>代码

开始之前使用上述示例

例如:

<condPageBreak height="1in"/>
<condPageBreak height="72"/>