从WickedPDF获取PDF以通过Carrierwave进行附件
在Rails3中,我使用WickedPDF gem
来渲染我的一个模型的PDF格式。 这工作正常: /invoices/123
返回HTML, /invoices/123
/invoices/123.pdf
下载PDF。
在我的发票模型中,我使用state_machine gem来跟踪发票状态。 当发票从“未开单”状态变为“开票”状态时,我想获取发票PDF的副本并使用CarrierWave将其附加到发票模型。
我将这三个部分分开工作:控制器创建PDF视图,模型跟踪状态并在进行正确转换时触发回调,并正确设置CarrierWave。 但是,我有一段时间让他们一起玩得很好。
如果我只是想获取发票的HTML版本,我可以从模型中调用render_to_string
。 但是render_to_string
似乎在接收PDF二进制文件时窒息。 如果我可以获得数据流,那么将这些数据写入临时文件并将其附加到上传器非常容易,但我无法弄清楚如何获取数据流。
有什么想法吗? 代码如下:
发票控制器
def show @invoice = @agg_class.find(params[:id]) respond_to do |format| format.pdf do render_pdf end format.html # show.html.erb format.json { render json: @aggregation } end end
…
def render_pdf(options = {}) options[:pdf] = pdf_filename options[:layout] = 'pdf.html' options[:page_size] = 'Letter' options[:wkhtmltopdf] = '/usr/local/bin/wkhtmltopdf' options[:margin] = { :top => '0.5in', :bottom => '1in', :left => '0in', :right => '0in' } options[:footer] = { :html => { :template => 'aggregations/footer.pdf.haml', :layout => false, } } options[:header] = { :html => { :template => 'aggregations/header.pdf.haml', :layout => false, } } render options end
Invoice.rb
def create_pdf_copy # This does not work. pdf_file = ApplicationController.new.render_to_string( :action => 'aggregations/show', :format => :pdf, :locals => { :invoice => self } ) # This part works fine if the above works. unless pdf_file.blank? self.uploads.clear self.uploads.create(:fileinfo => File.new(pdf_file), :job_id => self.job.id) end end
更新找到解决方案。
def create_pdf_copy wicked = WickedPdf.new # Make a PDF in memory pdf_file = wicked.pdf_from_string( ActionController::Base.new().render_to_string( :template => 'aggregations/show.pdf.haml', :layout => 'layouts/pdf.html.haml', :locals => { :aggregation => self } ), :pdf => "#{self.type}-#{self}", :layout => 'pdf.html', :page_size => 'Letter', :wkhtmltopdf => '/usr/local/bin/wkhtmltopdf', :margin => { :top => '0.5in', :bottom => '1in', :left => '0in', :right => '0in' }, :footer => { :content => ActionController::Base.new().render_to_string({ :template => 'aggregations/footer.pdf.haml', :layout => false }) }, :header => { :content => ActionController::Base.new().render_to_string({ :template => 'aggregations/header.pdf.haml', :layout => false }) } ) # Write it to tempfile tempfile = Tempfile.new(['invoice', '.pdf'], Rails.root.join('tmp')) tempfile.binmode tempfile.write pdf_file tempfile.close # Attach that tempfile to the invoice unless pdf_file.blank? self.uploads.clear self.uploads.create(:fileinfo => File.open(tempfile.path), :job_id => self.job.id) tempfile.unlink end end
解:
def create_pdf_copy wicked = WickedPdf.new # Make a PDF in memory pdf_file = wicked.pdf_from_string( ActionController::Base.new().render_to_string( :template => 'aggregations/show.pdf.haml', :layout => 'layouts/pdf.html.haml', :locals => { :aggregation => self } ), :pdf => "#{self.type}-#{self}", :layout => 'pdf.html', :page_size => 'Letter', :wkhtmltopdf => '/usr/local/bin/wkhtmltopdf', :margin => { :top => '0.5in', :bottom => '1in', :left => '0in', :right => '0in' }, :footer => { :content => ActionController::Base.new().render_to_string({ :template => 'aggregations/footer.pdf.haml', :layout => false }) }, :header => { :content => ActionController::Base.new().render_to_string({ :template => 'aggregations/header.pdf.haml', :layout => false }) } ) # Write it to tempfile tempfile = Tempfile.new(['invoice', '.pdf'], Rails.root.join('tmp')) tempfile.binmode tempfile.write pdf_file tempfile.close # Attach that tempfile to the invoice unless pdf_file.blank? self.uploads.clear self.uploads.create(:fileinfo => File.open(tempfile.path), :job_id => self.job.id) tempfile.unlink end end
有一种更好的方法: 没有控制器的Rails中的PDF 。
- Rails + CarrierWave:NoMethodError:nil的未定义方法`name’:NilClass
- 从S3下载Carrierwave上传
- 载波图像未加载到源代码中
- Rails – Errno :: EACCES(权限被拒绝)上传用户的头像时
- 缺少必需的参数:aws_access_key_id,aws_secret_access_key
- Carrierwave + repage选项不起作用
- Rails 4,Carrierwave-aws,图像在本地上传到amazon s3但未投放到生产中(Openshift)
- Carrierwave获取图像宽度和高度并将其存储在hstore字段中
- Carrierwave文件名在update_attributes上不断变化