Как можно объединить PDF-файлы (или PS, если это невозможно), чтобы каждый файл начинался с нечетной страницы? - PullRequest
11 голосов
/ 22 марта 2012

Я работаю в системе UNIX и хотел бы объединить тысячи файлов PDF в один файл, чтобы распечатать его.Я не знаю, сколько страниц у них заранее.

Я бы хотел напечатать его двухсторонним, чтобы два файла не находились на одной странице.

Поэтому, если бы файл слияния был выровнен так, чтобы каждый файл начинался с нечетной страницы, и добавлялась пустая страница, если следующим местом для записи является четная страница.

Ответы [ 8 ]

9 голосов
/ 06 октября 2012

Вот решение, которое я использую (оно основано на базовом принципе @ Dingo, но использует более простой подход к работе с PDF):

Сначала я создаю файл PDF с одной пустой страницей где-то, например"/path/to/blank.pdf".

Затем из каталога, содержащего все мои pdf-файлы, я запускаю небольшой скрипт, который добавляет файл blank.pdf к каждому pdf с нечетным номером страницы:

#!/bin/bash

for f in *.pdf; do
  let npages=$(pdfinfo "$f"|grep 'Pages:'|awk '{print $2}')
  let modulo="($npages %2)"
  if [ $modulo -eq 1 ]; then
    pdftk "$f" "/path/to/blank.pdf" output "aligned_$f"
  else
    cp "$f" "aligned_$f"
  fi
done

Теперьвсе "выровненные" файлы имеют четные номера страниц, и я могу присоединиться к ним, используя

pdftk aligned_*.pdf output result.pdf
4 голосов
/ 22 марта 2012

Ваша проблема может быть более легко решена, если вы посмотрите на это с другой точки зрения

, чтобы получить, что при печати, страница 1 из секунда PDF-файл не будет прикреплен к последней странице из первого PDF-файла на том же листе бумаги, и, в более общем случае, первая страница следующего PDF-файла будетне печатать на обратной стороне того же листа с последней страницей предыдущего файла PDF

необходимо выполнить выборочное добавление одной пустой страницы * только 1015 * к файлам PDF с нечетным номеромстраниц

Я написал простой скрипт с именем abbblankifneeded , который можно поместить в файл и затем скопировать в / usr / bin или / usr / local/ bin

и затем вызвать в папке, где у вас есть PDF с этим синтаксисом

for f in *.pdf; do addblankifneeded $f; done

, этот скрипт добавляет пустую страницу в конце в PDF-файлыс нечетным числом страниц, пропуская pdf-файлы с четным числом страници затем объедините все PDF в одно

требования: pdftk , pdfinfo

ПРИМЕЧАНИЕ: в зависимости от вашей среды bash вам может понадобиться заменить интерпретатор sh на интерпретатор bash в первой строке скрипта

#!/bin/sh
#script to add automatically blank page at the end of a pdf documents, if count of their pages is a not a module of 2 and then to join all pdfs into one
#
#  made by Dingo
#
# dokupuppylinux.co.cc
#
#http://pastebin.com/u/dingodog (my pastebin toolbox for pdf scripts)
#
filename=$1
altxlarg="`pdfinfo -box $filename| grep MediaBox | cut -d : -f2 | awk '{print $3 FS $4}'`"
echo "%PDF-1.4
%µí®û
3 0 obj
<<
/Length 0
>>
stream
endstream
endobj
4 0 obj
<<
/ProcSet [/PDF ]
/ExtGState <<
/GS1 1 0 R
>>
>>
endobj
5 0 obj
<<
/Type /Halftone
/HalftoneType 1
/HalftoneName (Default)
/Frequency 60
/Angle 45
/SpotFunction /Round
>>
endobj
1 0 obj
<<
/Type /ExtGState
/SA false
/OP false
/HT /Default
>>
endobj
2 0 obj
<<
/Type /Page
/Parent 7 0 R
/Resources 4 0 R
/Contents 3 0 R
>>
endobj
7 0 obj
<<
/Type /Pages
/Kids [2 0 R ]
/Count 1
/MediaBox [0 0 595 841]
>>
endobj
6 0 obj
<<
/Type /Catalog
/Pages 7 0 R
>>
endobj
8 0 obj
<<
/CreationDate (D:20110915222508)
/Producer (libgnomeprint Ver: 2.12.1)
>>
endobj
xref
0 9
0000000000 65535 f
0000000278 00000 n
0000000357 00000 n
0000000017 00000 n
0000000072 00000 n
0000000146 00000 n
0000000535 00000 n
0000000445 00000 n
0000000590 00000 n
trailer
<<
/Size 9
/Root 6 0 R
/Info 8 0 R
>>
startxref
688
%%EOF" | sed -e "s/595 841/$altxlarg/g">blank.pdf
pdftk blank.pdf output fixed.pdf
mv fixed.pdf blank.pdf
pages="`pdftk $filename dump_data | grep NumberOfPages | cut -d : -f2`"
if [ $(( $pages % 2 )) -eq 0 ]
    then echo "$filename has already a multiple of 2 pages ($pages ). Script will be skipped for this file" >>report.txt
    else
