如何使用 Ruby 在现有 PDF 上编辑或书写?

Posted

技术标签:

【中文标题】如何使用 Ruby 在现有 PDF 上编辑或书写?【英文标题】:How to edit or write on existing PDF with Ruby? 【发布时间】:2012-02-29 10:51:52 【问题描述】:

我有几个 PDF 模板文件,其中包含复杂的内容和几个空白区域/区域。我需要能够在这些空白区域写入文本并将生成的 PDF 保存在文件夹中。

我用谷歌搜索了这个问题的答案,但我没有找到明确的答案。更好的解决方案之一是PDF::Toolkit,但它需要购买 Adob​​e Acrobat 才能为现有 PDF 文档添加可替换属性。

php 世界拥有FPDI 的祝福,它可用于简单地打开 PDF 文件并在现有内容上书写/绘图。有一个 Ruby port of this library,但它的最后一次提交发生在 2009 年初。而且该项目看起来并不被广泛使用和支持。

问题是:在现有 PDF 上编辑、书写或绘图的更好的 Ruby 方式是什么?

这里似乎也没有回答这个问题。这些问题是相关的,但并不完全相同:

Prawn gem: How to create the .pdf from an *existing* file (.xls) watermark existing pdf with ruby Ruby library for manipulating existing PDF How to replace a word in an existing PDF using Ruby Prawn?

【问题讨论】:

【参考方案1】:

我能想到的最好的是Rails-latex,它不允许你编辑现有的PDF文件,但它允许你设置模板*.tex.erb,你可以动态修改并将它们编译成PDF格式(以及 dvi 和其他一些)。

【讨论】:

感谢您的回答,但就我而言,编辑现有的 PDF 文件是一项要求。对于创建新的 PDF,像虾之类的东西对我有用......【参考方案2】:

您必须查看Prawn gem,通过它您可以生成任何自定义 pdf 文件。您实际上可以使用 prawn 将文本写入现有 pdf,将现有 PDF 视为新 Prawn 文档的模板。

例如:

filename = "#Prawn::DATADIR/pdfs/multipage_template.pdf"
Prawn::Document.generate("full_template.pdf", :template => filename) do
  text "THis content is written on the first page of the template", :align => :center
end

这会将文本写入旧 pdf 的第一页。

在此处查看更多信息: http://prawn.majesticseacreature.com/manual.pdf

【讨论】:

是的,我已经考虑过了(甚至在我的问题中列出了),但是编辑现有的 PDF 是我的项目的一项要求。谢谢你的回答。 我有这个问题,知道吗? ***.com/questions/12076299/… 我正是使用这种方法在现有 PDF 中广泛添加文本。为什么这个答案对你不起作用? 对模板的支持在 Prawn 0.13.0 中被删除,在 0.14.0 中默认禁用,在 0.15.0 中被提取。 - 来自github.com/prawnpdf/prawn-templates 在 Prawn 中弃用模板支持后(详见@MichaelReinsch 的帖子),我最终编写了一个 Ruby 实现,用于组合 PDF 文件、标记它们、合并它们(按顺序以及顶部的一个另一个),添加简单的文本,提取PDF字体和其他简单的任务。稍后在 Paweł Gościcki 的回答中提到了这颗宝石:combine_pdf【参考方案3】:

PDFLib 似乎可以做你想做的事情并且有 ruby​​ 绑定。

【讨论】:

这确实看起来是一个很棒的工具,但由于它不是开源的(不是免费的)——我们必须考虑价格。我们可以使用的版本大约是 2100 美元——这是我们很多低预算的小项目。此外,这可能不能被视为“Rails-way”,因为它非常昂贵:) 我可能会继续使用 PDF::Toolkit 并使用它来填充 PDF 属性值,而不是在 PDF 上绘图。但是谢谢你的回答——我真的很感激! 是的,一开始总是很难咬下这么大的成本。前段时间购买了 Prince XML 用于制作 PDF,当时看起来是一大笔钱,但已经得到了回报。 我也将 Prince XML 用于我的其他项目之一 - 它有效,但不幸的是,我试图解决的不是这种情况。 值得注意的是,版本“n-1” - v7 - 是免费提供的,源代码pdflib.com/en/download/free-software/pdflib-lite-7 - 通过,不支持。我也不知道功能减少了多少“精简版”。【参考方案4】:

由于Prawn 已删除模板功能(它充满了错误),我发现最简单的方法如下:

    使用Prawn 生成仅包含您要添加的动态部分的PDF。 使用PDF::Toolkit(包装PDFtk)将Prawn PDF 与原始文件合并。

粗略的例子:

require 'prawn'
require 'pdf/toolkit'

