如何在ruby中组合PDF?

时间:2010-08-17 05:28:24

标签: ruby pdf pdf-generation itext pdftk

这是asked in 2008。希望现在有更好的答案。

如何在ruby中组合PDF?

我正在使用pdf-stamper gem填写PDF格式的表单。我想要 n PDF,在每个PDF中填写表格,并将结果保存为 n 页面文件。

你能用像prawn这样的本地库来做这件事吗?你能用rjb和iText做到这一点吗? pdf-stamper是iText的包装器。

如果可能的话,我想避免使用两个库(即pdftk和iText)。

8 个答案:

答案 0 :(得分:19)

截至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

答案 1 :(得分:15)

经过长时间搜索纯Ruby解决方案后,我最终从头开始编写代码来解析和合并/合并PDF文件。

(我觉得现在的工具太乱了 - 我想要一些东西原生,但它们似乎都有不同的问题和依赖...甚至Prawn放弃了他们用来拥有的模板支持)

我发布了宝石online,您也可以在GitHub找到它。

您可以使用以下方式安装:

gem install combine_pdf

它非常易于使用(无论是否将PDF数据保存到文件中)。

例如,这是一个“单行”:

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

如果您发现任何问题,请告诉我,我会继续修复。

答案 2 :(得分:11)

使用ghostscript组合PDF:

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

答案 3 :(得分:5)

我写了一个红宝石宝石来做这件事 - PDF::Merger。它使用iText。以下是您使用它的方式:

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

答案 4 :(得分:2)

在Ruby中没有看到很好的选择 - 我得到了最好的结果炮轰pdftk

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

答案 5 :(得分:0)

我们比2008年更接近,但还不是那么。

Prawn的最新开发版本允许您使用现有PDF作为模板,但在添加更多页面时不能反复使用模板。

答案 6 :(得分:0)

通过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();

答案 7 :(得分:0)

如果您想使用 combine_pdf gem 添加任何模板(由macOS Pages或Google Docs创建),则可以尝试以下操作:

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"