How do I generate pdf file using Prawn in Rails? - ruby-on-rails

I have used the following syntax to generate a pdf file:
Prawn::Document.generate("#{RAILS_ROOT}/public/pdf/generate.pdf") do
pdf.text "hello"
end
But when I look for the file within the /public/pdf/ folder, I dont find any file.
Well my controller code for this is
def generate
respond_to do |format|
format.pdf{ render :file => "#{RAILS_ROOT}/public/pdf/generate.pdf"}
end
end

It could be something else, but the code supplied doesn't seem to work:
Prawn::Document.generate("x.pdf") do
pdf.text "Hello"
end
gives me
NameError: undefined local variable or method `pdf' for #<Prawn::Document:0x352b6e4>
from c:/ruby/lib/ruby/gems/1.8/gems/prawn-core-0.8.4/lib/prawn/graphics/color.rb:72:in `method_missing'
from (irb):3
You should be able to see if you're getting something similar in your log file.
I think the pdf. is not needed:
Prawn::Document.generate("x.pdf") do
text "Hello"
end

ruby - 1.9.3
rails - 3.2
way 1
create new project in rails
rails new prawn_sample
you can find gem file inside project folder, add prawn gem.
gem 'prawn'
then bundle install
now, install prawnto plugin
rails plugin install git#github.com:forrest/prawnto.git
For sample data to display, let’s create a Book model with title,author and description.
rails generate scaffold book title:string author:string description:text
then
rake db:migrate
now start the server and enter sample data's to test
so,
rails s
localhost:3000/books
here enter the required amount of data's
next
Let’s get started with something simple and add a pdf version of the show action. Open up the books controller and add format.pdf
def show
#book = Book.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #book }
format.pdf { render :layout => false }
end
end
create the show.pdf.prawn file inside app/views/books. For now, lets have hello world
pdf.text "Hello World!"
visit
http://localhost:3000/books/1
http://localhost:3000/books/1.pdf
you successfully generated PDF.
Let’s make the view specific to the books.
in show.pdf.prawn
pdf.font "Helvetica"
pdf.text "Book: #{#book.title}", :size => 16, :style => :bold, :spacing => 4
pdf.text "Author: #{#book.author}", :spacing => 16
pdf.text #book.description
now you see some text with format specified above . Browse more for format you required.
way 2
Gemfile
gem 'prawn'
/config/initializers/mime_types.rb
Mime::Type.register "application/pdf", :pdf
AuditsController
def show
#audit = Audit.find(params[:id])
respond_to do |format|
format.html
format.pdf do
pdf = Prawn::Document.new
pdf.text "This is an audit."
send_data pdf.render, type: "application/pdf", disposition: "inline"
end
end
end

Not sure what version of Prawn you're using, but this worked for me:
pdf = Prawn::Document.new(background: img, :page_size => "LETTER", :page_layout => :landscape)
pdf.render_file File.join(Rails.root, "app/pdfs", "x.pdf")
I think you're missing the pdf.render_file line that actually creates the file.

Related

Undefined method `pdf` with prawn-rails

