CombinePDF - это отличная модель, написанная в Pure Ruby, для анализа файлов PDF и комбинирования (слияния) с другими файлами PDF, водяным знаком или штамкой (все используя формат файла PDF и чистый код Ruby).
Я решил прекратить поддерживать этот драгоценный камень и надеюсь, что кто -то сможет взять на себя пиар -отзывы и обслуживание этого драгоценного камня (или просто открыть успешную вилку).
Я написал этот драгоценный камень, потому что мне нужно было решить проблему с существующими документами PDF-номера Бейтса.
Однако с 2014 года я поддерживал драгоценность бесплатно и без причины, за исключением того, что мне нравилось делиться им с сообществом.
Мне нравится этот драгоценный камень, но я не могу продолжать поддерживать его, так как у меня есть свои собственные проекты, чтобы сосредоточиться, и мне нужно как время, так и (что более важно) для разума.
Установите с помощью рубиновых драгоценных камней:
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 CombinePDF запускает рекурсивный код как для Parse, так и для форматирования файлов PDF. Следовательно, файлы PDF, которые имеют сильно вложенные объекты, а также факторы, которые объединяются таким образом, что приводит к циклическому гнездованию, могут взорвать стек, что приводит к исключению или сбое программы.
CombinePDF написан назначен в Ruby и должен (предположительно) работать на всех платформах Ruby, которые следуют совместимости Ruby 2.0.
Тем не менее, файлы PDF являются довольно сложными существами, и никаких гарантий не предоставляется.
Например, известно, что формы PDF имеют проблемы, и данные формы могут быть потеряны при попытке объединить PDF с заполненными данными формы (также формы являются глобальными объектами, а не специфичными для страниц, поэтому следует объединить весь PDF для любых данных с иметь шанс быть сохраненным).
То же самое относится и к ссылкам на PDF и содержимого таблицы, которые имеют глобальные атрибуты и могут быть повреждены или потеряны при объединении данных PDF.
Если эта библиотека вызывает потерю данных или сжигает ваш дом, я не виноват - как указывает лицензия MIT. Тем не менее, я счастливо использую библиотеку после тестирования против различных решений.
Чтобы объединить файлы 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 ] )
В качестве другого примера, черты вокруг номера удаляются, и вокруг него расположена коробка. Нумерация полупрозрачной, а первые 3 страницы пронумерованы с использованием букв (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 Stumping Web-App» и прочитать его код. Удачи :)
Некоторые файлы PDF зашифрованы, а некоторые сжаты (использование фильтров) ...
Существует очень небольшая поддержка зашифрованных файлов и очень основной и ограниченной поддержки сжатых файлов.
Мне нужна помощь с этим.
Если вы хотите помочь с кодом, имейте в виду:
Я самоучастен в душе. Документация не хватает, а комментарии в коде являются плохими руководящими руководствами.
Сам код должен быть очень простым, но не стесняйтесь спрашивать, что вы хотите.
Стефан Лейтнер (@SLE1TNER) написал контур слияния слияния, поддерживающий PDF, которые содержат TOC.
Caige Nichols написал удивительный драгоценный камень RC4, который я использовал в своем коде.
Я хотел установить драгоценный камень, но у меня были проблемы с Интернетом, и в итоге он копировал сам код в файл класса combine_pdf_decrypt.
Кредит его чудесному приведению здесь. Пожалуйста, уважайте его лицензию и авторские права ... и мой.
Грань
Вы можете посмотреть на страницу проблем Github и увидеть теги «Помогите разыскиваться».
Если вы думаете о пожертвованиях или отправляете мне деньги - нет необходимости. Этот проект может поддерживать себя без ваших денег.
Этот проект нуждается в том, что время, которое дано ухаживающим за разработчиками, которые поддерживают его в курсе и исправляют любые ошибки или проблемы документации, которые они замечают ... Сказав это, подарки (такие как бесплатный кофе или подарочные карты iTunes) всегда веселые. Но я думаю, что есть те, кто в реальной потребности, больше выиграет от вашей щедрости.