pdftk A=$filename B=blank.pdf cat A B output blankadded.pdf
mv blankadded.pdf $filename
pdffiles=`ls *.pdf | grep -v -e blank.pdf -e joinedtogether.pdf| xargs -n 1`;  pdftk $pdffiles cat output joinedtogether.pdf
fi
exit 0
1 голос
/ 22 августа 2018

Вот версия PowerShell самого популярного решения с использованием pdftk. Я сделал это для Windows, но вы можете использовать PowerShell Core для других платформ.

# install pdftk server if on windows
# https://www.pdflabs.com/tools/pdftk-server/

$blank_pdf_path = ".\blank.pdf"
$input_folder = ".\input\"
$aligned_folder = ".\aligned\"
$final_output_path = ".\result.pdf"

foreach($file in (Get-ChildItem $input_folder -Filter *.pdf))
{
    # easy but might break if pdfinfo output changes
    # takes 7th line with the "Page: 2" and matches only numbers
    (pdfinfo $file.FullName)[7] -match "(\d+)" | Out-Null

    $npages = $Matches[1]
    $modulo = $npages % 2

    if($modulo -eq 1)
    {
        $output_path = Join-Path $aligned_folder $file.Name
        pdftk $file.FullName $blank_pdf_path output $output_path
    }
    else
    {
        Copy-Item $file.FullName -Destination $aligned_folder
    }
}

$aligned_pdfs = Join-Path $aligned_folder "*.pdf"
pdftk $aligned_pdfs output $final_output_path
1 голос
/ 28 сентября 2016

Вы можете использовать PDFsam :

  • бесплатно
  • работает в Microsoft Windows, Mac OS X и Linux
  • доступна мобильная версияпо крайней мере в Windows)
  • может добавить пустую страницу после каждого объединенного документа, если документ имеет нечетное количество страниц

enter image description here

1 голос
/ 06 мая 2014

Отказ от ответственности: я являюсь автором инструментов, о которых я упоминаю здесь.

sejda-console

Это бесплатный интерфейс командной строки с открытым исходным кодом длявыполнение PDF-манипуляций, таких как слияние или разделение.Команда merge имеет параметр:

[- addBlanks]: добавить пустую страницу после каждого объединенного документа, если число страниц нечетное (необязательно)

Поскольку вам просто нужно распечатать PDF-файл, я предполагаю, что вы не заботитесь о порядке объединения ваших документов.Вы можете использовать эту команду:

sejda-console merge -d /path/to/pdfs_to_merge -o /outputpath/merged_file.pdf --addBlanks

Ее можно загрузить с официального сайта sejda.org .

sejda.com

Это веб-приложение, поддерживаемое Sejda и имеющее те же функции, что и выше, но через веб-интерфейс.Вы обязаны загружать свои файлы, поэтому, в зависимости от размера вашего набора ввода, это может быть неправильным решением для вас.

Если вы выберете команду merge и загрузите ваши документы в формате PDF, у вас будетустановить флажок Add blank page if odd page number, чтобы получить желаемое поведение.

0 голосов
/ 01 марта 2019

Код @Chris Lercher в https://stackoverflow.com/a/12761103/1369181 не совсем работал для меня.Я не знаю, так ли это, потому что я работаю над Cygwin / mintty.Кроме того, я должен использовать qpdf вместо pdftk.Вот код, который работал для меня:

#!/bin/bash

for f in *.pdf; do
  npages=$(pdfinfo "$f"|grep 'Pages:'|sed 's/[^0-9]*//g')
  modulo=$(($npages %2))
  if [ $modulo -eq 1 ]; then
    qpdf --empty --pages "$f" "path/to/blank.pdf" -- "aligned_$f"
  else
    cp "$f" "aligned_$f"
  fi
done

