从Zip中的Prawn文件下载PDF

时间:2014-09-24 13:50:08

标签: ruby-on-rails pdf prawn

在我的WebApp中,我使用Prawn生成帐单。

我想以压缩文件的形式下载所有账单!

我做到了:

def download
  bills = Bill.search(params[:q]).result(distinct: true).paginate(:page => params[:page], limit: 20, order: "paid_at DESC")

  bills.each do |b|
    Prawn::Document.generate("#{Rails.root}/public/pdfs/web_#{b.reference}.pdf")
  end


  require 'rubygems'
  require 'zip'
  zipfile_name = "#{Rails.root}/public/pdfs/factures.zip"
  Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
    bills.each do |bill|
      zipfile.add("web_#{bill.reference}.pdf", "#{Rails.root}/public/pdfs/web_#{bill.reference}.pdf")
    end
  end

  path = File.join(Rails.root, "public", "pdfs")
  send_file File.join(path, "factures.zip")
end

但PDF是空的,因为我没有指定" * .prawn"允许生成PDF的文件!

任何人,请允许我这样做?

由于

修改

我的show.pdf.prawn

prawn_document() do |pdf|


pdf.image "#{Rails.root}/app/assets/images/logo.jpg"
  pdf.move_down 30

  pdf.move_down 10
  pdf.text "<b>Email :</b> <a href='mailto:contact@mtaville.fr'>contact@mtaville.fr</a>", inline_format: true
  pdf.text "<b>Site :</b> <a href='http://www.mtaville.fr'>www.mtaville.fr</a>", inline_format: true

  pdf.move_up 230
  pdf.table [["Facture N° #{@bill.reference}"],["Date : #{ldate(@bill.paid_at, format: :short2)}"]], position: :right do
    cells.style do |c|
      c.background_color = "2857BE"
      c.text_color = "FFFFFF"
      c.border_color = "2857BE"
      c.align = :center
    end
  end

  pdf.move_down 30
  pdf.table [["CLIENT"]], position: :right do
    cells.style do |c|
      c.background_color = "2857BE"
      c.text_color = "FFFFFF"
      c.border_color = "2857BE"
      c.width = 280
    end
  end

  pdf.bounding_box([260, 600], :width => 280, :height => 80) do
    pdf.text "#{@bill.billable.name}", style: :bold
    pdf.text "#{@bill.billable.address_1} #{@bill.billable.address_2}"
    pdf.text "#{@bill.billable.zipcode} - <b>#{@bill.billable.town}</b>", inline_format: true
  end

  pdf.move_down 100
  pdf.text "<b>Objet :</b> Facture n° #{@bill.reference}", inline_format: true

  if @bill.billable_type == 'Subscription'
    pdf.move_down 10
    data = [
      ["Produit", "Prix unitaire HT", "Prix total HT"],
      ["Renouvellement de souscription à votre espace privé", "#{number_to_currency(@bill.total)}", "#{number_to_currency @bill.total}" ]
    ]
    pdf.table data, width: 540 do
      cells.style do |c|
        c.background_color = (c.row == 0)? "2857BE" : "ffffff"
        c.text_color = (c.row == 0)? "ffffff" : "000000"
        c.font_style = (c.row == 0)? :bold : :normal
      end
    end
  end
  if @bill.billable_type == 'Order'
    pdf.move_down 10
    data = [
      ["Produit", "Prix unitaire HT", "Prix total HT"],
      ["Annonce n°#{@bill.billable.ad.id}", "#{number_to_currency(@bill.total)}", "#{number_to_currency @bill.total}" ]
    ]
    pdf.table data, width: 540 do
      cells.style do |c|
        c.background_color = (c.row == 0)? "2857BE" : "ffffff"
        c.text_color = (c.row == 0)? "ffffff" : "000000"
        c.font_style = (c.row == 0)? :bold : :normal
      end
    end
  end

  pdf.move_down 20
  data = [
    ["Total HT", "#{number_to_currency(@bill.total)}" ],
    ["Total TVA #{@bill.tva}%", "#{number_to_currency(@bill.amount_vat)}"],
    ["Total TTC", "#{number_to_currency(@bill.amount_inclusive_of_tax)}"]
  ]
  pdf.table data, position: :right do
    cells.style do |c|
      c.font_style = (c.row % 2 == 0)? :bold : :normal
      c.width = 140
      c.align = (c.column == 1)? :right : :left
    end
  end

  pdf.move_down 20
  data = [["NET A PAYER", "#{number_to_currency(0)}"]]
  pdf.table data, position: :right do
    cells.style do |c|
      c.font_style = :bold
      c.background_color = "2857BE"
      c.text_color = "ffffff"
      c.width = 140
      c.align = (c.column == 1)? :right : :left
    end
  end

end

**答案**

这是我控制器中的功能:

