2013-02-07 9 views
14

रेलवे 3 में संलग्नक के लिए WickedPDF से पीडीएफ प्राप्त करना, मैं अपने मॉडल में से किसी एक के पीडीएफ प्रारूप को प्रस्तुत करने के लिए WickedPDF gem का उपयोग कर रहा हूं। यह ठीक काम कर रहा है: /invoices/123 एचटीएमएल, /invoices/123.pdf एक पीडीएफ डाउनलोड करता है।कैरियरवेव

मेरे चालान मॉडल में, मैं चालान स्थिति का ट्रैक रखने के लिए state_machine मणि का उपयोग कर रहा हूं। जब कोई चालान "असंबद्ध" से "बिल" राज्य में जाता है, तो मैं चालान पीडीएफ की प्रतिलिपि लेना चाहता हूं और इसे कैरियरवेव का उपयोग करके चालान मॉडल से जोड़ना चाहता हूं।

मेरे पास तीन हिस्सों अलग से काम कर रहे हैं: नियंत्रक एक पीडीएफ व्यू बनाता है, मॉडल ट्रैक करता है और सही संक्रमण करते समय कॉलबैक ट्रिगर करता है, और कैरियरवेव ठीक तरह से स्थापित होता है। हालांकि, मुझे एक साथ अच्छी तरह से खेलने के लिए एक समय का एक बिल्ली है।

यदि मैं सिर्फ चालान के HTML संस्करण को पकड़ना चाहता था, तो मैं मॉडल से render_to_string पर कॉल कर सकता था। लेकिन render_to_string पीडीएफ बाइनरी फ़ाइल प्राप्त करने पर चकित लगता है। अगर मैं डेटा की स्ट्रीम वापस प्राप्त कर सकता हूं, तो उस डेटा को एक tempfile पर लिखना और अपलोडर को संलग्न करना बहुत आसान है, लेकिन मैं यह नहीं समझ सकता कि डेटा स्ट्रीम कैसे प्राप्त करें।

किसी भी विचार? नीचे दिए गए कोड:

चालान नियंत्रक

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

ठीक है, मुझे यह काम मिल गया है। चरण 1 इस तथ्य के आसपास काम कर रहा था कि WickedPDF नियंत्रक के संदर्भ में नहीं चलते समय वैश्विक कॉन्फ़िगरेशन सेटिंग्स को अनदेखा करता है। चरण 2: पीडीएफ आउटपुट को बाइनरी मोड टेम्पफाइल के रूप में सहेजने के लिए टेम्पफाइल का उपयोग करें, फिर उसे कैरियरवेव से संलग्न करें। समाधान को प्रतिबिंबित करने के लिए मूल पोस्ट संपादित किया गया। – lascarides

+0

क्या आप मुझे चरण 1 पर अधिक जानकारी दे सकते हैं? मेरे पास स्थानीय रूप से wkhtmltopdf का पुराना संस्करण था और render_to_string के साथ निर्यात ठीक था। सर्वर पर मेरे पास wkhtmltopdf 0.11.0 है, और render_to_string काम करता है लेकिन पीडीएफ अपठनीय है .. स्थानीय रूप से 0.11.0 में अपग्रेड किया गया है और render_to_string chokes .. आपके जैसा ही समस्या हो रही है .. FYI: मैं 'file = StringIO का उपयोग करता हूं (render_to_string (विकल्प)) 'तो मैं Tempfile छोड़ सकते हैं। यह पेपरक्लिप के साथ है, लेकिन यदि आप विचार पसंद करते हैं तो आप इसे आज़मा सकते हैं। –

+2

खुशी है कि आपने इसे हल किया है। आपको अपना समाधान एक उत्तर के रूप में लिखना चाहिए, और फिर अपना जवाब स्वीकार करना चाहिए। अपने प्रश्न का उत्तर देने में कोई हानि नहीं! – sockmonk

उत्तर

6

समाधान:

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 
संबंधित मुद्दे