CombinePDF是一种用纯ruby编写的精美模型,用于解析PDF文件并将其与其他PDF文件组合(合并),加水印或盖章(所有使用PDF文件格式和纯Ruby Code)。
我决定停止维护这颗宝石,希望有人可以接管该宝石的公关评论和维护(或只是打开成功的叉子)。
我之所以写这颗宝石,是因为我需要解决bates数量的问题,使现有的pdf文档划分。
但是,自2014年以来,我一直免费维护宝石,完全无缘无故,除了我喜欢与社区分享它。
我喜欢这个宝石,但是我无法继续保持它,因为我有自己的项目要专注于自己,而且我需要时间和(更重要的是)思维空间。
与Ruby Gems安装:
gem install combine_pdf
快速摘要:
阅读PDF表单时,可能会丢失某些表单数据。我尝试以最好的能力来解决这个问题,但我不确定这一切还可以。
当组合PDF表单时,表单数据可能会统一。我无法解决此问题,因为这是PDF形式的工作方式(填充字段以相同名称填充数据),但是坦率地说,我有点喜欢这个问题……这几乎是一个功能。
在更统一相同的TOC数据时,其中一个引用将与另一个参考统一(这意味着,如果页面看起来相同,则两个引用将链接到同一页面,而不是链接到两个不同的页面)。您可以通过在合并PDF文件之前将内容添加到页面(即向所有页面添加空文本框)来解决此问题。
某些链接和数据(URL链接和PDF“命名目的地”)存储在PDF的根部,并且它们没有从页面上链接回。保留此信息需要合并PDF对象,而不是它们的页面。
从PDF文件中删除页面并将它们与另一个PDF合并时,一些链接将丢失。
一些加密的PDF文件(通常是没有密码的文件)会悄悄地失败,而不是吵闹。如果您希望选择嘈杂的路线,则可以使用CombinePDF.load(pdf_file, raise_on_encrypted: true)
指定raise_on_encrypted
选项,该选项将增加一个CombinePDF::EncryptionError
。
有时,即使可以解析PDF(即,当存在PDF可选内容时),CombinePDF也会引起异常。尽管对于可选的内容PDF,但使用CombinePDF.load(pdf_file, allow_optional_content: true)
。
CombinePDF GEM运行递归代码以解析和格式化PDF文件。因此,PDF文件具有重嵌套的对象,以及以导致环状嵌套的方式组合的文件可能会爆炸堆栈 - 导致异常或程序故障。
CombinePDF本地编写在Ruby中,应该(大概)在所有遵循Ruby 2.0兼容性的Ruby平台上工作。
但是,PDF文件是非常复杂的生物,没有保证。
例如,已知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文件。从内存中加载对于通过Internet或从其他作用库(例如大虾)收到的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
同样,对于加载和解析,也可以对内存或文件执行渲染。
您可以使用.to_pdf
输出PDF数据字符串。例如,让用户从Rails应用程序或Plezi应用程序下载PDF:
# 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文件已加密,有些是压缩的(使用过滤器)...
对加密文件几乎没有支持,并且非常基本和有限的压缩文件支持。
我需要帮助。
如果您想帮助代码,请注意:
我是一个自言自语的嗜好。该文档缺乏,《守则》中的评论是差的指南。
代码本身应该非常直截了当,但请随时询问您想要的任何内容。
Stefan Leitner(@sle1tner)编写了支持包含TOC的PDF的大纲合并代码。
Caige Nichols写了一个令人惊叹的RC4宝石,我在代码中使用了它。
我想安装宝石,但是我在Internet上遇到了问题,最终将代码本身复制到Combine_pdf_decrypt类文件中。
归功于他的美妙之处。请尊重他的执照和版权...和我的。
麻省理工学院
您可以查看GitHub问题页面,并查看“ Help Wants”标签。
如果您正在考虑捐款或向我寄钱 - 无需。这个项目可以在没有您的钱的情况下维持自己。
这个项目需要的是关怀开发人员给它最新并修复他们注意到的任何文档错误或问题的时间...曾经说过,礼物(例如免费咖啡或iTunes礼品卡)总是很有趣。但是我认为,有些真正需要的人将从您的慷慨中受益更多。