Printing a booklet on a Mac

I had a 47-page PDF document that I wanted to turn into a compact A5 booklet – you know, one of those things where you get out the big stapler and make something like this:

Unfortunately, you need to print page 39 on the same page as page 10, and then pages 40 and 9 on the other side, etc, and when you get to anything more than about 4 pages it’s hard and tedious to do this by hand and get it right. My HP printer driver had a ‘booklet’ facility, and it worked OK for 8 pages, but let me down when given any more.

Now, there are utilities you can buy which can do exactly this, but why would I spend a tenner or two when I could instead use a few otherwise lucrative working hours and build one myself?

So here’s my solution, which could be a lot tidier, but does the only tricky bit of the job: getting the pages in the right order. It’s an Automator script which you can run as a service: once installed, you can right-click on a PDF and select Services, and you should find a ‘Make Booklet PDF’ option. It produces a new PDF on your Desktop with appropriately shuffled pages. You can then just print that using Preview as follows:

  • Go into the Layout section of the Print dialog.
  • Select Two-Sided Printing
  • Set Pages per Sheet to ‘2’
  • Set the ‘Two-Sided’ option to ‘Short-Edge Binding’

Now, please note: You should understand how this works before trying it! It’s not complex, and I could have made it much prettier and self-explanatory, but I was using Automator, which is so far from a real programming language as to be frustrating. It does, however, have a few useful ways of manipulating PDFs without having to install anything else, and my script will at least prompt you with some of the following information when you run it.

OK,

  • First, the number of pages in your starting PDF must be a multiple of 4. Fortunately, you can easily append blank pages in Preview if needed. Select the last page and choose ‘Edit > Insert > Blank Page’ as often as needed and then save. The script will warn you if your page count isn’t right.

  • Then when you run the script, it will create a folder called ‘booklet-pages’ on your desktop. In here, it will create one PDF for each page of your document.

  • Finally, it will work out what order these pages should be in, and create a new ‘booklet.pdf’ on your desktop with the pages reassembled in that order.

  • You can then delete the ‘booklet-pages’ folder.

So, here’s a zip file containing the Automator script. You should be able to double-click it and open it in Automator if you want to see what’s inside, but I think if you put it into your ~/Library/Services folder within your home directory, it will probably just appear as a service if you right-click on a PDF file in the Finder.

Make Booklet PDF on desktop.zip

Hope it’s useful to someone! Sorry I can’t provide any support if you try it, but recommendations and improvements are welcome from anybody with more Automator stamina than me! All I can say is that it works nicely on my Mac running High Sierra (10.13.6).

Enjoyed this post? Why not sign up to receive Status-Q in your inbox?

73 Comments

Thank you for this. I discovered the two sheets per page thing, which is really handy, but it’s so bonkers that it won’t print as a booklet in Mac by default.

You’ve seriously been a HUGE help. Thank you.

We just migrated to a MacBook Air from 2 respective PC’s, it’s a bit of a challenge since I always used Publisher to create booklets. It automatically collated pages as you mentioned (i.e. Page 1 & 8 and 2 & 7 were actually the ‘same’ page, that is one 8 x 10 paper folded in half equals 4 sides/pages. Like you did, you had to create your pages in multiples of 4, whether worded or blank. Life was easy!!! That process of folding an 8 x 10 paper in half like a book and marking each ‘quarter’ with a number is an old trick printers used to do when creating a book. Okay, I’m obviously over 50 here :).
Anyway, wondering if this would work with the IOS 14?
thanks!

    Hi Debra –

    No, I’m afraid this is definitely Mac-only; it wouldn’t work on iOS. I haven’t done a search to see whether there’s anything out there that might: it’s not the sort of thing I get the urge to do on my phone, or even my iPad, I must admit!

    Best,
    Quentin

Thanks so much! Worked perfectly.

Awesome. Thanks. It was a perfect solution.

if anyone wants to do this in python


# booklet.py import sys import PyPDF3 as pdf # open our input and output files r = pdf.PdfFileReader(open(f"{sys.argv[1]}.pdf", 'rb')) w = pdf.PdfFileWriter() # create a list of page indices pages = list(range(r.getNumPages())) # pad page index list until its len is a multiple of four while len(pages) % 4: pages.append(None) # index of the last page n = len(pages) - 1 # get document dimensions w = r.getPage(0).mediaBox.getWidth() h = r.getPage(0).mediaBox.getHeight() # we loop in pairs for x in range(len(pages) // 2): # alternately count from the front and back for index in (x, n - x) if x % 2 else (n - x, x): if pages[index] is None: w.addBlankPage(w, h) # pad else: w.addPage(r.getPage(index)) # write the output file w.write((open(f"{sys.argv[1]}-book.pdf", 'wb')))

