CombinPDF هو نموذج أنيق ، مكتوب في Ruby Pure ، لتحليل ملفات PDF ودمجها (دمج) مع ملفات PDF أخرى ، علامة مائية لهم أو ختمها (كلها باستخدام تنسيق ملف PDF ورمز Ruby Pure).
قررت التوقف عن الحفاظ على هذه الأحجار الكريمة وآمل أن يتمكن شخص ما من تولي مراجعات العلاقات العامة وصيانة هذه الأحجار الكريمة (أو ببساطة فتح شوكة ناجحة).
لقد كتبت هذه الأحجار الكريمة لأنني كنت بحاجة إلى حل مشكلة مع ترقيم مستندات PDF الحالية.
ومع ذلك ، منذ عام 2014 ، كنت أحافظ على الأحجار الكريمة مجانًا ولم يكن لها سبب على الإطلاق ، إلا أنني استمتعت بمشاركتها مع المجتمع.
أنا أحب هذه الأحجار الكريمة ، لكنني لا أستطيع الاستمرار في الحفاظ عليها لأن لدي مشاريعي الخاصة للتركيز على كل من الوقت و (الأهم من ذلك) Mindspace.
تثبيت مع روبي الأحجار الكريمة:
gem install combine_pdf
المتهدمة السريعة:
عند قراءة نماذج PDF ، قد تضيع بعض بيانات النموذج. حاولت إصلاح هذا الأمر بأفضل ما لدي من قدرتي ، لكنني لست متأكدًا من أن كل شيء يعمل حتى الآن.
عند الجمع بين نماذج PDF ، قد تكون بيانات النموذج موحدة. لم أستطع إصلاح هذا لأن هذه هي الطريقة التي تعمل بها نماذج PDF (تملأ حقل يملأ البيانات في أي حقل بنفس الاسم) ، لكنني بصراحة ، لقد أحببت المشكلة ... إنها ميزة تقريبًا.
عند توحيد نفس بيانات TOC أكثر من ذلك مرة واحدة ، سيتم توحيد أحد المراجع مع الآخر (وهذا يعني أنه إذا كانت الصفحات تبدو كما هي ، فسترتبط كلتا المراجعين بنفس الصفحة بدلاً من ربط صفحتين مختلفتين). يمكنك إصلاح هذا عن طريق إضافة محتوى إلى الصفحات قبل دمج ملفات PDF (أي إضافة مربعات نصية فارغة إلى جميع الصفحات).
يتم تخزين بعض الروابط والبيانات (روابط URL و PDF "الوجهات المسماة") في جذر PDF ولا يتم ربطها مرة أخرى من الصفحة. يتطلب الحفاظ على هذه المعلومات دمج كائنات PDF بدلاً من صفحاتها.
سيتم فقد بعض الروابط عند تمزيق الصفحات من ملفات PDF ودمجها مع PDF آخر.
ستفشل بعض ملفات PDF المشفرة (عادة ما لا يمكنك عرضها بدون كلمة مرور) بهدوء بدلاً من صاخبة. إذا كنت تفضل اختيار المسار الصاخب ، فيمكنك تحديد الخيار raise_on_encrypted
باستخدام CombinePDF.load(pdf_file, raise_on_encrypted: true)
الذي سيثير CombinePDF::EncryptionError
.
في بعض الأحيان ، ستثير CombinePDF استثناءًا حتى لو كان يمكن تحليل PDF (أي ، عند وجود محتوى اختياري PDF) ... أجد أنه من الأفضل أن أخطئ على جانب الحذر ، على الرغم من أن محتوى PDF الاختياري يمكن تجنبه باستخدام CombinePDF.load(pdf_file, allow_optional_content: true)
.
تعمل GEM COMMONPDF على تشغيل التعليمات البرمجية العودية إلى كل من تحليل ملفات PDF وتنسيقها. وبالتالي ، فإن ملفات PDF التي تحتوي على كائنات متداخلة بشكل كبير ، وكذلك تلك التي تم دمجها بطريقة تؤدي إلى تعشيش دوري ، قد تنفجر المكدس - مما يؤدي إلى فشل استثناء أو في البرنامج.
يتم كتابة CombinPDF أصليًا في Ruby ويجب (من المفترض) أن تعمل على جميع منصات Ruby التي تتبع توافق Ruby 2.0.
ومع ذلك ، فإن ملفات PDF هي مخلوقات معقدة للغاية ولا يتم توفير أي ضمان.
على سبيل المثال ، من المعروف أن نماذج PDF لديها مشكلات وقد تضيع بيانات النموذج عند محاولة الجمع بين PDF مع بيانات النماذج المملوءة (أيضًا ، النماذج هي كائنات عالمية ، وليس محددة للصفحة ، لذلك ينبغي للمرء أن يجمع بين PDF بالكامل لأي بيانات إلى لديك أي فرصة للحفاظ على).
وينطبق الشيء نفسه على روابط PDF وجدول المحتويات ، والتي تحتوي جميعها على سمات عالمية ويمكن أن تفسدها أو فقدها عند الجمع بين بيانات PDF.
إذا تسببت هذه المكتبة في فقدان البيانات أو تحرق منزلك ، فأنا لا ألوم - كما أشار إلى ترخيص معهد ماساتشوستس للتكنولوجيا. ومع ذلك ، أنا أستخدم المكتبة بسعادة بعد الاختبار ضد حلول مختلفة.
لدمج ملفات PDF (أو البيانات):
pdf = CombinePDF . new
pdf << CombinePDF . load ( "file1.pdf" ) # one way to combine, very fast.
pdf << CombinePDF . load ( "file2.pdf" )
pdf . save "combined.pdf"
أو حتى بطانة واحدة:
( CombinePDF . load ( "file1.pdf" ) << CombinePDF . load ( "file2.pdf" ) << CombinePDF . load ( "file3.pdf" ) ) . save ( "combined.pdf" )
يمكنك أيضًا إضافة صفحات غريبة أو حتى:
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"
لاحظ أن إضافة جميع الصفحات الأولى تلو الأخرى هو أبطأ ثم إضافة الملف بأكمله.
لإضافة محتوى إلى صفحات PDF الموجودة ، أولاً استيراد المحتوى الجديد من ملف PDF موجود. بعد ذلك ، أضف المحتوى إلى كل صفحة من الصفحات في PDF الحالية.
في هذا المثال ، سنضيف شعار الشركة إلى كل صفحة:
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"
لاحظ أن << عامل على الصفحة وليس كائن PDF. يعمل << المشغل بشكل مختلف على كائنات PDF وعلى الصفحات.
تقصير << المشغل لتأمين الحقن عن طريق إعادة تسمية المراجع لتجنب الصراع. بالنسبة لتراكب الصفحات باستخدام بيانات مضغوطة قد لا تكون قابلة للتحرير (بسبب دعم المرشح المحدود) ، يمكنك استخدام:
pdf . pages ( nil , false ) . each { | page | page << stamp_page }
يعد إضافة أرقام الصفحات إلى كائن أو ملف PDF بسيطًا قدر الإمكان:
pdf = CombinePDF . load "file_to_number.pdf"
pdf . number_pages
pdf . save "file_with_numbering.pdf"
يمكن إجراء الترقيم مع العديد من الخيارات المختلفة ، مع تشكيلات مختلفة ، مع أو بدون كائن مربع ، وحتى مع قيم العتامة - انظر الوثائق.
على سبيل المثال ، إذا تفضل وضع رقم الصفحة على الجانب الأيمن السفلي لجميع صفحات PDF ، هل:
pdf . number_pages ( location : [ :bottom_right ] )
كمثال آخر ، تتم إزالة الشرطات حول الرقم ووضع مربع حوله. الترقيم شبه شفاف ويتم ترقيم الصفحات الثلاث الأولى باستخدام الحروف (A ، B ، C) بدلاً من الأرقام:
# 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)
يمكن إجراء تحميل بيانات PDF من نظام الملفات أو مباشرة من الذاكرة.
من السهل تحميل البيانات من ملف:
pdf = CombinePDF . load ( "file.pdf" )
يمكنك أيضًا تحليل ملفات PDF من الذاكرة. يعد التحميل من الذاكرة فعالًا بشكل خاص لاستيراد بيانات PDF التي تم استلامها عبر الإنترنت أو من مكتبة تأليف مختلفة مثل الروبيان:
pdf_data = prawn_pdf_document . render # Import PDF data from Prawn
pdf = CombinePDF . parse ( pdf_data )
يعد استخدام parse
فعالًا أيضًا عند تحميل البيانات من موقع بعيد ، مع التحايل على الحاجة إلى ملفات مؤقتة غير ضرورية. على سبيل المثال:
require 'combine_pdf'
require 'net/http'
url = "https://example.com/my.pdf"
pdf = CombinePDF . parse Net :: HTTP . get_response ( URI . parse ( url ) ) . body
وبالمثل ، إلى التحميل والتحليل ، يمكن أيضًا إجراء التقديم إما إلى الذاكرة أو إلى ملف.
يمكنك إخراج سلسلة من بيانات PDF باستخدام .to_pdf
. على سبيل المثال ، للسماح للمستخدم بتنزيل ملف PDF من تطبيق Rails أو تطبيق Plezi:
# in a controller action
send_data combined_file . to_pdf , filename : "combined.pdf" , type : "application/pdf"
في سيناترا:
# in your path's block
status 200
body combined_file . to_pdf
headers 'content-type' => "application/pdf"
إذا كنت تفضل حفظ بيانات PDF في ملف ، فيمكنك دائمًا استخدام طريقة save
كما فعلنا في أمثلةنا السابقة.
تحتوي بعض ملفات PDF على أقسام محتوى اختيارية لا يمكن دمجها دائمًا بشكل موثوق. بشكل افتراضي ، يتم إثارة استثناء إذا تم اكتشاف أحد هذه الملفات. يمكنك اختياريًا تمرير معلمة allow_optional_content
إلى PDFParser.new
، CombinePDF.load
و CombinePDF.parse
أساليب:
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 ) }
يمكنك رؤية عرض توضيحي لـ "تطبيق الويب Bates Restumping" وقراءة رمزه. حظ سعيد :)
يتم تشفير بعض ملفات PDF وبعضها مضغوط (استخدام المرشحات) ...
هناك القليل جدًا من الدعم للملفات المشفرة ودعم أساسي ومحدود للغاية للملفات المضغوطة.
أحتاج إلى مساعدة في ذلك.
إذا كنت ترغب في المساعدة في الرمز ، فيرجى أن تكون على علم:
أنا متعلم نفسي هو الهوائية في القلب. الوثائق غير موجودة والتعليقات في الكود هي إرشادات سيئة.
يجب أن يكون الكود نفسه مستقيمًا جدًا للأمام ، لكن لا تتردد في السؤال عن ما تريد.
كتب Stefan Leitner (@sle1tner) رمز دمج المخطط التفصيلي الذي يدعم ملفات PDF التي تحتوي على TOC.
كتب Caige Nichols جوهرة RC4 مذهلة استخدمتها في الكود الخاص بي.
كنت أرغب في تثبيت الأحجار الكريمة ، لكنني واجهت مشكلات مع الإنترنت وانتهى بي الأمر بنسخ الكود نفسه في ملف فئة Combine_PDF_Decrypt.
يرجع الفضل إلى رائع هنا. يرجى احترام ترخيصه وحقوق الطبع والنشر ... ولي.
معهد ماساتشوستس للتكنولوجيا
يمكنك إلقاء نظرة على صفحة مشكلات GitHub ومشاهدة علامات "Help Wanted".
إذا كنت تفكر في التبرعات أو ترسل لي المال - لا حاجة. هذا المشروع يمكن أن يحافظ على نفسه بدون أموالك.
ما يحتاجه هذا المشروع هو الوقت الذي يقدمه المطورين الذين يحافظون عليه على تحديثه ويصلحون أي أخطاء أو مشكلات توثيق يلاحظونها ... بعد أن قلت ذلك ، فإن الهدايا (مثل بطاقات هدايا القهوة أو iTunes المجانية) هي دائمًا ممتعة. لكنني أعتقد أن هناك من يحتاجون إلى الاستفادة أكثر من كرمك.