Теперь все "выровненные" файлы имеют четные номера страниц, и я могу присоединиться к ним, используя qpdf (благодаря https://stackoverflow.com/a/51080927):

qpdf --verbose --empty --pages aligned_* -- all.pdf

А вот полезный код из https://unix.stackexchange.com/a/272878, который я использовал для создания пустой страницы:

echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf
0 голосов
/ 31 июля 2018

Мартин хорошо начал.Я обновил до PyPdf2 и сделал несколько настроек, таких как сортировка вывода по имени файла.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from argparse import ArgumentParser
from glob import glob
from PyPDF2 import PdfFileReader, PdfFileWriter
import os.path
def merge(pdfpath, blank_filename, output_filename):

    with open(blank_filename, "rb") as f:
        blank = PdfFileReader(f)
        output = PdfFileWriter()

        filelist = sorted(glob(os.path.join(pdfpath,'*.pdf')))

        for pdffile in filelist:
            if pdffile == output_filename:
                continue
            print("Parse '%s'" % pdffile)

            document = PdfFileReader(open(pdffile, 'rb'))

            for i in range(document.getNumPages()):
                output.addPage(document.getPage(i))

            if document.getNumPages() % 2 == 1:
                output.addPage(blank.getPage(0))

            print("Add blank page to '%s' (had %i pages)" % (pdffile, document.getNumPages()))

        print("Start writing '%s'" % output_filename)
        with open(output_filename, "wb") as output_stream:
            output.write(output_stream)


if __name__ == "__main__":
    parser = ArgumentParser()

    # Add more options if you like
    parser.add_argument("-o", "--output", dest="output_filename", default="merged.pdf",
                      help="write merged PDF to FILE", metavar="FILE")
    parser.add_argument("-b", "--blank", dest="blank_filename", default="blank.pdf",
                      help="path to blank PDF file", metavar="FILE")
    parser.add_argument("-p", "--path", dest="path", default=".",
                      help="path of source PDF files")

    args = parser.parse_args()
    merge(args.path, args.blank_filename, args.output_filename)
`
0 голосов
/ 31 марта 2014

Подготовка

  1. Установите Python и убедитесь, что у вас есть пакет pyPDF.
  2. Создайте файл PDF с одним пробелом в /path/to/blank.pdf (я создал пустых страниц PDF здесь ).
  3. Сохраните это как pdfmerge.py в любом каталоге вашего $PATH. (Я не пользователь Windows. Это просто под Linux. Пожалуйста, дайте мне знать, если вы получаете ошибки / если это работает.)
  4. Сделать pdfmerge.py исполняемым

Каждый раз, когда вам это нужно

Запустите uniprint.py каталог, содержащий только файлы PDF, которые вы хотите объединить.

pdfmerge.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from argparse import ArgumentParser
from glob import glob
from pyPdf import PdfFileReader, PdfFileWriter

def merge(path, blank_filename, output_filename):
    blank = PdfFileReader(file(blank_filename, "rb"))
    output = PdfFileWriter()

    for pdffile in glob('*.pdf'):
        if pdffile == output_filename:
            continue
        print("Parse '%s'" % pdffile)
        document = PdfFileReader(open(pdffile, 'rb'))
        for i in range(document.getNumPages()):
            output.addPage(document.getPage(i))

        if document.getNumPages() % 2 == 1:
            output.addPage(blank.getPage(0))
            print("Add blank page to '%s' (had %i pages)" % (pdffile, document.getNumPages()))
    print("Start writing '%s'" % output_filename)
    output_stream = file(output_filename, "wb")
    output.write(output_stream)
    output_stream.close()

if __name__ == "__main__":
    parser = ArgumentParser()

    # Add more options if you like
    parser.add_argument("-o", "--output", dest="output_filename", default="merged.pdf",
                      help="write merged PDF to FILE", metavar="FILE")
    parser.add_argument("-b", "--blank", dest="blank_filename", default="blank.pdf",
                      help="path to blank PDF file", metavar="FILE")
    parser.add_argument("-p", "--path", dest="path", default=".",
                      help="path of source PDF files")

    args = parser.parse_args()
    merge(args.path, args.blank_filename, args.output_filename)

Тестирование

Пожалуйста, оставьте комментарий, если это работает на Windows и Mac.

Пожалуйста, всегда оставляйте комментарий, если он не работает / его можно улучшить.

Работает в Linux. Объединение 3 PDF-файлов в один 200-страничный PDF-файл заняло менее секунды.

...