2014-09-24 285 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