从 Rails 生成 PDF

Posted

技术标签:

【中文标题】从 Rails 生成 PDF【英文标题】:Generate PDF from Rails 【发布时间】:2010-09-30 19:03:21 【问题描述】:

Ruby On Rails Wiki lists a couple of libraries 有助于在 Rails 中生成 PDF。我需要打印出地址标签(以字母格式,因此每页 12-15 个地址)并且无法决定使用哪一个。有什么建议吗?

【问题讨论】:

我今天正在格式化圣战 :) 也许您希望生成 PDF,而不是“PFD” 【参考方案1】:

到目前为止我见过的最好的是虾:

大虾http://prawn.majesticseacreature.com/ http://advent2008.hackruby.com/past/2008/12/17/awn_and_the_future_of_ruby_pdf_generation/ http://railstips.org/2008/10/14/how-to-generate-pdfs-in-rails-with-prawn Prawn Rails 插件:http://www.cracklabs.com/prawnto

【讨论】:

谢谢!大虾似乎是要走的路……尤其是有了prawnto插件,它真的很容易使用【参考方案2】:

Prawn with Prawnto 当然可以。 DSL 是一种真正的享受,就像在 respond_to 格式块中将 PDF 视为任何其他格式一样简单:

respond_to do |format|
format.pdf  render :layout => false 

大虾here有教程视频:

【讨论】:

看起来这个答案中的链接坏了..还有其他地方可以找到信息吗,@btw? 该链接对我有用,但有一个“更新”(与答案中发布的链接相比,虽然它现在已有 10 年历史)RailsCast railscasts.com/episodes/153-pdfs-with-prawn-revised 更好的是,repo:github.com/cortiz/prawn-rails【参考方案3】:

还有RTeX。如果您愿意先翻译成LaTeX,那效果很好。 LaTeX 是一种非常好的存储标记文档的方法。这仅取决于每个文档的静态程度。如果大部分文档是动态的,那么使用 Prawn 或 PDF::Writer 可能会更好。如果大部分是静态的,每个只有几个文本替换,LaTeX 可能是更好的选择。

【讨论】:

【参考方案4】:

如果你没有做太复杂的事情,你也可以使用 htmlDOC,它将基本的 HTML 转换为 PDF。这使您不必学习更多专有的布局语法(例如在 Prawn 的情况下)。它可能会为您省去一些麻烦:)

这是 HTMLDOC 的 ruby​​ gem 的链接:

http://htmldoc.rubyforge.org/

另外,这里有一个很好的指南,可以使用 HTMLDOC 将 rails 中的视图渲染为 pdf:

http://blog.adsdevshop.com/2007/11/20/easy-pdf-generation-with-ruby-rails-and-htmldoc/

【讨论】:

【参考方案5】:

虾是要走的路。现在有了虾标签,这真的很容易做到。

在此处查看项目的 README:

https://github.com/jordanbyron/prawn-labels#readme

这是一个在 Rails 控制器中使用的超级简单的示例。不要忘记将gem 'prawn-labels' 添加到您的 Gemfile。

names = %wJordan Kelly Greg Bob

labels = Prawn::Labels.render(names, :type => "Avery5160") do |pdf, name|
  pdf.text name
end

send_data labels, :filename => "names.pdf", :type => "application/pdf"

【讨论】:

【参考方案6】:

还有PDFKit。也挺有意思的。

【讨论】:

【参考方案7】:

我使用过 PDF::Writer 和 Prawn,发现 Prawn 使用起来更愉快。查看Ruby Mendicant 获取comparison,它展示了Prawn w/r/t PDF::Writer 的乐趣。

实际上,无论如何,只要查看 Ruby Mendicant 即可获得出色的 design pattern 以获得作为开发人员的正确生计。

【讨论】:

【参考方案8】:

虽然不完全是 ruby​​,但您可以使用 OpenOffice .odt 通过结合 serenity 和 docsplit 来生成 PDF。

http://github.com/kremso/serenity

http://documentcloud.github.com/docsplit/

或者你可以使用clamsy gem,它使用odt和cups-pdf来生成PDF。

http://github.com/ngty/clamsy

【讨论】:

【参考方案9】:

对于您的用例,我同意大多数其他答案,即 prawn 是正确的选择,因为您需要对输出进行像素级控制。