usage, if we have a file document.pdf: `python3 booklet.py document

    Wow, this is so very useful!
    Just one small remark: the variable “w” is used twice in the python code (once as a PdfFileWriter, once for the width of the document). This gave me an error when executing the script. I renamed “w” to “width” and “h” to “height” and it worked as a charm.
    Would you mind me putting this on github?

What if you want to print 8 1/2″ w x 9″ tall? So each page is 4 1/4″ wide?

Thank you ever so much! This is so helpful!

I’ve been struggling to print PDFs as booklets for a very long time and this is the perfect solution.

I can’t understand how this option doesn’t come as part of the OS, since printing large documents as booklets saves a lot of paper. Apple should buy your piece of code and include it in future versions if they are serious about sustainability!

Um, this has literally made my life 100% easier, thank you so so much! 🙌🏽💫

I stumbled on this while being frustrated with printing booklets and even considered splurging on a publishing program like Affinity just to be able to make booklets. Thanks for making this available. I use it almost every week and it always works like a charm and is easy to use.

Hi, I’ve gotten all the way to “run the script” and a pdf has been created. However, when I go to print in Preview, I am not seeing the “Set the ‘Two-Sided’ option to ‘Short-Edge Binding’” option. Please advise. I have upside down pages that are out of order! Thanks so much.

    Hi Christine –

    Ah, I’m afraid, at that point, it’s dependent on your printer and the printer driver, and how you set up two-sided printing. I put that description in because that’s how it looks for most double-sided printers. Your options may be different.

    If yours doesn’t actually print double-sided, you might have to do something like printing the odd-numbered pages and then feeding them back in to print the even-numbered ones… but that’s something you’d need to work out at your end!

    Sorry not to be more help!
    Quentin

thanks, Quentin. My printer does print double-sided…but doesn’t show this option in Preview. I’ve seen it in google docs, however. Odd.

thank you for making this! thank you! God bless you

Thank you so much!!! 😀

God in heaven bless you.

This is great, thank you so much. I have been doing a photography course and wanted to produce a Zine as an assignment. This solves a huge problem.

Hi Quentin! I needed something a little different–take a series of small pages and make a mini-booklet. Ben Corser’s code above gave me the path forward. Below is what I use to take a series of 3″ x 4″ pages in PDF and produce a PDF I can print, cut, staple, and trim to make my booklets.

# bookleter.py
# Given a pdf of a series of pages (width<4, height<11), creates
# a new pdf that can be printed double-sided, cut to height, stapled, and trimmed
# to make a mini booklet.  Pages are centered on the paper.
#
# create input.pdf
# python3 bookleter.py
# output is booklet.pdf (8.5 x 11 paper)
# 
# If the booklet is <= 5.5" in height, can run the paper thru the printer
# again in the opposite direction and get a 2nd book using the same paper.
# However, some printers may reverse pages, so you may need to shuffle some.

# dgrover@redcedar.com 11/14/2021

# Based on code by Ben Corser in a comment on Q's blog:  https://statusq.org/archives/2019/01/11/8893/

import sys

import PyPDF3 as pdf
from PyPDF3.pdf import PageObject

# open our input and output files
readFile = pdf.PdfFileReader(open("input.pdf", 'rb'))
writeFile = pdf.PdfFileWriter()

# create a list of page indices
pages = list(range(readFile.getNumPages()))
# we do this so we can flag padded pages (==None)

# pad page index list with empty pages until its length is a multiple of four
# (4 pages for each sheet of the booklet)
# Note that when using the index, you must test if a page is None.
# If so, then make it blank on output
while len(pages) % 4:
    pages.append(None)

# get input document dimensions
inputPageWidth = readFile.getPage(0).mediaBox.getWidth()
inputPageHeight = readFile.getPage(0).mediaBox.getHeight()

# blank input page
blackInputPage = PageObject.createBlankPage(None, inputPageWidth, inputPageHeight)

# output dimensions, std 8.5x11 
outputPageWidth = 72.0 * 8.5
outputPageHeight = 72.0 * 11.0

# translation
translateY=outputPageHeight - inputPageHeight
translateXLeft = (outputPageWidth/2) - inputPageWidth
translateXRight = outputPageWidth/2

# each sheet of paper carries 4 pages
# Side 0 contains D (left) and A (right)
# side 1 contains B (left) and C (right)
for sheet in range( int(len(pages)/4)):
    #print("Sheet {0:d}".format(sheet))
    # calculate what pages go where:
    pageA=sheet * 2
    pageB=pageA + 1
    pageD=(len(pages)-1) - (sheet*2)
    pageC=pageD - 1


    # side 0
    # create blank page (output size)
    new_page = PageObject.createBlankPage(None, outputPageWidth, outputPageHeight)
    # add page D (left)
    if pages[pageD]!=None:
        new_page.mergeTranslatedPage(readFile.getPage(pages[pageD]), translateXLeft, translateY)
    # add page A (right)
    if pages[pageA]!=None:
        new_page.mergeTranslatedPage(readFile.getPage(pages[pageA]), translateXRight, translateY)
    # output this page
    writeFile.addPage(new_page)

    # side 1
    # create blank page (output size)
    new_page = PageObject.createBlankPage(None, outputPageWidth, outputPageHeight)
    # add page B (left)
    if pages[pageB]!=None:
        new_page.mergeTranslatedPage(readFile.getPage(pages[pageB]), translateXLeft, translateY)
    # add page C (right)
    if pages[pageC]!=None:
        new_page.mergeTranslatedPage(readFile.getPage(pages[pageC]), translateXRight, translateY)
    # output this page
    writeFile.addPage(new_page)


writeFile.write((open("booklet.pdf", 'wb')))
print("Wrote {0:d} double-sided sheets with {1:d} pages total.".format(int(len(pages)/4), len(pages) ))

Works brilliantly–thank you for your effort (Mac OS 10.14.6)

Leave a Reply to Ben Corser Cancel reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

*

© Copyright Quentin Stafford-Fraser