Как вы комбинируете PDF-файлы в ruby?

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

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

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

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

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

8 ответов

Решение

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

pdf = PDF::Merger.new
pdf.add_file "foo.pdf"
pdf.add_file "bar.pdf"
pdf.save_as "combined.pdf"

С 2013 года вы можете использовать креветки для объединения 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

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

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

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

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

gem install combine_pdf

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

Например, вот "одна строка":

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

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

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

 options = "-q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite"
 system "gs #{options} -sOutputFile=result.pdf file1.pdf file2.pdf"

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

system "pdftk #{file_1} multistamp #{file_2} output #{file_combined}"

Через 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();

Если вы хотите добавить какой-либо шаблон (созданный с помощью macOS Pages или Google Docs) с помощью гема comb_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"

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

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

Другие вопросы по тегам