Как объединить и разбить PDF в Linux подручными средствами



16 коммент.
В этой безблагодатной и беспросветной жизни, когда тебе в линукс присылают документы в DocX и формы в последнем Adobe Acrobat, приходится несладко. Часто заполненные с воем и рыданиями PDF-файлы приходится склеивать или, наоборот, разрезать на несколько. К счастью,деятели опенсорса иногда отвлекаются от Wayland, Mir и прочих systemd и делают годные костыли для простых страждущих.

Объединение файлов pdf в один с помощью PDFSaM

Для тех, кто не хочет перечитывать томик квантовой физики от авторов pdftk, есть вариант с рюшечками и бубенчиками под названием PDF Split and Merge (pdfsam).
Как это всегда бывает, когда что-то кажется слишком прекрасным, чтобы быть правдой, обязательно найдётся заподлянка. И pdfsam не исключение - написан он на Java, а это значит кучи exceptions по поводу и без, лютые тормоза и интерфейс из фильма ужасов.

Установка и использование PDFsam в Linux

Скачать самую свежую версию можно здесь. Запуск этого поделия командой
$ java -jar pdfsam
даёт что-то вроде:


Собственно, дальше всё довольно просто: pdfsam умеет объединять (merge), разрезать (split), поворачивать (rotate) документы PDF. Кроме того, имеет место быть режим burst, при котором из одного PDF-файла будет сделана куча одностраничных.


Например, для объединения PDF-файлов в один, просто добавляем файлы в порядке следования, выбираем новое имя файла и жмём RUN.

Из преимуществ можно отметить разве что графический, скажем так, интерфейс. Всё остальное - это типичное джава приложение: глючное, медленное и корявое (например, при split нужно указывать номер страницы, на единицу меньший той, с которой разрезание начнётся, и т.д.).

Сжатие и компрессия PDF файлов

Побочным продуктом работы pdfsam может быть раздувание PDF-файла до непричиных размеров. Этому горю можно помочь с помощью утилиты gs вот так:
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf
Это может сжать PDF, по крайней мере в большинстве случаев.

Мастерам консоли: резка и склейка PDF файлов в pdftk

PDFtk расшифровывается как pdf tool kit, и, как и подобает настоящему набору инструментов, требует некоторого изучения. Зато работает быстро, умеет много и клацать мышью не надо.
Установка pdftk проста - он уже есть в Debian:
$ sudo apt-get install pdftk
Синтаксис pdftk можно описать примерно так:
pdftk исходный_файл.pdf ДЕЙСТВИЕ страницы output получаемый_файл.pdf
Итак, поехали....

Как разбить PDF файл на несколько

Для того, чтобы разрезать PDF-файл на несколько, нужно воспользоваться ДЕЙСТВИЕМ cat, например вот так:
$ pdftk document.pdf cat 140-142 output zz1.pdf
Эта команда выдаст файл zz1.pdf, в котором будут три страницы, а именно 140, 141 и 142. Если же нужно разбить файл с какой-то страницы до конца, делаем так:
$ pdftk foo.pdf cat 30-end output biography.pdf

Объединение нескольких файлов PDF в один с помощью PDFtk

Та же самая команда cat может склеивать PDF-файлы в один:
$ pdftk zz* cat output Issue26.pdf
служит для объединения всех файлов, содержащих zz в имени, в один Issue26.pdf
Если файлы называются по-разному, можно использовать следующую команду для объединения файлов в один:
$ pdftk 1.pdf 2.pdf ... cat output merged.pdf
будет объединён в один файл merged.pdf.

Изменение полей PDF-документа

Речь идёт о полях в PDF файле вроде автора, заголовка или времени создания:

Не раз и не два товарищи, работающие с документами повышенной важности, оставляли в этих полях значения, подставленные услужливым MS Word - и имели на этом немало проблем. Это можно поправить с помощью pdftk сравнительно легко.
Сначала достаём исходные данные (metadata):
pdftk book.pdf dump_data output report.txt
В этом файле мы увидим нечто вроде:
InfoKey: Title
InfoValue: Coders At Work
InfoKey: Author
InfoValue: Peter Seivel
InfoKey: Subject
InfoValue: Programming
Эти значения можно отредактировать в полученном текстовом файле (report.txt в этом примере) и загрузить обратно:
pdftk book.pdf update_info report.txt output bookcopy.pdf
У pdf-документов могут быть и другие поля, которые тоже можно поправить при желании.

И это ещё не всё!

