CombinePDF ist ein nützliches Modell, das in reinem Ruby geschrieben wurde, um PDF -Dateien zu analysieren und sie mit anderen PDF -Dateien zu kombinieren (zusammenzuarbeiten), sie zu Wasserzeichen oder mit dem Stempel (alle verwenden das PDF -Dateiformat und den reinen Ruby -Code).
Ich beschloss, dieses Juwel nicht mehr aufrechtzuerhalten und zu hoffen, dass jemand die PR -Bewertungen und die Wartung dieses Juwelen übernehmen kann (oder einfach eine erfolgreiche Gabel öffnen).
Ich habe dieses Juwel geschrieben, weil ich ein Problem mit Bates-Numbering vorhandenen PDF-Dokumenten lösen musste.
Seit 2014 habe ich das Edelstein kostenlos und ohne Grund beibehalten, außer dass ich es genossen habe, es mit der Community zu teilen.
Ich liebe dieses Juwel, aber ich kann es nicht weiterhin aufrechterhalten, da ich meine eigenen Projekte habe, um mich zu konzentrieren, und ich brauche sowohl die Zeit als auch (was noch wichtiger) den Mindspace.
Mit Ruby Edelsteinen installieren:
gem install combine_pdf
Schneller Rückgang:
Beim Lesen von PDF -Formularen können einige Formulardaten verloren gehen. Ich habe versucht, dies nach besten Kräften zu beheben, aber ich bin mir nicht sicher, ob alles noch funktioniert.
Bei der Kombination von PDF -Formularen können Formulardaten einheitlich sein. Ich konnte dies nicht beheben, da PDF -Formulare so funktionieren (das Füllen eines Feldes füllt die Daten in jedem Feld mit demselben Namen aus), aber ehrlich gesagt hat es mir das Problem gefallen ... es ist fast eine Funktion.
Wenn dieselben TOC -Daten mehr vereint als einmal, wird eine der Referenzen mit der anderen vereinheitlicht (dh, wenn die Seiten gleich aussehen, verlinken beide Referenzen auf dieselbe Seite, anstatt mit zwei verschiedenen Seiten zu verknüpfen). Sie können dies beheben, indem Sie den Seiten Inhalte hinzufügen, bevor Sie die PDF -Dateien zusammenführen (dh leere Textfelder zu allen Seiten hinzufügen).
Einige Links und Daten (URL -Links und PDF "Named Destinations") werden am Wurzel eines PDF gespeichert und sind nicht mit der Seite zurückgeführt. Wenn diese Informationen beibehalten werden, müssen die PDF -Objekte statt ihrer Seiten zusammengeführt werden.
Einige Links gehen verloren, wenn Seiten aus PDF -Dateien herausgerissen und mit einem anderen PDF zusammengeführt werden.
Einige verschlüsselte PDF -Dateien (normalerweise diejenigen, die Sie ohne Passwort nicht anzeigen können) scheitern leise statt laut. Wenn Sie es vorziehen, die laute Route auszuwählen, können Sie die Option raise_on_encrypted
mit CombinePDF.load(pdf_file, raise_on_encrypted: true)
angeben, die einen CombinePDF::EncryptionError
erhöhen.
Manchmal stellt das Kombinieren eine Ausnahme an, selbst wenn der PDF analysiert werden könnte (dh, wenn der optionale PDF -Inhalt vorliegt) ... Ich finde es besser, mich auf der Seite der Vorsicht zu irren, obwohl für optionale Inhalte PDFs eine Ausnahme unter Verwendung CombinePDF.load(pdf_file, allow_optional_content: true)
.
Das Kombinepdf -Gem wird rekursivem Code ausführen, um die PDF -Dateien sowohl analysieren als auch formatieren. Daher können PDF -Dateien, die stark verschachtelte Objekte haben, sowie solche, die auf eine Weise kombiniert werden, die zu zyklischer Verschachtung führt, den Stapel explodieren - was zu einer Ausnahme oder einem Programmfehler führt.
CombinePDF ist nativ in Ruby geschrieben und sollte (vermutlich) auf allen Ruby -Plattformen arbeiten, die Ruby 2.0 Kompatibilität folgen.
PDF -Dateien sind jedoch ziemlich komplexe Kreaturen und es wird keine Garantie bereitgestellt.
Zum Beispiel ist bekannt haben eine Chance, erhalten zu werden).
Gleiches gilt für PDF -Links und das Inhaltsverzeichnis, die alle globale Attribute haben und bei der Kombination von PDF -Daten beschädigt oder verloren gehen können.
Wenn diese Bibliothek Datenverlust oder Verbrennungen in Ihrem Haus verursacht, bin ich nicht schuld - wie die MIT -Lizenz hervorgeht. Davon abgesehen benutze ich die Bibliothek glücklich, nachdem ich gegen verschiedene Lösungen getestet habe.
PDF -Dateien (oder Daten) kombinieren:
pdf = CombinePDF . new
pdf << CombinePDF . load ( "file1.pdf" ) # one way to combine, very fast.
pdf << CombinePDF . load ( "file2.pdf" )
pdf . save "combined.pdf"
Oder sogar ein One -Liner:
( CombinePDF . load ( "file1.pdf" ) << CombinePDF . load ( "file2.pdf" ) << CombinePDF . load ( "file3.pdf" ) ) . save ( "combined.pdf" )
Sie können auch nur seltsame oder sogar Seiten hinzufügen:
pdf = CombinePDF . new
i = 0
CombinePDF . load ( "file.pdf" ) . pages . each do | page |
i += 1
pdf << page if i . even?
end
pdf . save "even_pages.pdf"
Beachten Sie, dass das Hinzufügen aller Seiten nacheinander langsamer ist und die gesamte Datei hinzufügt.
Um vorhandenen PDF -Seiten Inhalte hinzuzufügen, importieren Sie zuerst die neuen Inhalte aus einer vorhandenen PDF -Datei. Fügen Sie den Inhalt danach zu jedem der Seiten in Ihrem vorhandenen PDF hinzu.
In diesem Beispiel werden wir jeder Seite ein Firmenlogo hinzufügen:
company_logo = CombinePDF . load ( "company_logo.pdf" ) . pages [ 0 ]
pdf = CombinePDF . load "content_file.pdf"
pdf . pages . each { | page | page << company_logo } # notice the << operator is on a page and not a PDF object.
pdf . save "content_with_logo.pdf"
Beachten Sie, dass sich der << Operator auf einer Seite befindet und kein PDF -Objekt. Der << Operator wirkt unterschiedlich auf PDF -Objekten und auf Seiten.
Der << Operator stellt die Injektion aus, indem Referenzen umbenannt werden, um Konflikte zu vermeiden. Bei Überlagerung von Seiten unter Verwendung komprimierter Daten, die möglicherweise nicht bearbeitet werden (aufgrund der begrenzten Filterunterstützung), können Sie verwenden:
pdf . pages ( nil , false ) . each { | page | page << stamp_page }
Das Hinzufügen von Seitenzahlen zu einem PDF -Objekt oder einer Datei ist so einfach wie möglich:
pdf = CombinePDF . load "file_to_number.pdf"
pdf . number_pages
pdf . save "file_with_numbering.pdf"
Die Nummerierung kann mit vielen verschiedenen Optionen durchgeführt werden, mit unterschiedlichem Formating, mit oder ohne Boxobjekt und sogar mit Opazitätswerten - siehe Dokumentation.
Sollten Sie beispielsweise die Seitennummer unten rechts von allen PDF -Seiten vorlegen, tun Sie es vor, die Seitennummer zu platzieren:
pdf . number_pages ( location : [ :bottom_right ] )
Als ein weiteres Beispiel werden die Striche um die Nummer entfernt und eine Schachtel um sie herum platziert. Die Nummerierung ist halbtransparent und die ersten 3 Seiten werden mit Buchstaben (a, b, c) anstelle von Zahlen nummeriert:
# number first 3 pages as "a", "b", "c"
pdf . number_pages ( number_format : " %s " ,
location : [ :top , :bottom , :top_left , :top_right , :bottom_left , :bottom_right ] ,
start_at : "a" ,
page_range : ( 0 .. 2 ) ,
box_color : [ 0.8 , 0.8 , 0.8 ] ,
border_color : [ 0.4 , 0.4 , 0.4 ] ,
border_width : 1 ,
box_radius : 6 ,
opacity : 0.75 )
# number the rest of the pages as 4, 5, ... etc'
pdf . number_pages ( number_format : " %s " ,
location : [ :top , :bottom , :top_left , :top_right , :bottom_left , :bottom_right ] ,
start_at : 4 ,
page_range : ( 3 ..- 1 ) ,
box_color : [ 0.8 , 0.8 , 0.8 ] ,
border_color : [ 0.4 , 0.4 , 0.4 ] ,
border_width : 1 ,
box_radius : 6 ,
opacity : 0.75 )
pdf.number_pages(number_format: " %s ", location: :bottom_right, font_size: 44)
Das Laden von PDF -Daten kann aus dem Dateisystem oder direkt aus dem Speicher erfolgen.
Das Laden von Daten aus einer Datei ist einfach:
pdf = CombinePDF . load ( "file.pdf" )
Sie können auch PDF -Dateien aus dem Speicher analysieren. Das Laden aus dem Speicher ist besonders effektiv zum Importieren von PDF -Daten, die über das Internet oder eine andere Autorierungsbibliothek wie Garnelen erhalten wurden:
pdf_data = prawn_pdf_document . render # Import PDF data from Prawn
pdf = CombinePDF . parse ( pdf_data )
Die Verwendung von parse
ist auch beim Laden von Daten von einem Remote -Standort wirksam, wobei die Notwendigkeit unnötiger temporärer Dateien umgeht. Zum Beispiel:
require 'combine_pdf'
require 'net/http'
url = "https://example.com/my.pdf"
pdf = CombinePDF . parse Net :: HTTP . get_response ( URI . parse ( url ) ) . body
In ähnlicher Weise kann zum Laden und Parsen auch das Rendering entweder entweder mit dem Speicher oder an einer Datei durchgeführt werden.
Sie können eine Zeichenfolge von PDF -Daten mit .to_pdf
ausgeben. So lassen Sie einen Benutzer den PDF entweder aus einer Rails -Anwendung oder einer Plezi -Anwendung herunterladen:
# in a controller action
send_data combined_file . to_pdf , filename : "combined.pdf" , type : "application/pdf"
In Sinatra:
# in your path's block
status 200
body combined_file . to_pdf
headers 'content-type' => "application/pdf"
Wenn Sie es vorziehen, die PDF -Daten in einer Datei zu speichern, können Sie die save
immer wie in unseren früheren Beispielen verwenden.
Einige PDF -Dateien enthalten optionale Inhaltsabschnitte, die nicht immer zuverlässig zusammengeführt werden können. Standardmäßig wird eine Ausnahme angelegt, wenn eine dieser Dateien erkannt wird. Sie können optional einen Parameter allow_optional_content
an den PDFParser.new
, CombinePDF.load
und CombinePDF.parse
-Methoden übergeben:
new_pdf = CombinePDF . new
new_pdf << CombinePDF . load ( pdf_file , allow_optional_content : true )
attachments . each { | att | new_pdf << CombinePDF . load ( att , allow_optional_content : true ) }
Sie können eine Demo für eine "Bates Stumping Web-App" sehen und seinen Code lesen. Viel Glück :)
Einige PDF -Dateien sind verschlüsselt und einige werden komprimiert (die Verwendung von Filtern) ...
Verschlüsselte Dateien und sehr grundlegende und begrenzte Unterstützung für komprimierte Dateien.
Ich brauche Hilfe dabei.
Wenn Sie mit dem Code helfen möchten, beachten Sie bitte:
Ich bin ein selbst gelehrtes Hobbiest im Herzen. Die Dokumentation fehlt und die Kommentare im Code sind schlechte Leitlinien.
Der Code selbst sollte sehr einfach sein, aber Sie können sich gerne fragen, was Sie wollen.
Stefan Leitner (@Sle1tner) schrieb den Umriss -Zusammenführungscode, der PDFs unterstützt, die einen TOC enthalten.
Caige Nichols schrieb ein erstaunliches RC4 -Juwel, das ich in meinem Code verwendet habe.
Ich wollte das Juwel installieren, hatte aber Probleme mit dem Internet und kopierte den Code selbst in die Klassendatei combine_pdf_decrypt.
Erstaunlich seines wunderbaren Ereignisses wird hier gegeben. Bitte respektieren Sie seine Lizenz und sein Urheberrecht ... und meine.
MIT
Sie können sich die Seite mit GitHub -Problemen ansehen und die Tags "Help Wanted" sehen.
Wenn Sie an Spenden denken oder mir Geld schicken - keine Notwendigkeit. Dieses Projekt kann sich ohne Ihr Geld aufrechterhalten.
Was dieses Projekt benötigt, ist die Zeit, die für Pflegeentwickler, die es auf dem neuesten Stand halten und alle Dokumentationsfehler oder Probleme beheben, die sie bemerken. Aber ich denke, es gibt solche, die in echten Bedürfnissen sind, die mehr von Ihrer Großzügigkeit profitieren.