Trying to set up a basic PDF template with prawn-rails, and something's not quite right.
Gemfile:
gem 'prawn-rails'
which does grab the latest version (1.0.0).
Controller:
def show
respond_to do |format|
format.pdf { render pdf: 'show.pdf.prawn' }
# ...
end
end
HAML view:
= link_to object_url(object, format: :pdf) do
%button.btn.btn.default Print
show.pdf.prawn:
prawn_document do
pdf.text "Some text"
end
config/initializers/prawn-rails.rb:
require 'prawn-rails'
PrawnRails.config do |config|
config.page_layout = :portrait
config.page_size = 'LETTER'
config.skip_page_creation = true
end
This is all according to the README of the prawn-rails repository.
But I get ActionView::Template::Error (undefined local variable or method 'pdf' for #<#<Class:0x005618ff5021e8>:0x005618ff97b968>).
Any thoughts? Should I just report this as an issue on the repo?
Should be:
prawn_document do |pdf|
pdf.text "Some text"
end
I'd send them a note and tell them to update their README.

RoR HTML template to .docx

I need to create a .docx file from a HTML template, so I used htmltoword gem.
Usage:
I added the gem (Gemfile):
gem 'htmltoword', '~> 0.5.1' #last version of the gem
I put a route (route.rb):
get 'preview' => 'foo#preview'
And in my bar.html.erb I have a link which target's that url:
<%= link_to '.docx', preview_path %>
Template (preview.docx.erb):
<h1>foobar</h1>
And in the controller (foos_controller.rb):
class FoosController < ApplicationController
respond_to :docx
#other code
def preview
respond_to do |format|
format.docx do
render docx: 'foobar', filename: 'preview.docx'
end
end
end
end
However, I'm getting an error:
ActionController::UnknownFormat
How to fix this error?
My config:
RoR v4.2.4
Ruby v2.2.3p173
Also, there is an open github issue for this/similar topic.
Update: as #kajalojha mentioned, respond_with / Class-Level respond_to has been removed to an individual gem, so I installed the responders gem, however, I get the same error.
Since respond_to has been removed from rails 4.2 to a individual gem i will recommend you to use formatter gem..
For further details you can look to the link given below.
Why is respond_with being removed from rails 4.2 into it's own gem?
Have you tried caracal-rails? You can find it here
I had to build this same functionality in an app earlier this year and also used the htmltoword gem.
# At the top of the controller:
respond_to :html, :js, :docx
def download
format.docx {
filename: "#{dynamically_generated_filename}",
word_template: 'name_of_my_word_template.docx')
}
end
I then have two "view" files that come into play. The first, is my method view file download.docx.haml. This file contains the following code:
%html
%head
%title Title
%body
%h1 A Cool Heading
%h2 A Cooler Heading
= render partial: 'name_of_my_word_template', locals: { local_var: #local_var }
From there, I have another file name_of_my_word_template.docx.haml that contains the meat of my Word file.
%h4 Header
%h5 Subheader
%div= local_var.method
%div Some other content
%div More content
%div Some footer content
When someone hits my_app.com/controller_name/download.docx, a Word file is generated and downloaded for them.
In order to ensure this happens, I have a route for the download method in my routes.rb file:
resources :model_name do
member do
get :download
end
end
Apologies for the long reply ... this has worked well for me and I hope helps you through this issue!
So, I figured it out. I added format: 'docx' to the route and it works now.
Note: as #kajalojha mentioned, respond_with / Class-Level respond_to has been removed to an individual gem, so I installed the responders gem.
Let's create a download logic.
Gemfile
gem 'responders'
gem 'htmltoword', '~> 0.5.1'
routes.rb
get 'download' => 'foos#download', format: 'docx' #added format
foos_controller.rb
class FoosController < ApplicationController
respond_to :docx
def download
#bar = "Lorem Ipsum"
respond_to do |format|
format.docx do
# docx - the docx template that you'll use
# filename - the name of the created docx file
render docx: 'download', filename: 'bar.docx'
end
end
end
end
download.docx.erb
<p><%= #bar %></p>
And I've added some link to trigger the download logic:
<%= link_to 'Download bar.docx', foo_download_path %>
Which will download the bar.docx file with "Lorem Ipsum" in it.

How to save generated pdf in server in rails

Currently I am generating a pdf using prawn gem of rails. pdf is generated when user hit on this action
def print_pdf
#user = User.find(params[:id])
#details = #user.details_data
respond_to do |format|
format.pdf do
pdf = PrintDetailsPdf.new(#user, view_context, #details)
send_data pdf.render, filename: "#{#user.id}.pdf",
type: 'application/pdf',
disposition: 'inline'
end
end
end
In above action, I generate the pdf and show it in browser and it works perfectly. But I want to show the pdf in browser and also save the pdf at server in public/user_details directory. How can I do that?
There are some good gems that help in file uploading and saving. Here is a list of these gems. Paperclip and Carrierwave are the most popular options.
You could also implement it from scratch. Rails has built-in helpers which make it easy to roll your own solution.
pdf_content = *Content you want to save in the file*
File.open(Rails.root.join('public', 'user_details', filename), 'wb') do |file|
file.write(pdf_content.read)
end
It depends on the complexity of what you want to achieve, but this is totally sufficient for easy file saving tasks. Go here to find more information.
You could do this
pdf_string = render_to_string :template => 'template', :layout => false
File.open("public/userfiles/example.pdf", 'wb') { |
f| f.write(pdf_string) }
end
Render the template to string and then create a file and write that pdf to it..
This should help

PDF Generator in rails 3

This code I have in the products controller Index Method:
def index
#products = Product.all
respond_to do |format|
format.html
format.pdf do
pdf = PDF::Writer.new
#products.each do |product|
pdf.text product.name
end
send_data pdf.render, :filename => 'products.pdf', :type => 'application/pdf', :disposition => 'inline'
end
end
end
and in
environment.rb file
require 'pdf/writer'
Mime::Type.register 'application/pdf', :pdf
While running the program I am getting the error
undefined method `each' for "Pen":String
Aha. According to PDF::Writer's home page, "PDF::WRITER HAS BEEN DISCONTINUED AS OF APRIL 15th, 2010. PLEASE USE ITS SPIRITUAL SUCCESSOR, PRAWN INSTEAD."
I've personally been very happy using prawn to generate PDF's. But to directly answer your question, my guess is that you're probably using ruby 1.9.x, which changed the String API a bit, and PDF::Writer is meant for ruby 1.8.7.
use metaskills-pdf-writer gem. This error is happening because the each method of strings on Ruby 1.8 has changed at version 1.9. So this no longer works on new versions of ruby. This gem i mentioned will fix the issue.

"Error: PDF could not be generated!" with WickedPDF

Error:
RuntimeError in BillsController#printing
Failed to execute:
"/usr/local/bin/wkhtmltopdf" -q "file:////var/folders/j5/2wx0qdjj7kl7vbvq3m2z4rj00000gn/T/wicked_pdf20130213-41259-x9dcb5.html" "/var/folders/j5/2wx0qdjj7kl7vbvq3m2z4rj00000gn/T/wicked_pdf_generated_file20130213-41259-mg4iqp.pdf"
Error: PDF could not be generated!
BillsController:
# GET /bills
# GET /bills.json
def print
respond_to do |format|
format.html
format.pdf do
render :pdf => "rechnung_id",
:layout => "printing.pdf",
:show_as_html => params[:debug]
end
end
end
as views I created a printing.html.erb and a printing.pdf.erb - and tried both.
I've installed wkhtmltopdf as binary and as gem. When I try to use the gem (commenting out the line:
WickedPdf.config = { :exe_path => '/usr/local/bin/wkhtmltopdf'}
something seems to crash and nothing happens..
When I use the binary, I get the error displayed on top.
The versions of my gems are:
wicked_pdf (0.9.4)
and wkhtmltopdf-binary (0.9.9.1).
I was searching for help - that's what I already tried:
"bundle update" and "bundle install"
installed wkhtmltopdf in version 9.9
added "Mime::Type.register "application/pdf", :pdf"
EDIT:
If I use the terminal and enter "wkhtmltopdf www.myHomepage.info myhomepage.pdf" it works fine. "which wkhtmltopdf" gives me the path "/usr/bin/wkhtmltopdf", but if I want to use with one, it's opening "wkhtmltopdf_darwin_386" and the website freezes..
now i solved the problem.
I changed my controller method to:
def printing
#bills = Bill.find(params[:id])
respond_to do |format|
format.html
format.pdf do
render :pdf => "bill_#{#bills.id}",
:wkhtmltopdf => '/usr/bin/wkhtmltopdf',
:template => '/bills/printing.pdf.erb',
:disposition => "inline"
#:save_to_file => Rails.root.join('pdf', "rechnung_#{#bills.id}.pdf")
end
end
end
and i had to remove WickedPDF as middleware in the application.rb:
require 'wicked_pdf'
config.middleware.use WickedPdf::Middleware, {}
now it's working as expected.

Resources