Возможности pdftk весьма велики, и желающие могут припасть к официальной документации.


Склейка страниц PDF файла в буклет с помощью LaTeX pdfpage

Отличная иллюстрация мощи пакета pdfpages была найдена на tex.stackexchange.com. Идея сводится к тому, что сначала мы создаём исходный документ, а потом ещё один, в который вставляются PDF-страницы в нужном порядке.

Например, у нас есть документ под формат А6, созданный в ЛаТеХе (назовём его mya6doc.pdf:

\documentclass{book}
\usepackage[english]{babel}%
\usepackage[a6paper]{geometry}% http://ctan.org/pkg/geometry
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\begin{document}
\chapter{First chapter} \lipsum[1-10]
\chapter{Second chapter} \lipsum[11-20]
\chapter{Third chapter} \lipsum[21-30]
\chapter{Final chapter} \lipsum[31-40]
\end{document}

Теперь создаём ещё один документ (назовём его mya4doc):

\documentclass{article}
\usepackage[english]{babel}%
\usepackage[a4paper]{geometry}% http://ctan.org/pkg/geometry
\usepackage{pdfpages}% http://ctan.org/pkg/pdfpages
\begin{document}
\includepdf[pages=-,nup=2x2,frame,noautoscale]{mya6doc}%
\end{document}

Скомпилировать его нужно с помощью pdflatex. Это позволит получить все страницы (pages=-) в 2x2 страницы на одной (nup=2x2) с прорисованной границей вокруг каждой страницы (frame).

Это означает, что pdfpages воспринимает вставляемые страницы как изображения, так что можно дополнительно задать поля для обрезки:

\includepdf[pages=1,landscape,clip,trim=1cm 2cm 3cm 4cm,frame,noautoscale,fitpaper=false]{AllTheMyGTDinOneScheme}

то есть страница будет обрезана на 1, 2, 3, 4 сантиметра слева, снизу, справа и сверху. Опция clip=true обрежет страницу.

Путь джедая: склеивание PDF документов с помощью gs

Как многие джедаи уже в курсе, gs это GhostScript, свободный как Столлман интерпретатор postscript и, соответственно, PDF. Командой gs можно не только орехи колоть, но и соединять документы. Соединять документы с помощью Ghostscript можно вот так:
$ gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=finished.pdf file1.pdf file2.pdf
Теперь что это всё значит:

-dBATCH -- после окончания пакетной обработки, GS прекращает работу (без этой опции он будет продолжать имитировать бурную деятельность)
-dNOPAUSE -- обрабатывать каждую страницу без пауз между ними
-q -- тихий режим, без выдачи сообщений
-sDEVICE=pdfwrite -- использовать встроенный обработчик PDF
-sOutputFile=finished.pdf -- записать выхлоп в файл finished.pdf
 
Преимущество такого джедайства в том, что Ghostscript входит во все дистрибутивы Linux и часто уже установлен в системе. И не нужно тащить килотонны джавы.

Сохранение размеров EPS файлов при конвертировании в PDF

Не совсем в тему, но тем не менее про PDF. Дело в том, что при конвертировании файлов EPS в PDF разными поделками вроде ps2pdf вы получаете PDF в виде пустой страницы A4 с картинкой EPS где-то в углу. То есть поделка ps2pdf просто игнорирует выставленный BoundingBox при использовании по умолчанию:
 
$ ps2pdf letterhead.eps
Я не буду говорить о вменяемости авторов ps2pdf, но всякий разработчик с IQ выше комнатной температуры должен понимать, что подобные WTF-моменты в пользовательском опыте в конечном итоге приводят к тому, год линупсов на десктопе уезжает в голубую даль. И это происходит именно из-за таких вот казусов, коих в ёпенсорце год от года становится только больше из-за набегающих леннартов поттерингов и прочих ковбоев, склонных к тяжёлому велосипедостроению там, где этого абсолютно не требуется.
Так как ps2pdf принимает те же аргументы, что и Ghostscript, имеющий 900 газиллионов опций, среди которых должна быть возможность сохранять BoundingBox. И таки да, чудо случилось:

$ ps2pdf -dEPSCrop letterhead.eps

который даёт тот самый PDF, который от него, собственно, и ждёшь.

Заключение

Перечисленные возможности - не предел мечтаний, и всегда можно найти свежесобранный опенсорцовый велосипед со спойлером, антикрыльями и колёсами в форме листа Мёбиуса. Обнаружившим нечто интересное в деле работы с PDF документами просьба не стесняться в комментариях.
Читать далее