63

I would like to print a PDF so that on the front of the first page are the first two pages, on the back the 3rd and 4th and so on.

-----------------          -----------------
|       |       |          |       |       |
|       |       |          |       |       |
|   1   |   2   |          |   3   |   4   |    . . .
|       |       |          |       |       |
|_______|_______|          |_______|_______|

 page 1 - front             page 1 - back

Because my printer using Linux fails to support manual duplex printing I'd thought, maybe I could edit the pdf in a according way.

But how?

6
  • I don't think that this is possible, do you only have the pdf?
    – Michael K
    Feb 15, 2011 at 15:31
  • This is possible on Linux using pstops from the psutils package and/or pdftk. Which operating system are you running?
    – rems
    Feb 15, 2011 at 15:31
  • @Ivo Flipse: har, i thought the exactly the same :) so, your comment gets a +1 as well.
    – akira
    Feb 15, 2011 at 17:54
  • @Ivo Flipse, @rems: You can upvote more ASCII art here: superuser.com/questions/54054/… and superuser.com/questions/235074/… ... @mokasin: these links may give you an idea how to solve the task you asked for. Mar 1, 2011 at 22:05
  • I don't understand the end product desired: If you have 4 pdf pages and want to put that on one sheet of paper, front |1|2|-|3|4| rear with the fold between pdf pages 1 and 2, then the folded page ends up with page 2 on front, then pages 3 and 4 on the interior, and finally page 1 will be on the back. So, it seems the correct order would be |4|1|-|2|3| if you plan on folding the sheet, then reading page 1 first, then 2 and 3 in the interior, and finally page 4 on the rear. (the fold on the front between 4 and 1 folds page 4 to the rear, then pages 2 and 3 on the inside. Is that what you want?
    – user12711
    Dec 19, 2021 at 19:19

12 Answers 12

35

In addition to what's been mentioned, pdfjam-extras includes a command line tool, pdfnup which does this. (It makes use of the pdfpages package for PDFLaTeX underneath, which you can also use.)

If you prefer a GUI, jPDFtweak is another option.

5
  • 4
    Sample usage: pdfnup --nup 2x1 mypdf.pdf. This prints 2 pages side-by-side per sheet on a landscape view, to be printed flipped over the short edge. See man pdfnup for a few more details. Nov 25, 2018 at 0:18
  • I've decided to add an answer too: how to convert 1 1-pg pdf into a landscape view with 2 copies of it duplicated on the same page (great for printing flyers): superuser.com/a/1452008/425838 Jun 23, 2019 at 17:29
  • 1
    @GabrielStaples Thanks for the sample usage! On Debian I had to install texlive-extra-utils to have this command.
    – jlh
    Jul 11, 2020 at 13:19
  • 9
    The utility script pdfnup has been removed from the distribution of pfdjam. It is possible to use pdfjam directly, e.g. via pdfjam --nup 2x1 in.pdf --outfile out.pdf --landscape Jul 15, 2020 at 16:56
  • Is there any option to make it right to left?
    – Shayan
    Mar 11, 2022 at 12:13
30

Use pdfnup:

$ pdfnup file.pdf

This will create a new pdf file exactly like you asked for.

5
  • pdfnup shows the command line options used with pdfjam and so you can tweak from there. (ex: if you want to not have landscape. you can remove the --landscape option when calling pdfjam) Nov 4, 2016 at 18:30
  • 7
    More exactly pdfnup --nup 2x1 --suffix test file.pdf will create a file-test.pdf with 2 pages in 1.
    – lolesque
    Nov 28, 2016 at 18:12
  • 1
    sudo apt install texlive-extra-utils to install these utils on Ubuntu.
    – Sarke
    Aug 8, 2018 at 1:39
  • I have a single page a4 I want to print in two copies of a5's per sheet. How do I accomplish this? The usage examples of 'pdfnup' above does not duplicate the first page, but instead makes the second a5-part of the first a4 sheet blank.
    – Nordlöw
    Mar 17, 2019 at 21:27
  • Is there any option to make it right to left?
    – Shayan
    Mar 11, 2022 at 12:23
