Mam program w języku Python, który generuje plik PDF za pomocą ReportLab i chciałbym wygenerować inny plik PDF, który jest sformatowany tak, aby każda strona była przecinana na pół, a następnie składana i zszywana razem w broszurę.

Na przykład, jeśli mój bieżący dokument zawiera strony A, B, C, D, E, F, G i H, chcę, aby nowy dokument miał dwie strony, które mogę wydrukować dwustronnie, aby wyglądały następująco:

BG|HA
DE|FC

Widziałem ten porządek określany jako 4-up lub imposition.

Moja drukarka ma opcję drukowania czterech stron na każdym arkuszu, ale nie zmienia kolejności stron. Jeśli wydrukuję bieżący dokument z tym ustawieniem i dwustronnie, wygląda to tak:

AB|EF
CD|GH

Moją pierwszą preferencją jest wygenerowanie pliku PDF z czterema stronami na arkusz, jak pokazano. Jeśli nie mogę tego rozgryźć, następną najlepszą rzeczą byłoby wygenerowanie pliku PDF ze zmienioną kolejnością stron, aby moja drukarka mogła wydrukować cztery strony na każdym arkuszu. Innymi słowy, zmień kolejność stron na B, G, D, E, H, A, F i C.

Oto przykład kodu, który drukuje osiem stron:

from subprocess import call

from reportlab.lib import pagesizes
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch
from reportlab.platypus import SimpleDocTemplate, Paragraph


def main():
    pdf_path = 'booklet.pdf'
    doc = SimpleDocTemplate(pdf_path,
                            pagesize=pagesizes.letter,
                            topMargin=0.625*inch,
                            bottomMargin=0.625*inch)
    styles = getSampleStyleSheet()
    paragraph_style = styles['Normal']
    print(paragraph_style.fontSize, paragraph_style.leading)
    paragraph_style.fontSize = 300
    paragraph_style.leading = 360
    story = []
    for text in 'ABCDEFGH':
        flowable = Paragraph(text, paragraph_style)
        story.append(flowable)

    doc.build(story)

    # call(["evince", pdf_path])  # launch PDF viewer


main()
0
Don Kirkby 17 grudzień 2019, 00:33

1 odpowiedź

Dzięki temu pytaniu mogłem zobaczyć, jak zbierać strony kanwy, zanim faktycznie zapiszę je w dokumencie. Dodałem trochę kodu, aby zmienić ich kolejność, a teraz mogę je wydrukować za pomocą dodatkowej opcji drukarki, aby uzyskać 4 strony na każdym arkuszu.

from subprocess import call

from reportlab.lib import pagesizes
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch
from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import SimpleDocTemplate, Paragraph


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

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

    def save(self):
        while len(self.pages) % 8 != 0:
            self.showPage()
        original_pages = self.pages[:]
        reordered_pages = []
        while original_pages:
            reordered_pages.append(original_pages.pop(1))
            reordered_pages.append(original_pages.pop(-2))
            reordered_pages.append(original_pages.pop(2))
            reordered_pages.append(original_pages.pop(-3))
            reordered_pages.append(original_pages.pop(-1))
            reordered_pages.append(original_pages.pop(0))
            reordered_pages.append(original_pages.pop(-1))
            reordered_pages.append(original_pages.pop(0))
        for page in reordered_pages:
            self.__dict__.update(page)
            super().showPage()
        super().save()


def main():
    pdf_path = 'booklet.pdf'
    doc = SimpleDocTemplate(pdf_path,
                            pagesize=pagesizes.letter,
                            topMargin=0.625*inch,
                            bottomMargin=0.625*inch)
    styles = getSampleStyleSheet()
    paragraph_style = styles['Normal']
    print(paragraph_style.fontSize, paragraph_style.leading)
    paragraph_style.fontSize = 300
    paragraph_style.leading = 360
    story = []
    for text in 'ABCDEFGH':
        flowable = Paragraph(text, paragraph_style)
        story.append(flowable)

    doc.build(story, canvasmaker=BookletCanvas)

    # call(["evince", pdf_path])  # launch PDF viewer


main()

Nadal wolę zrobić 4 strony dla każdego arkusza w pliku PDF, ale na razie to wystarczy.

0
Don Kirkby 17 grudzień 2019, 00:33