要生成带有内置(自定)表格样式、标题等的 PDF 报告,您可以使用 report gem - 查看 Generate pdf from Rails 3 - what tool to choose? 以了解如何使用的示例。

【讨论】:

【参考方案10】:

我使用飞碟从 html 生成 pdf。它是一个 java 库,但您可以使用 Ruby-Java Bridge gem 在您的 rails 应用程序中访问它。它与 css 2.1 兼容,并从 css3 中添加了一些内容,以允许对分页进行一些额外的控制。我推荐它,因为它不需要您在 html 中放入“pdf 代码”,您可以使用与生成 pdf 相同的视图和部分显示到浏览器。

飞碟:https://github.com/flyingsaucerproject/flyingsaucer

Ruby Java 桥:http://rjb.rubyforge.org/

我使用这个模块代码来生成 pdfs

require 'rubygems'
require 'rjb'

module Html2Pdf

  def self.included(controller)
      controller.send :helper_method, :create_pdf
  end

  def create_pdf(options = )
      itext = "#RAILS_ROOT/lib/html2pdf/jars/iText-2.0.8.jar"
      core_renderer = "#RAILS_ROOT/lib/html2pdf/jars/core-renderer.jar"
      xerces = "#RAILS_ROOT/lib/html2pdf/jars/xml-apis-xerces-2.9.1.jar" 
      joinchar = (RUBY_PLATFORM.include? 'mswin') ? ';' : ':'
          classpath = [itext, core_renderer, xerces].join(joinchar)
      Rjb::load(classpath, jvmargs=['-Djava.awt.headless=true'])
      if options[:htmlstring].nil?
      options[:layout] ||= false
          options[:template] ||= File.join(controller_path,action_name+".pdf.erb")
          html_string = render_to_string(:template => options[:template], :layout => options[:layout])
    else
          html_string = options[:htmlstring]
    end
    # Make all paths relative, on disk paths...
    html_string.gsub!(".com:/",".com/") # strip out bad attachment_fu URLs
    html_string.gsub!( /src=["']+([^:]+?)["']/i )  |m| "src=\"file:///#RAILS_ROOT/public/" + $1 + '"'  # re-route absolute paths
    html_string.gsub!( /url\(["']+([^:]+?)["']/i )  |m| "url\(\"file:///#RAILS_ROOT/public/" + $1 + '"'  # re-route absolute paths
    # Remove asset ids on images with a regex // tbh i can't remember what this line is for but i'm sure it did something awesome
    html_string.gsub!( /src=["'](\S+\?\d*)["']/i )  |m| 'src="' + $1.split('?').first + '"'  
    filename = "#RAILS_ROOT/public/pdfs/"+options[:filename]+".pdf"
    fileOutputStream = Rjb::import('java.io.FileOutputStream')
      iTextRenderer = Rjb::import('org.xhtmlrenderer.pdf.ITextRenderer')
      renderer = iTextRenderer.new
      renderer.setDocumentFromString(html_string)
      os = fileOutputStream.new(filename)
      renderer.layout()
      renderer.createPDF(os)
      os.close()
  end

end

用这样的代码调用它:

def generate_pdf  
  htmlsrc = render_to_string(:partial => 'invoice', :layout => false)
  rnd = Time.now.to_s(:datentime).gsub!(/[\/ \.:]/,'')
  filename = "docstore/tmp_#rnd"
  create_pdf(:htmlstring => htmlsrc, :filename => filename)
  contents = open("#RAILS_ROOT/public/pdfs/#filename.pdf", "rb")  |io| io.read 
  File.delete("#RAILS_ROOT/public/pdfs/#filename.pdf")
  respond_to do | wants |
    wants.html  render :text => contents, :content_type => 'application/pdf' 
  end    
end

【讨论】:

以上是关于从 Rails 生成 PDF的主要内容,如果未能解决你的问题,请参考以下文章

Rails wikedPDF错误。无法生成PDF

ruby rails3 prawn生成pdf

如何在 Rails 中为 Prawnto 生成的 PDF 进行内联格式(粗体和下划线)?

ruby on rails 中使用pdfkit生成pdf

Rails 3 - 从视图中渲染 PDF 并附加到电子邮件

Rails - 在 PDF 中嵌入 XML