0.0
No release in over 3 years
Low commit activity in last 3 years
A gem for overlaying text and other fields onto PDF templates using Prawn.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.3
>= 0
>= 0

Runtime

~> 0.12.0
 Project Readme

PdfTempura

Code Climate Build Status Dependency Status

A gem for overlaying text and other fields onto PDF templates using Prawn.

Installation

Add this line to your application's Gemfile:

gem 'pdf_tempura'

And then execute:

$ bundle

Or install it yourself as:

$ gem install pdf_tempura

Usage

Building your overlayed PDF template

Inherit from PdfTempura::Document to start off your pdf.

Specifying the template

Specify your template using:

  template "/some/path/to/template.pdf"

Specifying pages

The page method can be used to specify a page. It takes number to specify the page, and a block where you specify your fields.

You may also specify default options for layout by passing them into the "page" method. They will be inherited into all the page elements unless overridden by the options of that element.

page 1, alignment: "left" do
  # fields ...
end

Specifying fields

Fields should be specified inside pages using the page method. Fields can be specified by using one of the following fields methods.

Text fields

You can specify a text field using the text_field method. It requires a name, an array of coordinates (x and y), and an array of dimensions (width and height). Coordinates and dimensions are numbers referencing PDF units, starting from bottom left.

text_field(name, coordinates, dimensions, options)

It also takes an options hash where you can set the following options:

Common Options:

  • type: "text", "checkbox" or "box-list". Defines the type of the field and draws the appropriate type. A box-list will create a box field for each character of the passed text. Default is "text".
  • default_value: The default value for the field. Default is nil.

TextField options:

  • font_size: A number in pixels (i.e. 13), or auto to change the font to fit the field size. Default is 10px.
  • font_name: The name of the font to use. Default: "Helvetica"
  • italic: True or false. Makes the text italic when set to true. Default to false.
  • bold: True or false. Makes the text bold when set to true. Default is false.
  • alignment: "left", "center" or "right". Aligns the text in the boundaries of the field. Default is "left".
  • multi_line: True or false. Forces the text to wrap to the next line when it hits the boundaries of the field. Default is false.
  • padding: An array of 4 numbers, representing top, right, bottom, left. It adds padding in pdf units inside the field.
  • valign: Defines vertical alignment of the text in the box, top, center, or bottom.
  • leading: When multi_line is true, this will add top_margin to each wrapped line of text.
page 1 do
  text_field :country, [10, 20], [200, 400], default_value: "USA", font_size: 13, bold: true, alignment: left, multi_line:true
end
Checkbox fields

You can specify a checkbox field using the checkbox_field method. It requires a name, an array of coordinates (x and y), and an array of dimensions (width and height). Coordinates and dimensions are numbers referencing PDF units, starting from bottom left.

checkbox_field(name, coordinates, dimensions, options)

It also takes an options hash where you can set the following options:

  • default_value: True or false. The default value for the checkbox. Default is false.
page 1 do
  checkbox_field :send_me_snacks, [10, 20], [20, 20], default_value: true
end
Boxed Characters

This is a field which helps you to display a field which needs to be printed in a boxed fashion. E.g. [H][E][L][L][O]-[W][O][R][L][D].

boxed_characters :name, [10,20], 20, box_spacing: 1, box_width: 10 do
  characters 4
  space 2
  characters 4
end

Boxed Characters options:

  • box_spacing: Required, amount of space between each individual box
  • box_width: Required, the width of each individual box
  • other: You may use any of the options that are also in use with text_field EXCEPT for alignment, and multi-line.
Tables
class MyDoc < PdfTempura::Document
  page 1 do
    table :stuff, [500,50], height: 300, number_of_rows: 10, row_height: 25, cell_padding: 1 do
      text_column :pin, 50
      space 5
      checkbox_column :last_name, 100
    end
  end
end

The table construct allows the creation of a repeating set of fields.

Table options:

  • height: Optional, height of the overall table.
  • number_of_rows: The number of rows in the table, required
  • row_height: The height of each row
  • cell_padding: Padding between each cell, optional

The table call takes a name, the x,y position of the top-left corner of the table, the number of rows, either row_height or height (or both), and cell padding.

