Public
Snippet $128 authored by Jérome Perrin

pypdf_4_A7_on_A5.py

pypdf_4_A7_on_A5.py
def ERP5Site_mergeSmallPDF(self, pdf_data_list):
  """Create A5 PDF by merging 4 A7 PDFs per page.
  A7 PDFs are passed as A4, top right corner A7 is kept.

  `pdf_data_list` is a list of 4 tuples of PDF, passed as a string.
  The PDF data can be None, then this corner will be left blank.

  For example:
    [
      (pdf1_1, pdf1_2, pdf1_3, pdf1_4),
      (pdf2_1, pdf2_2, None, pdf2_4),
    ]

   Will be assembled, 4 per page:

 # page1:
    pdf1_1 pdf1_2
    pdf1_3 pdf1_4
 # page1:
    pdf2_1 pdf2_2
           pdf2_4

  """
  from StringIO import StringIO
  from PyPDF2 import PdfFileWriter, PdfFileReader
  from copy import deepcopy

  #  PDF coordinates are in points ( https://en.wikipedia.org/wiki/Point_(typography) ), A4 page is:
  #
  #     ^        . ( 595, 842 )
  #     |
  #     |
  #     |
  #   y |
  #     |
  #     +-------->
  # (0,0)    x

  output = PdfFileWriter()

  def getBlankA5PortraitPage():
    """Returns a new blank A5 page in portrait.

    A5 page is 420 x 595 points ( http://www.prepressure.com/library/paper-size/din-a5 )
    """
    writer = PdfFileWriter()
    writer.addBlankPage(
      width=595,
      height=420)
    return deepcopy(writer.getPage(0))

  def getTopRightCornerA7fromA4Page(page):
    """Crop a A7 sized zone for the top right corner of a A4:

      #          (298, 842)
      #     |XXXX
      #     |XXXX
      #     |    (298, 631)
      #     |
      #   y |
      #     |
      #     +-------->
      # (0,0)    x

    Returns a new page.
    """
    page = deepcopy(page)
    page.mediaBox.upperRight = (
      page.mediaBox.getUpperRight_x() / 2 ,
      page.mediaBox.getUpperRight_y())
    page.mediaBox.lowerLeft = (
      page.mediaBox.getLowerLeft_x(),
      page.mediaBox.getLowerLeft_y() + page.mediaBox.getUpperRight_y() * 3/4.)
    return page

  translation_list = [
    (0, -420),
    (298, -420),
    (0, -630),
    (298, -630),
  ]
  for (page1, page2, page3, page4) in pdf_data_list:
    target_page = getBlankA5PortraitPage()
    for (x, y), page in zip(translation_list, (page1, page2, page3, page4)):
      if page:
        sticker_page = PdfFileReader(StringIO(page)).getPage(0)
        sticker = getTopRightCornerA7fromA4Page(sticker_page)
        target_page.mergeTranslatedPage(sticker, x, y)
    output.addPage(target_page)

  outputStream = StringIO()
  output.write(outputStream)
  return outputStream.getvalue()