使用wicked_pdf从生成的PDF生成ZIP [英] generate ZIP from generated PDFs with wicked_pdf

查看:421
本文介绍了使用wicked_pdf从生成的PDF生成ZIP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的发票系统中,我希望有一个备份功能可以在一个zip文件中一次下载所有发票。
此系统在heroku上运行 - 因此只能暂时保存pdf。



我安装了rubyzip和wicked_pdf gem。



我在控制器中的当前代码:

  def zip_all_bills 
@bill = Bill.all
if @ bill.count> 0
t = Tempfile.new(bill_tmp _#{Time.now})
Zip :: ZipOutputStream.open(t.path)do | z |
@ bill.each do | bill |
@bills = bill
@customer = @ bills.customer
@customer_name = @ customer.name_company_id
t = WickedPdf.new.pdf_from_string(
render:template => ;
:margin => {:bottom => 23},
:footer = > {:html => {:template =>'pdf / footer.pdf.erb'}}


z.puts(invoice _#{bill.id} )
z.print IO.read(t.path)
end
end

send_file t.path,:type => application / zip,
:disposition => 附件,
:filename => bills_backup

t.close
结束

respond_to do | format |
format.html {redirect_to bills_url}
结束
结束

这结束于
BillsController中的IOError#zip_all_bills已关闭的流

解决方案

你的代码有什么问题是你没有zip,但你也可以用它来做个别pdf。所以我想当你尝试使用pdf文件的时候,这是一个问题,因为你已经在使用它作为zip。



但是我认为你根本不需要使用临时文件(而且我从来没有在Heroku上使用过临时文件解决方案)

这是一个适用于我的控制器方法 - 在heroku上也使用wickedpdf和rubyzip。请注意,我没有使用Tempfile,而是使用StringIO做了所有事情(至少我认为这是潜在的技术)。

  def dec_zip 
需要'zip'
#获取一些测试记录
@coverages = Coverage.all.limit(10)
stringio = Zip :: OutputStream.write_buffer do | zio |
@ coverages.each do | coverage |
#为此记录创建并添加文本文件
zio.put_next_entry(#{coverage.id} _test.txt)
zio.writeHello#{coverage.agency_name}!
#为此记录创建并添加pdf文件
dec_pdf = render_to_string:pdf => #{coverage.id} _dec.pdf,:template => 'coverages / dec_page',:locals => {coverage:coverage},:layout => 'print'
zio.put_next_entry(#{coverage.id} _dec.pdf)
zio<< dec_pdf
end
end
#这是必需的,因为我们在流的末尾,
#将发送零字节,否则
stringio.rewind
#just在这里使用变量赋值
binary_data = stringio.sysread
send_data(binary_data,:type =>'application / zip',:filename =>test_dec_page.zip)
结束


In my invoice system, I want a backup function to download all invoices at once in one zip file. This system is running on heroku - so it's only possible to save the pdfs temporary.

I've the rubyzip and wicked_pdf gem installed.

My current code in the controller:

  def zip_all_bills
    @bill = Bill.all
    if @bill.count > 0
      t = Tempfile.new("bill_tmp_#{Time.now}")
      Zip::ZipOutputStream.open(t.path) do |z|
        @bill.each do |bill|
          @bills = bill
          @customer = @bills.customer
          @customer_name = @customer.name_company_id
          t = WickedPdf.new.pdf_from_string(
              render :template => '/bills/printing.html.erb',
                     :disposition => "attachment",
                     :margin => { :bottom => 23 },
                     :footer => { :html => { :template => 'pdf/footer.pdf.erb' } }
          )

          z.puts("invoice_#{bill.id}")
          z.print IO.read(t.path)
        end
      end

      send_file t.path, :type => "application/zip",
                        :disposition => "attachment",
                        :filename => "bills_backup"

      t.close
    end

    respond_to do |format|
      format.html { redirect_to bills_url }
    end
  end

This ends with the message IOError in BillsController#zip_all_bills closed stream

解决方案

I think what is wrong in your code is that you have t for your zip but you also also use it for individual pdfs. So I think when you try to use the tempfile for a pdf it is a problem because you are already using it for the zip.

But I don't think you need to use tempfiles at all (and I never actually got a tempfile solution working on Heroku)

Here is a controller method that works for me--also using wickedpdf and rubyzip on heroku. Note that I'm not using a Tempfile instead I'm just doing everything with StringIO (at least I think that's the underlying tech).

def dec_zip
  require 'zip'
  #grab some test records
  @coverages = Coverage.all.limit(10)
  stringio = Zip::OutputStream.write_buffer do |zio|
      @coverages.each do |coverage|
        #create and add a text file for this record
        zio.put_next_entry("#{coverage.id}_test.txt")
        zio.write "Hello #{coverage.agency_name}!"
        #create and add a pdf file for this record
        dec_pdf = render_to_string :pdf => "#{coverage.id}_dec.pdf", :template => 'coverages/dec_page', :locals => {coverage: coverage}, :layout => 'print'
        zio.put_next_entry("#{coverage.id}_dec.pdf")
        zio << dec_pdf
      end
    end
    # This is needed because we are at the end of the stream and 
    # will send zero bytes otherwise
    stringio.rewind
    #just using variable assignment for clarity here
    binary_data = stringio.sysread
    send_data(binary_data, :type => 'application/zip', :filename => "test_dec_page.zip")
end

这篇关于使用wicked_pdf从生成的PDF生成ZIP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