12

This is a question old enough to think that the options we have now were absent at the time, but maybe it deserves an up-to-date solution.

Linux pdf viewers usually use the printing options/properties to set the page layout, and there you can print multiple pages per sheet/side. The idea is to use those to print to file as PDF.

Evince can do it, also qpdfview. More here.


qpdfview

enter image description here

enter image description here


Evince

enter image description here


PDF Studio Viewer

enter image description here

Other pdf viewers must have similar options.

7

For anyone wanting to take a 1 or 2 pg pdf and turn it into a pdf with 2 copies of that side-by-side in landscape view (great for printing flyers), do:

First, install texlive-extra-utils, which contains pdfnup:

sudo apt update
sudo apt install texlive-extra-utils

Then:

  1. Turn the 1 or 2 pg pdf input into an output which contains a duplicated copy of those pages (1-pg pdf --> 2-pg pdf, 2-pg pdf --> 4-pg pdf, etc):
    pdfunite in.pdf in.pdf out.pdf
    
  2. Combine that duplicated-copy pdf into a 2-pages-per-side-in-landscape-view pdf, for printing flyers for example:
    pdfnup out.pdf
    

Or (recommended) do both steps above all on a single line:

pdfunite in.pdf in.pdf out.pdf && pdfnup out.pdf

Note that out.pdf is the input to pdfnup. The resulting output file from pdfnup will be called "out-nup.pdf".

Also, watch the output of the pdfnup command and you'll see the verbose form of the command it is actually running, which gives you some insight into the options you can pass into it. Apparently pdfnup uses pdfjam under the hood, as it indicates here:

  pdfjam: Effective call for this run of pdfjam:  
          /usr/bin/pdfjam --suffix nup --nup '2x1' --landscape -- out.pdf -

Example output:

Original PDF (1 regular pg in Portrait view), "in.pdf": enter image description here

Final PDF (2 pgs side-by-side in Landscape view), "out-nup.pdf":

  • now can be cut in half down the middle to pass out as flyers enter image description here

Simple Bash Function: make_flyer

New version: get an even better and more up-to-date version of the below script here: make_flyer.sh, from my eRCaGuy_dotfiles repo. Follow the installation instructions in the comments at the top of the file.

Old version:

Copy and paste this bash function to the bottom of your ~/.bashrc file in order to get access to a simple and easy-to-use command make flyer:

