2015-04-04 86 views
1

我有一個Rails應用程序3使用這些寶石:Rails 3的妖獸PDF - 包括回形針S3 PDF文件

gem 'paperclip' 
gem 'wicked_pdf' 
gem 'combine_pdf' 

我使用wicked_pdf打開了costproject的PDF文件。 costproject有一個名爲viewproject.pdf.erb的HTML頁面。

我試圖將邪惡的pdf與costproject附件合併成一個pdf。

這是我的控制器代碼:

def viewproject 
    @costproject = Costproject.find(params[:costproject_id]) 
    respond_to do |format| 
     format.html 
     format.pdf do 
     pdf = CombinePDF.new 
     pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8" 
     pdf << CombinePDF.new(pdf2) 
     @costproject.attachments.each do |attachment| 
      pdf << CombinePDF.new(attachment.attach.path) 
     end 
     send_data pdf.to_pdf, :disposition => 'inline', :type => "application/pdf" 
     end 
    end 
    end 

pdf << CombinePDF.new(pdf2)是給我:

string contains null byte 

如果我看pdf2,它開始像這樣 - 所以它看起來像一個pdf:

>> pdf2 
=> "%PDF-1.4\n1 0 obj\n<<\n/Title (\xFE\xFF)\n/Producer (wkhtmltopdf)\n/CreationDate (D:20150405202628)\n>>\nendobj\n4 0 obj\n<<\n/Type /ExtGState\n/SA true\n/SM 0.02\n/ca 1.0\n/CA 1.0\n/AIS false\n/SMask /None>>\nendobj\n5 0 obj\n[/Pattern /DeviceRGB]\nendobj\n8 0 obj\n<<\n/Type /XObject\n/Subtype /Image\n/Width 71\n/Height 75\n/BitsPerComponent 8\n/ColorSpace /DeviceRGB\n/Length 9 0 R\n/Filter 

我也試過pdf << CombinePDF.new(pdf2.to_pdf)

感謝您的幫助!

UPDATE1

作爲一個測試,看看是否pdf2工作,我這樣做是成功的:

def viewproject 
    @costproject = Costproject.find(params[:costproject_id]) 
    respond_to do |format| 
     format.html 
     format.pdf do 
     pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8" 

     send_data pdf2, :disposition => 'inline', :type => "application/pdf" 
     end 
    end 
    end 

UPDATE2

神祕島是有關使用parse正確的。謝謝!

我現在用的這條線在控制器代碼:

pdf << CombinePDF.new(attachment.attach.url) 

我得到這個錯誤:

No such file or directory - http://s3.amazonaws.com/ ... 

但是,如果我複製HTTP地址,粘貼到瀏覽器的PDF顯示向上。

回答

5

我在編輯此答案以反映遠程存儲的PDF文件的問題。

我應該指出,如果沒有與S3存儲器的持久連接並且沒有使用S3 API,以下解決方案將影響性能*。

正如我所指出的,CombinePDF.new方法與CombinePDF.load方法相同。它接受文件名並嘗試打開文件。 CombinePDF.parse方法將接受原始PDF數據並將其解析爲PDF對象。

在下面的代碼中,我使用Net::HTTP.get(URI.parse(url))來獲取原始PDF數據。

我建議用S3本地解決方案替換此解決方案,以便整個應用程序可以共享一個或多個持久連接。這是一個性能問題,對您而言可能並非重要。

require 'net/http' 

    def viewproject 
    @costproject = Costproject.find(params[:costproject_id]) 
    respond_to do |format| 
     format.html 
     format.pdf do 
     pdf = CombinePDF.new 
     pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8" 
     pdf << CombinePDF.parse(pdf2) 
     @costproject.attachments.each do |attachment| 
      pdf << CombinePDF.parse(Net::HTTP.get(URI.parse(attachment.attach.url))) 
     end 
     send_data pdf.to_pdf, :disposition => 'inline', :type => "application/pdf" 
     end 
    end 
    end 

*對性能的影響取決於你有PDF附件的數量,對用戶您的應用的數量,網絡流量,你的架構(單/多線程)和其他因素。

持續連接應該會大幅度降低性能,主要是由於建立連接是一項昂貴的操作。

+0

你對使用'parse'是正確的。但是,現在我有一個問題,它在本地工作 - 因爲我將附件PDF保存在Rails中,但在Heroku上,我使用S3。我正在嘗試'pdf << CombinePDF.new(attachment.attach.path)' – Reddirt 2015-04-05 21:05:41

+0

'pdf << CombinePDF.new(attachment.attach.url)''不起作用的不同代碼 – Reddirt 2015-04-05 21:13:25

+0

您通常會如何訪問raw來自S3層的文件內容?它在本地安裝嗎?你使用特定的API嗎? – Myst 2015-04-05 22:46:11