PDF generate
Setting:
To install praw into a Rails application is very simple, we just need to declare the gem line "prawn" in the Gemfile. Next, we need to run the command in the terminal
bundle install
Use:
Step 1: We need to declare PDF Mime::Type in the config/initializers/mime_types.rb file as follows:
Mime::Type.register “application/pdf”, :pdf
From now on, every time there is a request where the mime is a PDF, the application will return the content of the PDF file.
Step 2: We will perform processing in the controller to return the PDF file format. For example the code below:
class InvoicesController < ApplicationController
before_filter :authenticate_customer!, :only => [:index, :show]
def index
@invoices = Invoice.all_invoices(current_customer)
end
def show
@invoice = Invoice.find(params[:id])
respond_to do |format|
format.html
format.pdf do
pdf = InvoicePdf.new(@invoice, view_context)
send_data pdf.render, filename:
"invoice_#{@invoice.created_at.strftime("%d/%m/%Y")}.pdf",
type: "application/pdf"
end
end
end
end
In the above code, we have changed the format of the response in two formats, html and pdf. And inside the format.pdf block, we call the send_data method with the file content, filename, and application type as parameters to read the file. In addition, this function also has one more option disposition: "inline" that will display the PDF file right on the browser instead of having to download it to the client computer.
Step 3: We will proceed to the PDF file format that needs to be created using praw. This is done in the InvoicePdf class that extends the Prawn::Document class in the praw library.
class InvoicePdf < Prawn::Document
def initialize(invoice, view)
super()
text "This is an order invoice", size: 16, font: "Helvetica", color: "0000FF"
end
end
The above code uses praw's text method to display in a PDF file with font size 16, font Helvetica and blue text. Similarly, we can display other lines of text by using this method again.
When creating an invoice, we usually print the company's logo. So how can we create images in PDF files?. This becomes extremely simple with the use of the library's image method. For example, if we display an image in the middle of the file with a size of 50x50, we will do the following:
def logo
logopath = "#{Rails.root}/app/assets/images/logo.png"
open(logopath), fit: [500, 500], position: :center
end
Moving Around##
This is a feature that helps us to determine exactly where we want to place each text or image... element in the document by moving the mouse pointer to the desired coordinate through the move_down( function). n), move_up(n) or move_cursor_to(n). Note that the coordinate axis of the document page with origin [0, 0] is at the last position on the left of the page and the positive axis points upwards.
In addition, the praw library, also allows us to present the document in the form of a table using table, row and column methods.
The following is the code of the InvoicePdf class to display an Invoice in PDF format for your reference for formatting a simple PDF file.
class InvoicePdf < Prawn::Document
def initialize(invoice, view)
super()
@invoice = invoice
@view = view
logo
thanks_message
subscription_date
subscription_details
subscription_amount
regards_message
end
def logo
logopath = "#{Rails.root}/app/assets/images/logo.png"
image logopath, width: 197, height: 91
move_down 10
draw_text "Receipt", at: [220, 575], size: 22
end
def thanks_message
move_down 80
text "Hello #{@invoice.customer.profile.first_name.capitalize},"
move_down 15
text "Thank you for your order.Print this receipt as
confirmation of your order.",
indent_paragraphs: 40, size: 13
end
def subscription_date
move_down 40
text "Subscription start date:
#{@invoice.start_date.strftime("%d/%m/%Y")} ", size: 13
move_down 20
text "Subscription end date :
#{@invoice.end_date.strftime("%d/%m/%Y")}", size: 13
end
def subscription_details
move_down 40
table subscription_item_rows, width: 500 do
row(0).font_style = :bold
columns(1..3).align = :right
self.header = true
self.column_widths = {0 => 200, 1 => 100, 2 => 100, 3 => 100}
end
end
def subscription_amount
subscription_amount = @invoice.calculate_subscription_amount
vat = @invoice.calculated_vat
delivery_charges = @invoice.calculated_delivery_charges
sales_tax = @invoice.calculated_sales_tax
table ([["Vat (12.5% of Amount)", "", "", "#{precision(vat)}"] ,
["Sales Tax (10.3% of half the Amount)", "", "",
"#{precision(sales_tax)}"] ,
["Delivery charges", "", "", "#{precision(delivery_charges)} "],
["", "", "Total Amount", "#{precision(@invoice.total_amount) } "]]),
:width => 500 do
columns(2).align = :left
columns(3).align = :right
self.header = true
self.column_widths = {0 => 200, 1 => 100, 2 => 100, 3 => 100}
columns(2).font_style = :bold
end
end
def subscription_item_rows
[["Description", "Quantity", "Rate", "Amount"]] +
@invoice.subscriptions.map do |subscribe|
[ "#{subscribe.description} ", subscribe.quantity,
"#{precision(subscribe.rate)} ",
"#{precision(subscribe.quantity * subscribe.rate)}" ]
end
end
def precision(num)
@view.number_with_precision(num, :precision => 2)
end
def regards_message
move_down 50
text "Thank You," ,indent_paragraphs: 400
move_down 6
text "XYZ",
indent_paragraphs: 370, :size: 14, style: :bold
end
end
The last step: We add the link of the PDF file in the views: app/views/invoices/show.html.erb:
<%= link_to "Download invoice", invoice_path(invoice.id, format: "pdf") %>;