2010-06-18 3 views
6

Я работаю с некоторыми сложными выводами PDF с помощью reportlab. Они вообще прекрасны, но есть некоторые случаи, когда я получаю LayoutErrors - это обычно потому, что Flowables слишком велики в какой-то момент.Обработка и отладка ReportLab LayoutError

Это доказывает, что их довольно сложно отладить, поскольку я не часто получаю больше информации, чем нечто подобное;

Flowable <[email protected] 4 rows x 6 cols> with cell(0,0) containing 
'<Paragraph at 0x104df2ea8>Authors'(789.0 x 1176) too large on page 5 in frame 'normal'(801.543307087 x 526.582677165*) of template 'Later' 

Это действительно не так уж полезно. То, что я хотел бы лучше всего знать, - это лучшая стратегия отладки и тестирования этой подобной вещи.

  • Есть ли способ просмотреть разбитый PDF-файл? то есть визуализируются с ошибками макета, поэтому я могу видеть, что происходит более легко.
  • Есть ли способ добавить крючок в reportlab, чтобы лучше справляться с этими ошибками? Вместо того, чтобы просто проваливать весь PDF-файл?
  • Любые другие предложения об улучшении, тестировании и обработке таких проблем.

У меня нет конкретного примера, поэтому его более общий совет, исключение выше, которое я разрешил, но его вид с помощью проб и ошибок (читайте, угадывайте и смотрите, что происходит).

ответ

2

У нас возникла проблема при использовании Reportlab для форматирования некоторого контента, который был изначально html, а иногда html был слишком сложным. Решение (и я не беру на себя никакой ответственности, это было от парней в Reportlab) заключалось в том, чтобы поймать ошибку, когда она произошла, и вывести ее непосредственно в PDF-файл.

Это означает, что вы видите причину проблемы в правильном контексте. Вы могли бы расширить на этом для вывода деталей, за исключением, но в нашем случае, так как нашей проблемы было преобразование HTML в RML мы просто должны были показать наш вход:

Лобовое опрятный шаблон содержит следующее:

{{script}} 
#This section contains python functions used within the rml. 
#we can import any helper code we need within the template, 
#to save passing in hundreds of helper functions at the top 
from rml_helpers import blocks 
{{endscript}} 

и потом биты шаблона, как:

{{if equip.specification}} 
<condPageBreak height="1in"/> 
     <para style="h2">Item specification</para> 
     {{blocks(equip.specification)}} 
    {{endif}} 

В rml_helpers.py мы имеем:

from xml.sax.saxutils import escape 
from rlextra.radxml.html_cleaner import cleanBlocks 
from rlextra.radxml.xhtml2rml import xhtml2rml 

def q(stuff): 
    """Quoting function which works with unicode strings. 

    The data from Zope is Unicode objects. We need to explicitly 
    convert to UTF8; then escape any ampersands. So 
     u"Black & Decker drill" 
    becomes 
     "Black &amp; Decker drill" 
    and any special characters (Euro, curly quote etc) end up 
    suitable for XML. For completeness we'll accept 'None' 
    objects as well and output an empty string. 

    """ 
    if stuff is None: 
     return '' 
    elif isinstance(stuff,unicode): 
     stuff = escape(stuff.encode('utf8')) 
    else: 
     stuff = escape(str(stuff)) 
    return stuff.replace('"','&#34;').replace("'", '&#39;') 

def blocks(txt): 
    try: 
     txt2 = cleanBlocks(txt) 
     rml = xhtml2rml(txt2) 
     return rml 
    except: 
     return '<para style="big_warning">Could not process markup</para><para style="normal">%s</para>' % q(txt) 

Итак, все, что слишком сложно для xhtml2rml, обрабатывает исключение и заменяется на выходе большим предупреждением «Не удалось обработать разметку», за которым следует разметка, вызвавшая ошибку, сбежала, поэтому она отображается как буквальная.

Тогда все, что нам нужно сделать, это запомнить поиск выходного PDF-сообщения для сообщения об ошибке и исправление ввода соответствующим образом.

4

Убедитесь, что вы не используете повторно какие-либо ваши текущие объекты (как, например, рендеринг нескольких версий документа с использованием общих частей шаблона). Это не поддерживается ReportLab и может вызвать эту ошибку.

Причина заключается в том, что ReportLab установит атрибут этих объектов при выполнении макета, чтобы указать, что это необходимо для перемещения их на отдельную страницу. Если он должен быть перемещен дважды, он выкинет это исключение. Эти атрибуты не сбрасываются при рендеринге документа, поэтому может показаться, что объект был перемещен на отдельную страницу дважды, когда это действительно не так.

Я взломал это раньше, сбросив атрибут вручную (я не могу запомнить имя прямо сейчас, это было «_deferred» или что-то еще), но правильный подход заключается в том, чтобы выкинуть любые объекты, которые вы использовали для рендеринга документ после его рендеринга.

+0

Конечно, моя проблема решена. Благодаря! Надеюсь, это помогло и ОП. – arikb

+0

Спасибо! Я был готов отказаться от ReportLab из-за этого «случайного», что я, похоже, не мог решить. Но это то, что мне нужно. – MinchinWeb

Смежные вопросы