# Description: outputs a landscape-oriented flyer pdf
# ("my/pdf/input--flyer.pdf") for each 1 or more pg input pdf 
# ("my/pdf/input.pdf")
#   - 1-pg input PDFs are converted to a 1-sided landscape, printable flyer 
#     that you cut down the center to make 2 flyers.
#   - 2-pg input PDFs are converted to a 2-sided landscape, printable flyer 
#     (flip on short edge when printing double-sided), and also cut down the 
#     middle to make 2 flyers.
#   - **3+ pg input PDFs**: using `pdfnup` directly in this case would make 
#     more sense, since this function will otherwise unnecessarily create 2 
#     copies.
#   - 3 and 4-pg input PDFs are converted to a single piece of paper, 
#     double-sided, flipped on short edge, x 2 copies. No cutting is necessary.
#   - 5+ pg input PDFs simply require half as much paper to print is all since 
#     you get 2 pages per side of paper; they do NOT print like booklets, but 
#     rather just as a landscape-printed, flipped-on-short-edge bundle of pages
#     (like a deck of slides). You get *2 copies* per print though, so just 
#     print half of the total number of pages. 
#
# Example:
#       make_flyer "path/to/inputpdf1.pdf" "path/to/inputpdf2.pdf"
make_flyer() {
    num_args=$# # see: https://stackoverflow.com/questions/4423306/how-do-i-find-the-number-of-arguments-passed-to-a-bash-script/4423321#4423321
    suffix="flyer"

    loop_cnt=0
    for inputpdf in "$@"
    do
        ((loop_cnt++))
        echo "==== CONVERTING PDF $loop_cnt OF $num_args ===="
        echo "     INPUT:  \"$inputpdf\""

        # Strip off the .pdf extension from the input path, while retaining the rest of the path
        # - See: https://stackoverflow.com/questions/12152626/how-can-i-remove-the-extension-of-a-filename-in-a-shell-script/32584935#32584935
        input_path_base="$(echo "$inputpdf" | rev | cut -f 2- -d '.' | rev)"
        input_file_base="$(basename "$inputpdf" .pdf)"
        temp_pdf="${input_path_base}-.pdf" # is "input_path_base-.pdf"
        
        echo "     OUTPUT: \"$(pwd)/${input_file_base}--${suffix}.pdf\""

        # Convert a single 1-pg pdf into a temporary 2-pg pdf
        pdfunite "$inputpdf" "$inputpdf" "$temp_pdf"

        # Lay out the temporary 2-pg pdf into a side-by-side 1-sided flyer to print; creates "input_path_base--flyer.pdf"
        # Note that `pdfnup` places the output from this operation in the location from where you call this script
        # (ie: in your `pwd` [Present Working Directory])!--NOT the location where temp_pdf is located!
        pdfnup "$temp_pdf" --suffix $suffix

        # Delete the temporary 2-pg pdf, called "input_path_base-.pdf", thereby leaving only the original 
        # "input_path_base.pdf" and the new "input_path_base--flyer.pdf"
        rm "$temp_pdf"
    done
}
alias make_flyer_help='echo -e "Ex usage: make_flyer \"path/to/inputpdf.pdf\" - Creates a landscape-side-by-side flyer version called \"inputpdf--flyer.pdf\"\n          *in your pwd* from a 1 or 2 pg input pdf called \"path/to/inputpdf.pdf\". Accepts multiple arguments. Ex:\n          make_flyer \"path/to/inputpdf1.pdf\" \"path/to/inputpdf2.pdf\""'

Example usage:

make_flyer "path/to/inputpdf1.pdf" "path/to/inputpdf2.pdf"

See Help info:

make_flyer_help

Output:

$ make_flyer_help   
Ex usage: make_flyer "path/to/inputpdf.pdf" - Creates a landscape-side-by-side flyer version called "inputpdf--flyer.pdf"  
          *in your pwd* from a 1 or 2 pg input pdf called "path/to/inputpdf.pdf". Accepts multiple arguments. Ex:  
          make_flyer "path/to/inputpdf1.pdf" "path/to/inputpdf2.pdf"

References:

  1. https://superuser.com/a/948095/425838
  2. https://stackoverflow.com/a/11280219/4561887

Related:

  1. https://askubuntu.com/questions/214538/printing-in-booklet-format/1095789#1095789

Bash References:

  1. Bash How to pass arguments into a bash function: https://bash.cyberciti.biz/guide/Pass_arguments_into_a_function
  2. Bash Concatenate strings: https://linuxize.com/post/bash-concatenate-strings/
  3. Bash execute a cmd stored as a string! https://stackoverflow.com/questions/2005192/how-to-execute-a-bash-command-stored-as-a-string-with-quotes-and-asterisk
  4. Bash iterate over all inputs to a cmd: https://stackoverflow.com/questions/255898/how-to-iterate-over-arguments-in-a-bash-script/255913#255913
  5. Bash passing parameters to function: https://stackoverflow.com/questions/6212219/passing-parameters-to-a-bash-function/6212408#6212408
  6. How to convert a 1-pg pdf into a flyer [my own ans!]: How to convert a 1 page PDF to a 2 page per sheet PDF?
0
1

