【问题标题】:Is there a way to generate multiple documents in my application using the Prawn gem?有没有办法使用 Prawn gem 在我的应用程序中生成多个文档?
【发布时间】:2021-09-17 07:22:11
【问题描述】:

我正在尝试使用 prawn gem 生成 pdf。目标是使用通过表单提交的数据创建自定义 pdf。这些示例可能是报告、发票、出生证明等。我已经初步成功地生成了 a pdf。这个名为“报告”。

  #Controller
  class TemplatesController < ApplicationController
  before_action :set_template, only: %i[ show edit update destroy ]

  def show
    @templates = Template.all

    respond_to do |format|
      format.html
      format.pdf do
        pdf = ReportPdf.new
        send_data pdf.render, filename: 'report.pdf', type: 'application/pdf', 
        disposition: "inline"
      end
    end
  end

 #....lots of code

# Only allow a list of trusted parameters through.
def template_params
  params.require(:template).permit(:name, :address, :idnumber)
end
end

这可以工作并生成一个带有如下模板的pdf:

#My Report.pdf. Similar templates exist for birth certificates deeds, invoices and 
other pdf documents

class ReportPdf < Prawn::Document
  def initialize
    super()
    header
    text_content
  end

  def header
  #Inserts an image in the pdf file and sets its size.
  image "#{Rails.root}/app/assets/images/logo.jpg", width: 230, height: 75
  end

  def text_content
    bounding_box([0, y_position], :width => 270, :height => 300) do
  
    text "This is a sample report by #{@template.name} who lives at # 
    {@template.address} etc etc"
    end
  end
end

最后,我想向用户展示一个表单:

<%=form_with url: templates_path(format: "pdf"), local: true,method: :get do |form| %>

<%= form.label :pdf_type %>
<%= form.select :pdf_type,
options_for_select([
['Report','Report'],
['Birth_certificate','Birth Certificate'],
['Deed','Deed'],
['Title','Title']]),
{}, {class: "form-control" } %> 

<%= form.button "Download", class: "btn btn-primary" %>
<% end %>

可以看出,报告 pdf 被“绑定”到控制器操作,因此当前允许生成一个 pdf(“报告”)。没有灵活性。要生成不同类型的报告,我必须手动更改控制器代码 如何允许用户从表单中选择 pdf 类型并生成他选择的 pdf?

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    仅从 RESTful POV 开始,您最好使用 create 操作来处理 PDF 生成。或许将 form_with 更改为指向 POST 操作,然后检查 pdf_type 参数以检查要生成的报告类型。

    从概念上讲,您对资源的“展示”概念进行了超载。 PDF 尚不存在,因此显示它没有多大意义。我知道你可以这样做,但你确实违反了 Rails 及其约定。

    因此,简而言之,将表单的呈现移动到控制器的 new 方法中,并在 create 方法中处理 PDF 的生成和发送,就像您目前对 send_data 所做的那样。

    编辑:我可能误解了您要实现的目标,但您的示例中有一些令人困惑的伪影 - 例如@templates 的作用是什么。

    如果只是根据用户输入选择要生成的正​​确 PDF,您只需要 case 语句或类似语句,例如

    pdf = case template_params[:name]
    when 'Report' then ReportPdf.new
    when 'Birth_certificate' then BirthCertificatePdf.new
      .. etc ..
    end
    
    respond_to do |format|
      format.html
      format.pdf do
        send_data pdf.render, filename: 'report.pdf', type: 'application/pdf', 
        disposition: "inline"
      end
    end
    

    您必须检查 template_params 中的实际内容,将参数值与构建您所追求的特定报告的 case 子句相匹配。

    这些有意义吗?我不觉得我在帮助。对不起。

    【讨论】:

    • 你的建议是合乎逻辑的。我的思绪跳过了案例陈述的可能性。这似乎是我需要的!谢谢你。所以在“响应”块中,我是否对文件名进行字符串插值以识别所需的模板?它仍然指向“report.pdf”,这在实践中如何运作? (为了回答你的问题,@template.name 等引入了用户属性。我的模型名为 Template。我稍后会更改它)
    • “名称”可能是 PDF 资源的属性吗?例如class ReportPdf &lt; Prawn::Document; def name; "report.pdf"; end 然后在您的 send_data 调用中引用 (filename: pdf.name) - 或类似的东西
    • 在您的示例中,顺便说一句,'report.pdf' 只是一个字符串文字 - 文件的名称,它将向用户显示。它似乎没有任何价值。
    • 'name' 目前是这样一个属性:Rails g scaffold 模板名称、地址、身份编号:整数我会试试你的推荐
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    相关资源
    最近更新 更多