Inside the table block, you define columns or spaces. Columns themselves have amalgamous names to those you may use in "page" to describe fields. Use "text_column" for a column containing text, "checkbox_column" for a cell containing a checkbox.

Space only takes one parameter, its width.

Column mimicks 'field', except you only specify the width of the column, the rest is figured out by the table.

Table data is assigned through assigning an array of hashes to the key named after the name of the table.

eg:

data = {
 1 => {
   stuff: [
     { pin: "12 3456789 6", last_name: "Doe"}
   ]
 }
}
Field Sets

A field set allows you to group pieces of data under a particular heading. You define a field set simply by the name of the heading it will be contained under in the data. This is to help you organize your data logically.

You may also specify default options for layout by passing them into the field_set method. They will be inherited into all the page elements unless overridden by the options of that element.

class MyPdf < PdfTempura::Document
  ...

  page 1 do
    field_set "customer", font_size: 12 do
      text_field "name", [0,0], [10,20]
      text_field "address", [0,10], [10,20]
    end
  end

end

data = {
  1 => {
    "customer" => { "name" => "John Bazdaritch", "address" => "123 Hollywood Blvd" }
  }
}
Specifying default options for a few elements

The with_default_options block can be used to provide default options for all elements within it's specified block. These default options will be merged with the default options of the enclosing page, field set or table. Elements can override these default options by explicitly passing the option to the element.

page 1, alignment: "left" do
  text_field :aligned_left, [10,20], [100,50]

  with_default_options alignment: "right" do
    text_field :aligned_right, [40,60], [100,50]
    text_field :also_aligned_left, [70,80], [100,50], alignment: "right"
  end
end

#### Specifying reusable groups

If you have the same fields on multiple pages, you can use the `group` method to DRY your template.

```ruby
group :employee_details do
  field :first_name, [10, 20], [100, 30]
  field :surname, [120, 20], [200, 30], bold: true
  field :company, [330, 20], [300, 30], alignment: right
end

Then you can use the include_group method to add that group to pages.

page 1 do
  include_group :employee_details
  field :address, [10, 20], [500, 60]
  ...
end

page 2 do
  include_group :employee_details
  field :emergency_contact, [10, 20], [500, 60]
  ...
end

Rendering your PDF

Loading field data

You can load the field data by creating a new instance of your overlayed template and passing a data hash. The data hash should be a hash of hashes, the keys at the first level matching the page numbers and groups of your template, and the keys inside the nested hashes matching the names of the fields in those pages.

data_hash = {
  :employee_details => {
    :first_name => "Stan",
    :surname => "Smith",
    :company => "CIA"
  },
  1 => {
    :address => "The Pentagon, Washington, DC"
  },
  2 => {
    :emergency_contact => "Francine Smith"
  }
}

my_pdf = MyPdf.new(data_hash)

You can override group values by including the key in a specific page's data hash. Keys can be either strings or symbols.

Rendering your overlayed PDF

After loading the field data, you can then render the PDF using the render method. The render method takes a block, and provides the opened pdf file as an argument. The pdf file will be closed when the block terminates and the value of the block will be returned.

mypdf.render do |pdf|
  # save PDF to file
  File.new("/path/to/file". "w+") do |file|
    file.write(pdf.read)
  end
end

Repeating data

If you would like the template you have specified to be repeated on matching pages then you need to use the "repeatable" option in your Document class. If repeatable is set then if you specify pages 1,2 in your document, and then specify 1,2,3,4 in your data the produced page will reuse the template's page 1 for page 3 and page 2 for page 4, etc.

class MyPdf < PdfTempura::Document

  template "/some/path/to/template.pdf"
  repeatable

  ...

end

data = {1 => ... data for page 1,
        2 => ... data for page 2,
        3 => ... data for page 3,
        4 => ... data for page 4}

Debug mode

You can set your template to debug mode to help you position your fields using the debug method. The debug options are:

  • grid: This will overlay a grid on the document, each box representing a 10x10 unit area.
  • outlines: This will outline each field with a black border.
class MyPdf < PdfTempura::Document

  template "/some/path/to/template.pdf"

  debug :grid, :outlines

  ...

end

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request