A very quick and dirty option if you have Google Chrome browser is to use the built in PDF printer/viewer and "save as PDF" feature.

  1. Open/drop the pdf inside a Chrome tab (if a save file window is displayed you have to enable the PDF internal viewer option, go to this page on your browser chrome://settings/content/pdfDocuments)

  2. Right click and select "Print"

  3. In the print panel select "save as PDF"

  4. Select the number of pages in "Pages per sheet"

NOTE: it can have few quirks if pages are not even or different aspect ratio, also as far as I can tell the page format is A4 and I can't find any obvious way to change it.

Also if you have Adobe Acrobat installed you can use the Adobe PDF printer instead, in this case more and advanced options will be available.

1

There are freeware & open source command line tools available to convert PDFs to reader's spreads, booklet spreads etc.

I lost the app I was using, so no help there, but a from a quick search I see a program called pdfshuffler which might be what you need. Has a gui, so not likely to be automagical, but it is a front-end for python-pyPdf.

1

You can do this with PyPDF2. The code below is not a perfect solution to your problem, but it will hopefully help others who come here from google.

#!/usr/bin/env python

# requires PyPdf2 library, version 1.26 or above -
# its homepage is https://pythonhosted.org/PyPDF2/index.html
# running: ./this-script-name output.pdf file-with-pdf-list

import copy, sys
from PyPDF2 import PdfFileWriter, PdfFileReader, pdf
output = PdfFileWriter()
output_page_number = 0
alignment = 6 # align on 6 pages for printing 6 up
for filename in sys.argv[2:]:

    page = pdf.PageObject.createBlankPage(None, 850, 1100)
    input = PdfFileReader(open(filename, "rb"))

    position = 0
    for i in range(0, input.getNumPages()):
        x = 0
        # Two Up
        # if position == 0:
        #    position = 1
        #    page.mergeScaledTranslatedPage(input.getPage(i), 0.5, 100, 650)
        #else:
        #    page.mergeScaledTranslatedPage(input.getPage(i), 0.5, 100, 100)
        #    output.addPage(page)
        #    page = pdf.PageObject.createBlankPage(output)
        #    position = 0
        # 6 Up
        scale = 0.25
        col1 = 100
        col2 = 450
        sep = 130
        row3 = sep + 25
        row2 = row3 + sep + 215
        row1 = row2 + sep + 215
        if position == 0:
           position = 1
           page.mergeScaledTranslatedPage(input.getPage(i), scale, col1, row1)
        elif position == 1:
           position = 2
           page.mergeScaledTranslatedPage(input.getPage(i), scale, col2, row1)
        elif position == 2:
           position = 3
           page.mergeScaledTranslatedPage(input.getPage(i), scale, col1, row2)
        elif position == 3:
           position = 4
           page.mergeScaledTranslatedPage(input.getPage(i), scale, col2, row2)
        elif position == 4:
           position = 5
           page.mergeScaledTranslatedPage(input.getPage(i), scale, col1, row3)
        else:
           page.mergeScaledTranslatedPage(input.getPage(i), scale, col2, row3)
           output.addPage(page)
           page = pdf.PageObject.createBlankPage(output)
           position = 0
    if position != 0:
        output.addPage(page)

output.write(open(sys.argv[1], "wb"))
1
  • not compatible with >>> import PyPDF2 >>> PyPDF2.__version__ '3.0.1' Sep 13, 2023 at 14:56
0

If you have the print to file facility. print to the file with two pages per page setting and with odd pages. repeat the process with even pages. Now print the odd ones, reverse the printed papers and print the even pages file.

0

@mokasin: You didn't say which PDF reader you're using. If you use the Linux version of Acrobat/Adobe Reader: there is an option to print "2-up" right in the print dialog. You can also choose to only print the odd or even pages, so combining this will help you to achieve your desired output.

0

This software I tested on Solaris 11.2 operating system can create that scheme which is called 2-up, usually used for hand-out at classrooms or meetings. It is possible to produce other schemes; for example, hand-out with 3 or 4 or more pages on one sheet or both sides of a sheet. It can be run from a terminal as it is a JAR file or just run the GUI for ease of access. Besides Solaris other Linux distributions are also compatible, running the software, as "executable," with super-user privileges. Be aware not using "Open the Archive." It is also working on any Windows and Mac where there is already a Java Runtime Environment (JRE) installed, as is the case most of the time. Software is Dysprosium Imposition and is free to download and to use.

0

pdfnup has been deprecated or has disappeared from distributions.

But pdfautonup is a wonderful replacement that works as easy as:

pdfautonup foo.pdf

0

solution with python (PyPDF2 version 3.0.1)

input (left) / output (right)

enter image description here

usage

Most likely you need to install PyPDF2 (in the specified version) with

pip install PyPDF2==3.0.1

Then you can execute the script by

python create_multipage_pdf.py demo.pdf

code

Spacing and number of pages (n_rows, n_cols) are configurable. You can also put the output-pdf to landscape mode by ROTATE_OUTPUT = 90.

create_multipage_pdf.py

PAGE_SHAPE_OUT = (297, 210)  # width, height
PAGES_PER_SHEET = (2, 2)  # n_rows, n_cols
PAD_LEFT = 20
PAD_RIGHT = 20
PAD_TOP = 20
PAD_BOTTOM = 20
WSPACE = 10
HSPACE = 20
ROTATE_OUTPUT = 0

FN_OUT_SEP = "_"
FN_OUT_SUFFIX = "multipage.pdf"

import sys
import PyPDF2
from math import prod

def add_page(doc_out, page, rects):
    """add page to PdfWriter and draw rectangle around subpages"""
    doc_out.add_page(page.rotate(ROTATE_OUTPUT))
    for rect in rects:
        # rect boarder is drawn inside
        pad = 1
        rect_padded = (rect[0] - pad, rect[1] - pad, rect[2] + pad, rect[3] + pad)
        doc_out.add_annotation(-1, PyPDF2.generic.AnnotationBuilder.rectangle(rect=rect_padded))

def main():
    global FNS_IN

    if len(sys.argv) > 1:
        FNS_IN = sys.argv[1:]

    fn_out = FN_OUT_SUFFIX
    if len(sys.argv) == 2:
        fn_out = FNS_IN[0][:-4] + FN_OUT_SEP + FN_OUT_SUFFIX
    doc_out = PyPDF2.PdfWriter()

    pos = 0
    page = None
    for filename in FNS_IN:

        doc_in = PyPDF2.PdfReader(open(filename, "rb"))
        for pp in range(0, len(doc_in.pages)):


            if pos % prod(PAGES_PER_SHEET) == 0:
                if page is not None:
                    add_page(doc_out, page, rects)
                page = PyPDF2.PageObject.create_blank_page(None, *PAGE_SHAPE_OUT)
                rects = []



            page_in = doc_in.pages[pp]

            # scale
            page_in_width = float(page_in.mediabox[2])
            page_in_height = float(page_in.mediabox[3])
            page_in_width_available = (
                (PAGE_SHAPE_OUT[0] - PAD_LEFT - PAD_RIGHT - WSPACE*(PAGES_PER_SHEET[0] - 1))
                / PAGES_PER_SHEET[0]
            )
            page_in_height_available = (
                (PAGE_SHAPE_OUT[1] - PAD_TOP - PAD_BOTTOM - HSPACE*(PAGES_PER_SHEET[1] - 1))
                / PAGES_PER_SHEET[1]
            )
            scale = min(page_in_width_available/page_in_width, page_in_height_available/page_in_height)
            page_in_width_scaled = page_in_width * scale
            page_in_height_scaled = page_in_height * scale

            # pos
            pos_page = pos % prod(PAGES_PER_SHEET)
            pos_row = pos_page // PAGES_PER_SHEET[1]
            pos_col = pos_page % PAGES_PER_SHEET[1]
            pos_x = PAD_LEFT + (WSPACE + page_in_width_available) * pos_col
            pos_y = PAD_BOTTOM + (HSPACE + page_in_height_available) * (PAGES_PER_SHEET[1] - 1 - pos_row)

            # rects
            rects += [(pos_x, pos_y, pos_x + page_in_width_scaled, pos_y + page_in_height_scaled)]

            tansformation = PyPDF2.Transformation().scale(scale).translate(tx=pos_x, ty=pos_y)
            page_in.add_transformation(tansformation)
            page.merge_page(page_in)
            pos += 1

    add_page(doc_out=doc_out, page=page, rects=rects)
    doc_out.write(open(fn_out, "wb"))

if __name__ == "__main__":
    assert len(sys.argv) >= 2, "call python script with at least one argument (pdfs to be multipaged)"
    main()

info

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .