Ответ 1
Я написал рубиновый камень, чтобы сделать это - PDF:: Слияние. Он использует iText. Вот как вы его используете:
pdf = PDF::Merger.new
pdf.add_file "foo.pdf"
pdf.add_file "bar.pdf"
pdf.save_as "combined.pdf"
Это было в 2008 году. Надеюсь, теперь лучший ответ.
Как вы можете объединить PDF файлы в ruby?
Я использую pdf-stamper gem, чтобы заполнить форму в формате PDF. Я хотел бы взять n PDF файлов, заполнить форму в каждом из них и сохранить результат как документ n-страницы.
Можете ли вы сделать это с помощью родной библиотеки, такой как креветка? Можете ли вы сделать это с помощью rjb и iText? pdf-stamper - это оболочка на iText.
Я хотел бы избежать использования двух библиотек (т.е. pdftk и iText), если это возможно.
Я написал рубиновый камень, чтобы сделать это - PDF:: Слияние. Он использует iText. Вот как вы его используете:
pdf = PDF::Merger.new
pdf.add_file "foo.pdf"
pdf.add_file "bar.pdf"
pdf.save_as "combined.pdf"
С 2013 года вы можете использовать креветку для объединения PDF файлов. Gist: https://gist.github.com/4512859
class PdfMerger
def merge(pdf_paths, destination)
first_pdf_path = pdf_paths.delete_at(0)
Prawn::Document.generate(destination, :template => first_pdf_path) do |pdf|
pdf_paths.each do |pdf_path|
pdf.go_to_page(pdf.page_count)
template_page_count = count_pdf_pages(pdf_path)
(1..template_page_count).each do |template_page_number|
pdf.start_new_page(:template => pdf_path, :template_page => template_page_number)
end
end
end
end
private
def count_pdf_pages(pdf_file_path)
pdf = Prawn::Document.new(:template => pdf_file_path)
pdf.page_count
end
end
Используйте ghostscript для объединения PDF файлов:
options = "-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite"
system "gs #{options} -sOutputFile=result.pdf file1.pdf file2.pdf"
После долгого поиска чистого Ruby-решения я закончил писать код с нуля, чтобы разобрать и объединить/объединить файлы PDF.
(Я чувствую, что это беспорядок с текущими инструментами - мне нужен что-то native, но все они, похоже, имеют разные проблемы и зависимости... даже Prawn отказался от поддержки шаблонов, которые они используют )
Я разместил драгоценный камень онлайн, и вы можете найти его на GitHub.
вы можете установить его с помощью:
gem install combine_pdf
Он очень прост в использовании (с сохранением или отсутствием данных PDF в файл).
Например, вот "однострочный":
(CombinePDF.load("file1.pdf") << CombinePDF.load("file2.pdf") << CombinePDF.load("file3.pdf")).save("out.pdf")
Если вы обнаружите какие-либо проблемы, сообщите мне, и я поработаю над исправлением.
Не видел отличных опций в Ruby - у меня были лучшие результаты, обходящие pdftk:
system "pdftk #{file_1} multistamp #{file_2} output #{file_combined}"
Мы ближе, чем были в 2008 году, но еще не совсем там.
Последняя версия версии Prawn позволяет использовать существующий PDF в качестве шаблона, но не использовать шаблон снова и снова при добавлении большего количества страниц.
Через iText это будет работать... хотя вы должны сгладить формы, прежде чем объединять их, чтобы избежать конфликтов имен полей. Это или переименовать поля по одной странице за раз.
Внутри PDF поля с тем же именем имеют значение. Обычно это не желаемое поведение, хотя оно время от времени пригодится.
Что-то по строкам (в java):
PdfCopy mergedPDF = new PdfCopy( new Document(), new FileOutputStream( outPath );
for (String path : paths ) {
PdfReader reader = new PdfReader( path );
ByteArrayOutputStream curFormOut = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper( reader, curFormOut );
stamper.setField( name, value ); // ad nauseum
stamper.setFlattening(true); // flattening setting only takes effect during close()
stamper.close();
byte curFormBytes = curFormOut.toByteArray();
PdfReader combineMe = new PdfReader( curFormBytes );
int pages = combineMe .getNumberOfPages();
for (int i = 1; i <= pages; ++i) { // "1" is the first page
mergedForms.addPage( mergedForms.getImportedPage( combineMe, i );
}
}
mergedForms.close();