Module: BarkestCore::PdfHelper

Defined in:
app/helpers/barkest_core/pdf_helper.rb

Overview

This module defines the method that makes PDF generation just a bit easier.

Instance Method Summary collapse

Instance Method Details

#pdf_doc(options = {}) {|pdf| ... } ⇒ Object

Creates a PDF document with the specified options.

The document will be setup with configured margins, a 100x100 grid, and one embedded font (ArhivoNarrow). Once the document is configured, the pdf will be yielded to the block provided to generate the content.

Accepted options:

page_layout

Specify the page layout. This can be either :portrait or :landscape. Defaults to :portrait.

page_size

Specify the page size. This defaults to ‘LETTER’. See Prawn PDF Manual for more information.

margin

Specify the margin size. This can be either a single value or an array of values. Internally it always gets converted to an array of values. If you only specify a single value, it will be filled out as the margin for all four edges. Alternatively, you can set :top_margin, :right_margin, :left_margin, and :bottom_margin individually.

top_margin

Specify the top margin size. Defaults to 0.5 in.

right_margin

Specify the right margin size. Defaults to 0.5 in.

left_margin

Specify the left margin size. Defaults to 0.5 in.

bottom_margin

Specify the bottom margin size. Defaults to 0.5 in.

print_scaling

Allows you to specify the default print scaling in the print dialog. Defaults to :none. See the Prawn PDF Manual for more information.

font_name

Specify the default font for the document. Can be one of ‘Helvetica’, ‘Times-Roman’, ‘Courier’, or ‘ArchivoNarrow’. Defaults to ‘Helvetica’.

font_size

Specify the default font size for the document. Defaults to 10 pt.

skip_footer

Set to true to skip footer generation. Otherwise, once you finish generating content, a footer will be attached to every page automatically.

footer_left

Set the left footer text. Defaults to the current user name and time.

footer_center

Set the center footer text. Defaults to the request path.

footer_right

Set the right footer text. Defaults to “Page # of #”.

footer_hr

Set to true to draw a horizontal rule above the footer, or false to omit the horizontal rule. Defaults to true.

footer_color

Set the color of the footer text. Defaults to ‘000000’ (black).

Yields:

  • (pdf)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'app/helpers/barkest_core/pdf_helper.rb', line 74

def pdf_doc(options = {})

  # our default values merged with the configured values and then the options provided.
  options = {
      page_layout: :portrait,
      page_size: 'LETTER',
      margin: [ 0.5.in, 0.5.in, 0.55.in, 0.5.in ],
      print_scaling: :none,
      font_name: 'Helvetica',
      font_size: 10.0
  }.merge(PrawnRails.config.to_h).merge(options || {})

  # build the info
  options[:info] ||= {}
  options[:info].merge!({
                            Title: options.delete(:title) ||  "#{controller_name}##{action_name}",
                            Creator: options.delete(:creator) || Rails.application.app_company,
                            Producer: options.delete(:producer) || Rails.application.app_info,
                            CreationDate: options.delete(:creation_date) || Time.now
                        })

  # build the margin array
  options[:margin] ||= []
  options[:margin] = [ options[:margin] ] * 4 unless options[:margin].is_a?(Array)

  # top margin defaults to 0.5".
  options[:margin][0] = options[:top_margin] if options[:top_margin]
  options[:margin][0] = 0.5.in unless options[:margin][0]

  # right margin defaults to top margin.
  options[:margin][1] = options[:right_margin] if options[:right_margin]
  options[:margin][1] = options[:margin][0] unless options[:margin][1]

  # bottom margin defaults to top margin.
  options[:margin][2] = options[:bottom_margin] if options[:bottom_margin]
  options[:margin][2] = options[:margin][0] unless options[:margin][2]

  # left margin defaults to right margin.
  options[:margin][3] = options[:left_margin] if options[:left_margin]
  options[:margin][3] = options[:margin][1] unless options[:margin][3]

  font_name = options[:font_name] || 'Helvetica'
  font_size = options[:font_size] || 10.0

  skip_footer = options[:skip_footer].nil? ? false : options[:skip_footer]

  footer_left = options[:footer_left].nil? ? "#{current_user.name} - #{Time.zone.now.strftime('%Y-%m-%d %H:%M:%S')}" : options[:footer_left].to_s
  footer_center = options[:footer_center].nil? ? request.fullpath : options[:footer_center].to_s
  footer_right = options[:footer_right].nil? ? nil : options[:footer_right].to_s
  footer_hr = options[:footer_hr].nil? ? true : options[:footer_hr]
  footer_color = options[:footer_color].nil? ? '000000' : options[:footer_color].to_s

  # remove some options that are custom.
  options.except!(
      :title, :creator, :producer, :creation_date,
      :top_margin, :bottom_margin, :left_margin, :right_margin,
      :font_name, :font_size,
      :skip_footer
  )

  left_edge = options[:margin][3]
  right_edge = options[:margin][1]
  bottom_edge = options[:margin][2]

  pdf = PrawnRails::Document.new(options)

  # ArchivoNarrow gives us another sans font that has tighter letter spacing, and it is also a freely available font requiring no licensing.
  pdf.font_families['ArchivoNarrow'] = {
      bold:         { file: pdf.asset_font_path('barkest_core/ArchivoNarrow-Bold.ttf') },
      italic:       { file: pdf.asset_font_path('barkest_core/ArchivoNarrow-Italic.ttf') },
      bold_italic:  { file: pdf.asset_font_path('barkest_core/ArchivoNarrow-BoldItalic.ttf') },
      normal:       { file: pdf.asset_font_path('barkest_core/ArchivoNarrow-Regular.ttf') },
  }

  # set the default font and size
  pdf.font font_name, size: font_size

  # nice fine grid layout.
  pdf.define_grid columns: 100, rows: 100, gutter: 2.5

  yield pdf if block_given?

  unless skip_footer
    pdf.font font_name, size: 8.0 do
      (1..pdf.page_count).each do |pg|
        pdf.go_to_page pg
        pdf.canvas do
          width = pdf.bounds.right - right_edge - left_edge
          if footer_hr
            pdf.stroke_color '000000'
            pdf.stroke { pdf.horizontal_line left_edge, pdf.bounds.right - right_edge, at: bottom_edge }
          end
          pos = [ left_edge, bottom_edge - 3 ]
          pdf.bounding_box(pos, width: width, height: 12) { pdf.text pdf.footer_values[0] || footer_left, align: :left, color: footer_color }
          pdf.bounding_box(pos, width: width, height: 12) { pdf.text pdf.footer_values[1] || footer_center, align: :center, color: footer_color }
          pdf.bounding_box(pos, width: width, height: 12) { pdf.text pdf.footer_values[2] || (footer_right || "Page #{pg} of #{pdf.page_count}"), align: :right, color: footer_color }
        end
      end
    end
  end

  pdf.render

end