6

reportlab を使用して、いくつかの複雑な PDF 出力を処理してきました。これらは通常は問題ありませんが、LayoutErrors が発生するケースがまだいくつかあります。これは通常、ある時点で Flowables が大きすぎるためです。

このようなものよりも多くの情報を持っていないことが多いため、これらをデバッグするのはかなり難しいことが証明されています。

Flowable <Table@0x104C32290 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全体を失敗させるだけではなく?
  • このような問題の一般的な改善、テスト、および処理に関するその他の提案。

特定の例がないので、より一般的なアドバイスです。上記の例外は解決しましたが、試行錯誤の結果です(読んで、何が起こるかを推測して見てください)。

4

2 に答える 2

4

フロー可​​能なオブジェクトを再利用していないことを確認してください (共通のテンプレート パーツを使用してドキュメントの複数のバージョンをレンダリングするなど)。これは ReportLab ではサポートされていないため、このエラーが発生する可能性があります。

その理由は、ReportLab がレイアウトの実行時にこれらのオブジェクトに属性を設定して、それらを別のページに移動する必要があることを示すためと思われます。2 回移動する必要がある場合は、その例外がスローされます。これらの属性は、ドキュメントをレンダリングしてもリセットされないため、実際には移動していないオブジェクトが別のページに 2 回移動したように見えることがあります。

以前、属性を手動でリセットすることでこの問題を回避しました (今は名前を思い出せません。'_deferred' か何かでした)。レンダリングされます。

于 2010-08-25T14:09:12.990 に答える
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 でエラー メッセージを検索し、それに応じて入力を修正することを忘れないでください。

于 2010-08-19T15:05:37.877 に答える