2012-03-12 68 views
9

我們目前正在Heroku上託管一個Rails應用程序。我們正在嘗試生成PDF並將其推送給用戶進行下載。在Heroku上使用蝦

我們正在使用Prawn來處理PDF生成。

我們對生成的PDF的代碼是目前:

Prawn::Document.generate @name[0]+ ".pdf" do 

其次是所有的我們的代碼生成文檔。不幸的是,這將文檔保存到磁盤上,這對Heroku上託管的應用程序是不可能的(據我所知)。

然後我們把它推到使用

send_file "#{Rails.root}/"[email protected][0]+ ".pdf", :type => 
'application/pdf',:filename => @name[0]+ ".pdf" 

有沒有辦法用蝦直接推動文檔的用戶的下載而無需先將文件保存到磁盤的用戶?如果沒有,有沒有其他的寶石用於生成PDF文件,在發送文件之前不需要將文件保存到磁盤?

回答

7

在Aspen/Bamboo上,您可以將文件保存到應用程序目錄(可能爲Rails.root.join("tmp"))或任何子目錄的tmp/目錄中的磁盤中。

在Cedar上,您可以將文件保存到應用程序目錄中的任意位置,但仍然應該選擇應用程序的tmp/目錄的子目錄。

無論哪種情況,保存的文件都是短暫的。它們不在應用程序的兩個正在運行的實例之間共享;它們不會在重新啓動之間保持;等等。不要依賴將文件保存在一個請求中,然後能夠在第二個請求中訪問它。

+0

請參閱有關使用沒有文件名稱的對象在內存中呈現的其他註釋。 – kwerle 2014-05-02 15:45:13

5

儘管很久以前就已經回答了這個問題,但我會爲其他可能想要這樣做的人發佈帖子。

您也可以在當前Prawn v0.13.2中調用render沒有文件名。一個字符串將被返回,可以通過send_data發送給客戶端。模式是:

pdf = Prawn::Document.new 
# ... calls to build the pdf 
send_data pdf.render, 
      type: 'application/pdf', 
      filename: 'download_filename.pdf', 
      disposition: :inline 

這將在瀏覽器中顯示PDF。如果您希望讓用戶下載它,請省略, disposition: :inline

當然,如果文檔相當短或您的系統沒有被大量使用,您只需要這樣做,因爲在用戶下載完成之前它將消耗RAM。

+0

我想一個挑戰可能是Heroku強加的30秒請求限制。如果文件處理時間超過30秒 - 應用程序有可能會失敗500. – tamersalama 2015-12-11 21:08:49

+0

@tamersalama雖然這是真的,但OP的原始解決方案在此之前會因此失敗,因爲寫入然後讀取文件比寫入文件慢在內存中緩衝。我只是表明可以避免文件I/O。 – Gene 2015-12-11 21:39:13

+0

同意 - 只是評論你的答案因爲我喜歡它:) – tamersalama 2015-12-11 21:41:01