template_filename = 'some/dir/Awesome-Graphics.pdf'
prawn_filename = 'temp.pdf'
output_filename = 'output.pdf'

Prawn::Document.generate(prawn_filename) do
  # Generate whatever you want here.
  text_box "This is some new text!", :at => [100, 300]
end

PDF::Toolkit.pdftk(prawn_filename, "background", template_filename, "output", output_filename)

【讨论】:

【参考方案5】:

我推荐prawn 用于生成PDF,然后使用combine_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"

【讨论】:

我发现这对我来说效果不佳,因为“徽标”文件(对我来说,它是一个整体模板,我只是添加了一点文本)将涵盖添加我添加的任何内容(使用 Prawn::PDF,类似于其他一些答案)。不过,我发现这可以为我解决这个问题(替换此答案中第 3 行块内的内容):page.replace(company_logo.copy &lt;&lt; page) 这对我有用,我认为比the PDF::Toolkit route 更清晰的解决方案对我不起作用。【参考方案6】:

根据我的研究,Prawn 是我发现的免费且最好的宝石之一。模板功能在更高版本中不起作用。我能找到与模板一起使用的最新版本是 1.0.0.rc2 - 2013 年 3 月 1 日。找不到任何与模板一起使用的更高版本。因此,如果您使用的是比这更高的版本,请注意。查看下面的线程以获取更多信息。

https://groups.google.com/forum/#!searchin/prawn-ruby/prawn$20templates/prawn-ruby/RYGPImNcR0I/7mxtnrEDHeQJ

PDFtk 是另一个功能强大的 PDF 操作工具和模板。但它提到了以下几点,

此库可供个人免费使用,但如果使用则需要许可证 在生产中 这是一个非 ruby​​ 命令行工具

更多信息请参考以下链接 http://adamalbrecht.com/2014/01/31/pre-filling-pdf-form-templates-in-ruby-on-rails-with-pdftk/

【讨论】:

【参考方案7】:

您不需要使用多个宝石的组合,您可以只使用一个宝石!

在 Ruby/Rails 中使用 PDF 确实具有挑战性(所以我发现了!)

这是我能够在 rails 中将文本动态添加到 PDF 的方式。

将此 gem 添加到您的 gem 文件 gem combine_pdf

然后你可以使用这样的代码:

# get the record from the database to add dynamically to the pdf
user = User.last

# get the existing pdf
pdf = CombinePDF.load "#Rails.root/public/pdf/existing_pdf.pdf"

# create a textbox and add it to the existing pdf on page 2
pdf.pages[1].textbox "#user.first_name #user.last_name", height: 20, width: 70, y: 596, x: 72

# output the new pdf which now contains your dynamic data
pdf.save "#Rails.root/public/pdf/output#Time.now.to_s.pdf"

您可以在此处找到文本框方法的详细信息:https://www.rubydoc.info/gems/combine_pdf/0.2.5/CombinePDF/Page_Methods#textbox-instance_method

我花了好几天的时间研究许多不同的宝石:prawnwicked_pdfpdfkitfillable_pdf

但这对我来说是 2019 年迄今为止最顺利的解决方案。

我希望这可以为某人节省大量时间,这样他们就不必经历我在使用 PDF 时必须经历的所有试验和错误!!

【讨论】:

哇 :) 我不知道为什么这个答案的支持率很低..这应该是最重要的..你已经给出了完整的工作代码和一个优雅的解决方案.. @CodeTree 谢谢,很高兴它为您节省了我所经历的所有痛苦!随意点赞,这样可以帮助更多人!【参考方案8】:

您可以使用Origami gem 为现有的 pdf 添加密码或对其进行编辑。

pdf = WickedPdf.new.pdf_from_url(pdf_params[:url])
temp_file = Tempfile.new('temp', encoding: 'ascii-8bit')
temp_file.write(pdf)

# Creates an encrypted document with AES256 and passwords.
pdf = PDF.read(temp_file.path).encrypt(cipher: 'aes', key_size: 256,user_passwd: pdf_params[:user_password], owner_passwd: pdf_params[:owner_password])
save_path = "#File.basename(__FILE__, ".rb").pdf"

pdf.save(save_path)
temp_file.close

【讨论】:

以上是关于如何使用 Ruby 在现有 PDF 上编辑或书写?的主要内容,如果未能解决你的问题,请参考以下文章

在浏览器中编辑*现有* PDF

如何允许表单(pdf)在保存后可重新编辑(目标 C)

急急急!!!如何用java把可编辑的pdf文档转换成不可编辑的pdf文档

是否有可以将 JavaScript 插入现有 PDF 文件的 Ruby gem?

如何使用相同的表单在 ruby​​ on rails 中创建和编辑

使用 itextsharp 在现有 pdf 中插入文本