Может ли <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>