2010-08-17 9 views
15

Esto era asked in 2008. Espero que haya una mejor respuesta ahora.¿Cómo se combinan los archivos PDF en rubí?

¿Cómo se pueden combinar archivos PDF en rubí?

Estoy usando el pdf-stamper gem para completar un formulario en un PDF. Me gustaría tomar n PDFs, completar un formulario en cada uno de ellos y guardar el resultado como un documento n -page.

¿Se puede hacer esto con una biblioteca nativa como la gamba? ¿Puedes hacer esto con rjb e iText? pdf-stamper es un contenedor en iText.

Me gustaría evitar el uso de dos bibliotecas (es decir, pdftk e iText), si es posible.

Respuesta

5

me escribió una gema de rubíes para hacer esto - PDF::Merger. Utiliza iText. He aquí cómo lo usa:

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

Tengo curiosidad en cuanto a la Licencia iText. Si tiene una aplicación Rails, ¿tiene que comprar una licencia o puede usarla sin tener que abrir toda la aplicación? – taelor

+0

iText <= 4.2 es MPL/LGPL. iText> = 5.0 es Affero GPL. pdf-fusion usa 4.2. –

+0

¿Puedo tomar un pdf remoto de un cubo de Amazon y combinarlo con tu joya? – ajbraus

0

Estamos más cerca de lo que estábamos en 2008, pero todavía no llegamos a ese punto.

La última versión de desarrollo de Prawn le permite usar un PDF existente como plantilla, pero no usar una plantilla una y otra vez a medida que agrega más páginas.

0

A través de iText, esto funcionará ... aunque debe aplanar los formularios antes de fusionarlos para evitar conflictos de nombre de campo. Eso o renombrar los campos una página a la vez.

Dentro de PDF, los campos con el mismo nombre comparten un valor. Por lo general, este no es el comportamiento deseado, aunque resulta útil de vez en cuando.

Algo a lo largo de las líneas (en 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

Hay una forma mucho más simple de hacer esto: puede usar PDFCopyFields y addDocument. Mira la gema que hice. –

+0

Concedido, pero PdfCopyFields no cambiará el nombre de los campos ... y dado el "mismo nombre == mismo valor", pensé que aplanar sería la mejor ruta. Creo que el cambio de nombre de campo sería correcto en el callejón de CopyField, pero no veo nada en la API ref: http://api.itextpdf.com/. PdfStamper puede cambiar los nombres de los campos, pero no manejará la importación por usted. Tristemente iText tiene este tipo de problema tipo "no se puede caminar y mascar chicle" con bastante frecuencia, lo que requiere que usted cree, "guarde" y lea el mismo PDF para aplicarlo a otra cosa. No es terriblemente eficiente, pero funciona, y es difícil ser el precio. –

10

Uso Ghostscript para combinar archivos PDF:

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

Esto hizo el truco para mí después de renunciar a la gamba. – lobati

20

A partir de 2013 se puede utilizar gambas fusionar archivos PDF. Síntesis: 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 
+0

Gracias. Enorme ahorro de tiempo. Podría reemplazar la gema pdf-fusión anterior que hizo uso de Java. puaj. Esta debería ser la respuesta aceptada. – Hendrik

+1

He combinado miles de archivos PDF en uno con este script. ¡Gracias! – barbolo

+0

Tenga en cuenta que las plantillas de gambas no funcionan con todos los archivos PDF: se trata de un problema conocido y han considerado [** quitar el soporte para ello **] (https://groups.google.com/forum/#!topic/prawn -ruby/S6gXA-i0-do) en total. Hasta ahora, sigue siendo la mejor solución de Ruby. – Yarin

1

no hemos visto grandes opciones en Ruby- me dieron mejores resultados que los bombardeos a cabo pdftk:

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

Después de una larga búsqueda de una solución pura de Ruby, terminé de escribir código desde cero para analizar y combinar/combinar archivos PDF.

(creo que es un lío con las herramientas actuales - quería algo nativa pero todos ellos parecen tener diferentes temas y dependencias ... incluso gambas dejó caer la ayuda de la plantilla solían tener)

Publiqué la gema online y la puede encontrar en GitHub también.

puede instalarlo con:

gem install combine_pdf 

Es muy fácil de usar (con o sin guardar los datos de PDF a un archivo).

Por ejemplo, aquí es un "one-liner":

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

Si encuentra algún problema, por favor hágamelo saber y voy a trabajar en una solución.

+0

¿Puedo usar 'combine_pdf' para combinar varios archivos PDF de diferentes tamaños en uno con varias páginas, por lo que, por ejemplo, combinar 8 archivos PDF con un nuevo archivo PDF de 2 páginas? –

+0

Lo probé con diferentes tamaños de página y combina los archivos PDF sin problemas. los tamaños de página originales permanecen persistentes. No estoy seguro de lo que quiere decir con la combinación de 8 archivos y la obtención de 2 páginas - ¿Supongo que quería decir 2 tamaños de página ...? – Myst

+0

Me refiero a fusionar 2 PDF de tamaño A5 en 1 PDF de tamaño A4, por ejemplo. –

Cuestiones relacionadas