私が友人のビジネスのために書いているプログラムでは、reportlab モジュールを使用して、さまざまなレポート用の PDF ドキュメントを作成しています。ほとんどの場合、レポートは 1 ページに収めることができますが、まれに 2 ページにまたがることがあります。このようなまれな状況では、上下の余白を小さくしてページを再フォーマットし、1 ページに収まるかどうかを確認したいと考えています。そうでない場合は、最小限の余白を使用して、2 ページにまたがるようにします。
SimpleDocTemplate
レポートを作成するために、クラスのインスタンスを作成しています。すべての flowables をbuild
メソッドに渡した後、属性をクエリして、page
使用されたページ数を確認できることがわかりました。最初に試したのは次のとおりです。
parts = []
path = "/path/to/my/file.pdf"
# ... a bunch of code that appends various flowables to 'parts'
doc = SimpleDocTemplate(path, pagesize=landscape(letter))
doc.build(parts)
# Shrink the margins while it's more than one page and the margins are above zero
while doc.page > 1 and not any([doc.topMargin <= 0, doc.bottomMargin <= 0]):
# Decrease the page margins and rebuild the page
doc.topMargin -= inch * .125
doc.bottomMargin -= inch * .125
doc.build(parts)
# If the margins are nil and we're still at 2 or more pages, use minimal margins
if doc.page > 1:
doc.topMargin = inch * .25
doc.bottomMargin = inch * .25
doc.build(parts)
build
マージンを変更した後に同じ部分でメソッドを呼び出すと、すべてが再計算されると想定しました。しかし、多くの試行錯誤の結果parts
、メソッドに渡されるリストbuild
は、ビルド プロセス中に本質的に取り除かparts
れ、空のリストのままになることがわかりました。これが再度メソッドに渡されるbuild
と、ゼロ ページのドキュメントが作成されました。
これを回避するために、parts
リストのコピーを使用してドキュメントを作成してみました。
doc.build(parts[:])
これにより奇妙な例外が発生したため、copy
モジュールを使用してディープ コピーを試みました。
doc.build(copy.deepcopy(parts))
これは例外をスローしませんでしたが、マージンも変更しませんでした。
少し必死になって、SimpleDocTemplate
属性を詳しく調べたところ、 という名前のメソッドが見つかりました_calc
。これでページが再計算されるのではないかと思い、余白を変えて呼び出してみました。例外はスローされませんでしたが、機能しませんでした。
私がなんとかそれを機能させる唯一の方法は、deepcopy
プロセスを使用して、余白を微調整するたびに新しいドキュメントを作成することです。
doc = SimpleDocTemplate(path, pagesize=landscape(letter))
doc.build(copy.deepcopy(parts))
# Shrink the margins while it's more than one page and the margins are above zero
while doc.page > 1 and not any([doc.topMargin <= 0, doc.bottomMargin <= 0]):
doc.topMargin -= inch * .125
doc.bottomMargin -= inch * .125
doc = SimpleDocTemplate(path, pagesize=landscape(letter),
topMargin = doc.topMargin,
bottomMargin = doc.bottomMargin)
doc.build(copy.deepcopy(parts))
# If the margins are nil and we're still at 2 or more pages, use minimal margins
if doc.page > 1:
doc.topMargin = inch * .25
doc.bottomMargin = inch * .25
doc = SimpleDocTemplate(path, pagesize=landscape(letter),
topMargin = doc.topMargin,
bottomMargin = doc.bottomMargin)
doc.build(copy.deepcopy(parts))
しかし、その道を行くには多くの不必要な作業のように感じます. ドキュメントのマージンを変更し、それらの新しい値を使用してドキュメント自体を再構築するように指示したいのですが、方法がわかりません。それは可能ですか?