Как вы комбинируете PDF-файлы в ruby? - PullRequest
16 голосов
/ 17 августа 2010

Это было в 2008 году . Надеюсь, теперь есть лучший ответ.

Как объединить PDF-файлы в ruby?

Я использую pdf-stamper gem , чтобы заполнить форму в PDF. Я хотел бы взять n PDF-файлов, заполнить форму в каждом из них и сохранить результат в виде n -страничного документа.

Можете ли вы сделать это с нативной библиотекой, такой как креветка? Вы можете сделать это с помощью RJB и iText? pdf-stamper - это обертка на iText.

Я бы по возможности не использовал две библиотеки (т.е. pdftk и iText).

Ответы [ 8 ]

20 голосов
/ 11 января 2013

Начиная с 2013 года вы можете использовать Prawn для объединения PDF-файлов. Суть: 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
15 голосов
/ 10 сентября 2014

После долгих поисков чистого решения на Ruby я в итоге написал код с нуля, чтобы анализировать и объединять / объединять PDF-файлы.

(я чувствую, что это беспорядок с текущими инструментами - я хотелчто-то нативное но все они, похоже, имеют разные проблемы и зависимости ... даже Prawn отбросил поддержку шаблонов, которую они используют)

Я разместил гем онлайн ивы также можете найти его на GitHub .

вы можете установить его с помощью:

gem install combine_pdf

Это очень просто в использовании (с сохранением или без сохранения данных PDF вфайл).

Например, вот «однострочный»:

(CombinePDF.load("file1.pdf") << CombinePDF.load("file2.pdf") << CombinePDF.load("file3.pdf")).save("out.pdf")

Если вы обнаружите какие-либо проблемы, пожалуйста, сообщите мне, и я поработаю над исправлением.

11 голосов
/ 19 января 2012

Используйте ghostscript для объединения PDF-файлов:

 options = "-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite"
 system "gs #{options} -sOutputFile=result.pdf file1.pdf file2.pdf"
5 голосов
/ 20 октября 2010

Я написал для этого рубиновый камень - PDF :: Merger . Он использует iText. Вот как вы это используете:

pdf = PDF::Merger.new
pdf.add_file "foo.pdf"
pdf.add_file "bar.pdf"
pdf.save_as "combined.pdf"
2 голосов
/ 11 января 2014

Я не видел отличных опций в Ruby - я получил лучшие результаты, набрав pdftk :

system "pdftk #{file_1} multistamp #{file_2} output #{file_combined}"
0 голосов
/ 11 сентября 2018

Если вы хотите добавить какой-либо шаблон (созданный с помощью macOS Pages или Google Docs) с помощью Объединить_pdf гем , то вы можете попробовать это:

final_pdf = CombinePDF.new
company_template = CombinePDF.load(template_file.pdf).pages[0]
pdf = CombinePDF.load (content_file.pdf)
pdf.pages.each {|page| final_pdf << (company_template << page)} 
final_pdf.save "final_document.pdf"
0 голосов
/ 19 октября 2010

Через 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();
0 голосов
/ 17 августа 2010

Мы ближе, чем были в 2008 году, но пока еще не совсем.

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

...