2012-03-12 12 views
9

Obecnie pracujemy nad aplikacją Railsową hostowaną na Heroku. Próbujemy wygenerować plik PDF i przekazać go użytkownikowi do pobrania.Używanie Prawn na Heroku

Używamy Prawn do obsługi generowania plików PDF.

Nasz kod do generowania PDF jest obecnie:

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

Obserwowani przez cały nasz kod, aby wygenerować dokument. Niestety, zapisuje dokument na dysku, co nie jest możliwe (według mojej najlepszej wiedzy) dla aplikacji hostowanych na Heroku.

Następnie wsuń go do użytkownika za pomocą

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

jest jakiś sposób za pomocą Prawn bezpośrednio wcisnąć pobrania dokumentu dla użytkownika bez zapisywania dokumentu na dysku, w pierwszej kolejności? Jeśli nie, czy istnieją inne klejnoty do generowania plików PDF, które nie wymagają zapisania pliku na dysku przed wysłaniem pliku?

Odpowiedz

7

Na Aspen/Bamboo można zapisać plik na dysku w katalogu tmp/ w katalogu aplikacji (prawdopodobnie Rails.root.join("tmp")) lub dowolnym podkatalogu.

W programie Cedar można zapisać plik na dysku w dowolnym miejscu w katalogu aplikacji, ale mimo to nadal należy wybrać podkatalog z katalogiem aplikacji tmp/.

W obu przypadkach zapisane pliki są efemeryczne. Nie są one dzielone między dwie uruchomione instancje Twojej aplikacji; nie są przechowywane między ponownymi uruchomieniami; itp. Nie polegaj na zapisywaniu pliku w jednym żądaniu, a następnie masz do niego dostęp w drugim żądaniu.

+0

Zobacz drugi komentarz na temat używania krewetki bez nazwy pliku do renderowania w pamięci. – kwerle

5

Chociaż odpowiedź na to pytanie była już dawno temu, opublikuję wiadomość dla innych osób, które mogą chcieć to zrobić.

Możesz również zadzwonić pod numer render bez nazwy pliku w bieżącym Prawn v0.13.2. Zwrócony zostanie łańcuch, który można wysłać do klienta pod numerem send_data. Wzór:

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

Spowoduje to wyświetlenie pliku PDF w przeglądarce. Jeśli zamiast tego chcesz, aby użytkownik go pobrał, pomiń to, co chcesz, aby go pobrać, pomiń oczywiście, jeśli dokument jest względnie krótki lub system nie jest intensywnie wykorzystywany, ponieważ będzie zużywał pamięć RAM, dopóki pobieranie nie zostanie zakończone.

+0

Chyba jednym wyzwaniem może być 30-sekundowy limit na żądanie nałożony przez Heroku. Jeśli przetwarzanie pliku trwa dłużej niż 30 sekund - jest szansa, że ​​aplikacja zakończy się niepowodzeniem z 500. – tamersalama

+0

@tamersalama Chociaż to prawda, oryginalne rozwiązanie PO nie powiodło się z tego powodu przed tym, ponieważ pisanie i czytanie pliku jest wolniejsze niż buforowanie w pamięci. Właśnie pokazałem, że można uniknąć pliku i/o. – Gene

+0

zgadzam się - właśnie komentowałem twoją odpowiedź coz ja lubię :) – tamersalama