Может ли <condPageBreak height = '? Cm'> динамически меняться?

У меня есть <blockTable> это изменение размера в зависимости от ввода пользователя.
Я хочу продолжить рисование на следующей странице, если на той же странице недостаточно места для рисования таблицы.

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

Как я могу изменить blockTable height перейти на следующую страницу, если на текущей странице недостаточно места?

2 ответа

Решение

Нет способа сделать это из condPageBreak тег.

Но вы можете расширить парсер PDF, получить RML код и рассчитать blockTable Затем сохраните изменения перед вызовом:

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

Для этого нужно добавить <condPageBreak height="?"/> до <blockTable ...> тег в отчете RML и в использовании парсера 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
)

Я не уверен насчет динамического изменения или разрыва страницы. Но я использую ниже метод. Может быть, это будет полезно для вас.

Попробуйте с помощью этих отчетов RML.

<condPageBreak/> Тег является "условным разрывом страницы". Чтобы использовать его, вы задаете ему высоту в любых единицах, которые может обрабатывать RML.

Затем он сравнивает эту высоту с оставшимся доступным пространством на странице. Если места достаточно, то следующие элементы помещаются на текущую страницу, но если места меньше, чем высота, которую вы ей дали, после <condPageBreak/> продолжение на следующей странице

<condPageBreak/> имеет только один атрибут - обязательный атрибут высоты

Например:

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

Для более подробной информации: руководство пользователя RML

НОТА:

Используйте приведенные выше примеры перед началом <blockTable> тег

Например:

<condPageBreak height="1in"/>
    <blockTable style="Table4">
    .
    .
    .
    </blockTable>
Другие вопросы по тегам