2014-09-24 240 views
1

在我的WebApp中,我与Prawn生成了账单。从Zip文件中下载PDF文件

我想下载压缩文件中的所有账单!

我这样做:

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:[email protected]'>[email protected]</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 

** **回答

这里是我的控制器的fonction:

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 
+0

你可以使用'Tempfile'生成一个临时文件并将其添加到压缩文件中。确保在完成使用后关闭文件。 – kobaltz 2014-09-24 13:54:10

+0

好的,但是如何在tempfile中添加内容? – p0k3 2014-09-24 13:57:12

+0

查看我的答案,我已经扩展了这个想法。 – kobaltz 2014-09-24 14:01:24

回答

3

为了扩大对我的评论更多,请参阅下面的代码重构。您可以使用Tempfile s,而不是将文件添加到公共目录(这对于安全原因而言很危险)。你可能需要稍微调整一下,但是应该给你Tempfile的基本想法。

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 
+0

由于这可能需要很长时间,因此您可能希望将其移至'delayed_job'或类似的位置。只要文件准备就绪,您就可以启动下载或发送文件准备好下载的ajax。这完全取决于你的应用程序的构建范围,以便最适合什么。 – kobaltz 2014-09-24 14:03:23

+0

我把它当作安全。但是,我所有的PDF都是空白的! – p0k3 2014-09-24 14:18:31

+0

在'temp_prawn_pdf = Prawn :: Document.new(#WHATEVER YOUR PARAMETERS ARE)'行中,您需要将'Prawn :: Document .....'设置为任何PDF生成器。例如,查看您的其他代码,在该代码中文档成功生成并将代码放在那里;修改任何必要的参数。 – kobaltz 2014-09-24 14:20:10