web-dev-qa-db-ja.com

Reportlab:PDFファイルにフッターを追加する方法

私はすでにこれを尋ねました 質問 しかしまだ答えがないので、活発に開発されており、fpdf python libraryよりも優れているように見えるReportlabを見てみたいと思います。

私はすでにこれを見ました 質問 与えられた答えはこれと多かれ少なかれ同じようです ブログ投稿 。とにかく、示されているスクリプトはエラーでいっぱいですが、私はそれを投票したくありません、OPはそれを受け入れ、彼の問題を解決したようでした、私は主張します、私はむしろ別の質問をしたいと思います。

まず、インポートする必要があります

_from reportlab.pdfgen.canvas import Canvas
_

そしてそれはcanvasではありませんそれはCanvasですそしてあなたはただすることはできません

Canvas.restoreState()またはCanvas.saveState()

エラーがもっとあるかもしれませんが、別の例を使用したいと思います。私は昨日、そのスニペットを機能させるために一晩中過ごしましたが、機能しませんでした。

フッターを作成する別の方法はありますか?私が聞きたい具体的な方法は this 、男はforループを実行し、_row[0]_で何かを書きます。_row[1]_何か

_Liberation Serif_ 12を使用して、A4であるLibreOfficeドキュメントを頼りにしました。49行あります。フォントサイズに応じて平均45行あり、フッターのフォントサイズが8であるとすると、この_x=row[45]_のようにフッターを挿入し、ページ番号に基づいてxをインクリメントすることはできませんか?それははるかに簡単な解決策ではないでしょうか?

ファイルの終わり、またはテキストが挿入されている最後の行を検出できれば、それを実行できると思います。

私の他の質問を参照すると、PowerPoint、Excel、およびWordをPDFに変換してから、フッターを挿入していることに気付くでしょう。

LinuxとWindowsで動作するライブラリがあり、PowerPointとExcelをWordに変換し、フッターを追加してからpdfに変換する場合は、ドキュメントよりもPDFの方が操作しやすいと思います。

12
Lynob

まず第一に、Reportlabは素晴らしいです。 PDFを生成するために私が見つけた最高のライブラリ。

例を試す前に、reportlabをインストールしてください。

pip install reportlab

脚注を作成するには、multibuildを使用してドキュメントをレンダリングし、canvasmakerを使用してフッターを追加する必要があります。

まず、2ページの簡単なPDFファイルを作成しましょう。

from reportlab.platypus import (SimpleDocTemplate, Paragraph, PageBreak)
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.pagesizes import LETTER


if __name__ == '__main__':

    # Content
    styles = getSampleStyleSheet()
    elements = []
    elements.append(Paragraph("Hello", styles["Normal"]))
    elements.append(Paragraph("World", styles["Normal"]))
    elements.append(PageBreak())
    elements.append(Paragraph("You are in page 2", styles["Normal"]))

    # Build
    doc = SimpleDocTemplate("my_file.pdf", pagesize=LETTER)
    doc.build(elements)

PDFファイルが正しく作成されていることを確認してください。

次に、キャンバスクラスを追加して、行番号とページ番号を示すフッターを描画し、最後の行でビルドをマルチビルドに変更します。

from reportlab.pdfgen import canvas
from reportlab.platypus import (SimpleDocTemplate, Paragraph, PageBreak)
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.pagesizes import LETTER


class FooterCanvas(canvas.Canvas):

    def __init__(self, *args, **kwargs):
        canvas.Canvas.__init__(self, *args, **kwargs)
        self.pages = []

    def showPage(self):
        self.pages.append(dict(self.__dict__))
        self._startPage()

    def save(self):
        page_count = len(self.pages)
        for page in self.pages:
            self.__dict__.update(page)
            self.draw_canvas(page_count)
            canvas.Canvas.showPage(self)
        canvas.Canvas.save(self)

    def draw_canvas(self, page_count):
        page = "Page %s of %s" % (self._pageNumber, page_count)
        x = 128
        self.saveState()
        self.setStrokeColorRGB(0, 0, 0)
        self.setLineWidth(0.5)
        self.line(66, 78, LETTER[0] - 66, 78)
        self.setFont('Times-Roman', 10)
        self.drawString(LETTER[0]-x, 65, page)
        self.restoreState()


if __name__ == '__main__':

    # Content
    styles = getSampleStyleSheet()
    elements = []
    elements.append(Paragraph("Hello", styles["Normal"]))
    elements.append(Paragraph("World", styles["Normal"]))
    elements.append(PageBreak())
    elements.append(Paragraph("You are in page 2", styles["Normal"]))

    # Build
    doc = SimpleDocTemplate("my_file.pdf", pagesize=LETTER)
    doc.multiBuild(elements, canvasmaker=FooterCanvas)

マルチビルドでは、次の場合に最初のページに別のキャンバスを指定することもできます。

doc.multiBuild(Elements, onFirstPage=myFirstPage, onLaterPages=myLaterPages)

お役に立てれば。

[〜#〜]編集[〜#〜]

現在の目標は、既存のpdfファイルにフッターを追加することです。残念ながら、これはReportlabだけでは実行できません(少なくともオープンソースバージョンでは、プロフェッショナルバージョンにこの機能があると思います)。

最初に、レシピに少し追加する必要がありますpdfrw

pip install pdfrw

これで、既存のpdfにフッターを追加できます。元のpdfを開き、ページを抽出し、フッターに沿ってページを新しいpdfに一度に1ページずつ「描画」します。

from reportlab.pdfgen.canvas import Canvas
from pdfrw import PdfReader
from pdfrw.toreportlab import makerl
from pdfrw.buildxobj import pagexobj

input_file = "my_file.pdf"
output_file = "my_file_with_footer.pdf"

# Get pages
reader = PdfReader(input_file)
pages = [pagexobj(p) for p in reader.pages]


# Compose new pdf
canvas = Canvas(output_file)

for page_num, page in enumerate(pages, start=1):

    # Add page
    canvas.setPageSize((page.BBox[2], page.BBox[3]))
    canvas.doForm(makerl(canvas, page))

    # Draw footer
    footer_text = "Page %s of %s" % (page_num, len(pages))
    x = 128
    canvas.saveState()
    canvas.setStrokeColorRGB(0, 0, 0)
    canvas.setLineWidth(0.5)
    canvas.line(66, 78, page.BBox[2] - 66, 78)
    canvas.setFont('Times-Roman', 10)
    canvas.drawString(page.BBox[2]-x, 65, footer_text)
    canvas.restoreState()

    canvas.showPage()

canvas.save()

[〜#〜]免責事項[〜#〜]:Reportlabによって生成されたpdfファイルを入力ファイルとして使用してLinuxでテストされました。おそらく、任意のpdfファイルでは機能しません。

15
Juan Fco. Roco