def download
    bills = Bill.search(params[:q]).result(distinct: true).paginate(:page => params[:page], limit: 20, order: "paid_at DESC")

    require 'rubygems'
    require 'zip'
    require 'bill'
    zipfile_name = "#{Rails.root}/tmp/pdfs/factures.zip"
    Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
      bills.each do |bill|
        temp_pdf = Tempfile.new("web_#{bill.reference}.pdf")
        temp_pdf.binmode
        temp_prawn_pdf = BillPdf.new(bill)
        temp_pdf.write temp_prawn_pdf.render
        temp_pdf.rewind
        zipfile.add("web_#{bill.reference}.pdf", "#{temp_pdf.path}")
        temp_pdf.close
      end
    end

    path = File.join(Rails.root, "tmp", "pdfs")
    send_file File.join(path, "factures.zip")
  end

我的班级:

class BillPdf < Prawn::Document
  include ActionView::Helpers::TranslationHelper
  include ActionView::Helpers::NumberHelper
  def initialize(bill)
    super()
    image "#{Rails.root}/app/assets/images/logo.jpg"

    move_down 10
    text "<b>N° TVA :</b> TVA", inline_format: true
    text "<b>Siret :</b> 789 618 691 00016", inline_format: true
    text "<b>Site :</b> <a href='http://www.mtaville.fr'>www.mtaville.fr</a>", inline_format: true

    move_up 230
    table [["Facture N° #{bill.reference}"],["Date : #{l(bill.paid_at, format: :short2)}"]], position: :right do
      cells.style do |c|
        c.background_color = "2857BE"
        c.text_color = "FFFFFF"
        c.border_color = "2857BE"
        c.align = :center
      end
    end

    move_down 30
    table [["CLIENT"]], position: :right do
      cells.style do |c|
        c.background_color = "2857BE"
        c.text_color = "FFFFFF"
        c.border_color = "2857BE"
        c.width = 280
      end
    end

    bounding_box([260, 600], :width => 280, :height => 80) do
      text "#{bill.billable.name}", style: :bold
      text "#{bill.billable.address_1} #{bill.billable.address_2}"
      text "#{bill.billable.zipcode} - <b>#{bill.billable.town}</b>", inline_format: true
    end

    move_down 100
    text "<b>Objet :</b> Facture n° #{bill.reference}", inline_format: true

    if bill.billable_type == 'Subscription'
      move_down 10
      data = [
        ["Produit", "Prix unitaire HT", "Prix total HT"],
        ["Renouvellement de souscription à votre espace privé", "#{number_to_currency(bill.total)}", "#{number_to_currency bill.total}" ]
      ]
      table data, width: 540 do
        cells.style do |c|
          c.background_color = (c.row == 0)? "2857BE" : "ffffff"
          c.text_color = (c.row == 0)? "ffffff" : "000000"
          c.font_style = (c.row == 0)? :bold : :normal
        end
      end
    end
    if bill.billable_type == 'Order'
      move_down 10
      data = [
        ["Produit", "Prix unitaire HT", "Prix total HT"],
        ["Annonce n°#{bill.billable.ad.id}", "#{number_to_currency(bill.total)}", "#{number_to_currency bill.total}" ]
      ]
      table data, width: 540 do
        cells.style do |c|
          c.background_color = (c.row == 0)? "2857BE" : "ffffff"
          c.text_color = (c.row == 0)? "ffffff" : "000000"
          c.font_style = (c.row == 0)? :bold : :normal
        end
      end
    end

    move_down 20
    data = [
      ["Total HT", "#{number_to_currency(bill.total)}" ],
      ["Total TVA #{bill.tva}%", "#{number_to_currency(bill.amount_vat)}"],
      ["Total TTC", "#{number_to_currency(bill.amount_inclusive_of_tax)}"]
    ]
    table data, position: :right do
      cells.style do |c|
        c.font_style = (c.row % 2 == 0)? :bold : :normal
        c.width = 140
        c.align = (c.column == 1)? :right : :left
      end
    end

    move_down 20
    data = [["NET A PAYER", "#{number_to_currency(0)}"]]
    table data, position: :right do
      cells.style do |c|
        c.font_style = :bold
        c.background_color = "2857BE"
        c.text_color = "ffffff"
        c.width = 140
        c.align = (c.column == 1)? :right : :left
      end
    end
  end

end

1 个答案:

答案 0 :(得分:3)

要进一步扩展我的评论,请参阅下面的代码重构。您可以使用Tempfile,而不是将文件添加到您的公共目录,这可能是出于安全考虑的危险。您可能需要稍微调整一下,但应该给出Tempfile s。

背后的基本概念
def download
  bills = Bill.search(params[:q]).result(distinct: true).paginate(:page => params[:page], limit: 20, order: "paid_at DESC")

  require 'rubygems'
  require 'zip'
  zipfile_name = Tempfile.new(["#{Rails.root}/tmp/factures", '.zip'])
  Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
    bills.each do |bill|
      temp_pdf = Tempfile.new(["basic_questions_#{Time.now.to_i}", '.pdf'])
      temp_pdf.binmode
      temp_prawn_pdf = Prawn::Document.new(#WHATEVER YOUR PARAMETERS ARE)
      temp_pdf.write temp_prawn_pdf.render
      temp_pdf.rewind
      zipfile.add("web_#{bill.reference}.pdf", "#{temp_pdf.path}")
      temp_pdf.close
    end
  end

  path = File.join(Rails.root, "public", "pdfs")
  send_file File.join(path, "factures.zip")
ensure
  zipfile_name.close
end