Skip to content

Commit 5f8ab91

Browse files
authored
Merge pull request #93 from strzibny/qr-support
Add QR image support
2 parents 0715c23 + e529a47 commit 5f8ab91

File tree

13 files changed

+128
-2
lines changed

13 files changed

+128
-2
lines changed

assets/qr.png

12.5 KB
Loading

bin/invoice_printer

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def show_help
2222
--bold-font path to bold font or builtin font name
2323
-s, --stamp path to stamp
2424
--logo path to logotype
25+
--qr path to QR image
2526
--background path to background image
2627
--page-size letter or a4 (letter is the default)
2728
-f, --filename output path
@@ -60,6 +61,10 @@ parser = OptionParser.new do|opts|
6061
options[:logo] = path
6162
end
6263

64+
opts.on('--qr PATH') do |path|
65+
options[:qr] = path
66+
end
67+
6368
opts.on('--background PATH') do |path|
6469
options[:background] = path
6570
end
@@ -124,6 +129,7 @@ begin
124129
bold_font: options[:bold_font],
125130
stamp: options[:stamp],
126131
logo: options[:logo],
132+
qr: options[:qr],
127133
background: options[:background],
128134
page_size: options[:page_size]
129135
)
@@ -139,6 +145,7 @@ begin
139145
bold_font: options[:bold_font],
140146
stamp: options[:stamp],
141147
logo: options[:logo],
148+
qr: options[:qr],
142149
file_name: options[:filename],
143150
background: options[:background],
144151
page_size: options[:page_size]

docs/COMMAND_LINE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Options:
1616
--bold-font path to bold font or builtin font name
1717
-s, --stamp path to stamp
1818
--logo path to logotype
19+
--qr path to QR image
1920
--background path to background image
2021
--page-size letter or a4 (letter is the default)
2122
-f, --filename output path

docs/SERVER.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ Options:
6464
- `bold_font` - path to bold font file or builtin font name
6565
- `stamp` - path to stamp file
6666
- `logo` - path to logotype file
67+
- `qr` - path to QR image file
6768
- `background` - path to background file
6869
- `page_size` - letter or A4 page size
6970

@@ -107,6 +108,7 @@ Options:
107108
- `bold_font` - path to bold font file or builtin font name
108109
- `stamp` - path to stamp file
109110
- `logo` - path to logotype file
111+
- `qr` - path to QR image file
110112
- `background` - path to background file
111113
- `page_size` - letter or A4 page size
112114
- `filename` - path for saving the generated output PDF

examples/qr.png

12.5 KB
Loading

examples/qr_invoice.pdf

33.9 KB
Binary file not shown.

examples/qr_invoice.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env ruby
2+
# Example demonstrating adding a QR image to the invoice (bottom-right)
3+
4+
lib = File.expand_path('../../lib', __FILE__)
5+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6+
require 'invoice_printer'
7+
8+
provider_address = <<ADDRESS
9+
5th Avenue
10+
747 05 NYC
11+
ADDRESS
12+
13+
purchaser_address = <<ADDRESS
14+
7th Avenue
15+
747 70 NYC
16+
ADDRESS
17+
18+
item = InvoicePrinter::Document::Item.new(
19+
name: 'Programming',
20+
quantity: '10',
21+
unit: 'hr',
22+
price: '$ 90',
23+
amount: '$ 900'
24+
)
25+
26+
invoice = InvoicePrinter::Document.new(
27+
number: 'NO. 202500000001',
28+
provider_name: 'John White',
29+
provider_lines: provider_address,
30+
purchaser_name: 'Will Black',
31+
purchaser_lines: purchaser_address,
32+
issue_date: '10/20/2025',
33+
due_date: '11/03/2025',
34+
total: '$ 900',
35+
bank_account_number: '156546546465',
36+
description: "Invoice with QR image example.",
37+
items: [item],
38+
note: "Scan the QR code for payment or details."
39+
)
40+
41+
qr_path = File.expand_path('../qr.png', __FILE__)
42+
logo_path = File.expand_path('../prawn.png', __FILE__)
43+
44+
InvoicePrinter.print(
45+
document: invoice,
46+
logo: logo_path,
47+
qr: qr_path,
48+
file_name: 'qr_invoice.pdf'
49+
)
50+
51+
InvoicePrinter.print(
52+
document: invoice,
53+
logo: logo_path,
54+
qr: qr_path,
55+
file_name: 'qr_invoice_a4.pdf',
56+
page_size: :a4
57+
)

examples/qr_invoice_a4.pdf

34.4 KB
Binary file not shown.

lib/invoice_printer.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
# bold_font: 'path-to-font-file.ttf',
1919
# stamp: 'stamp.jpg',
2020
# logo: 'logo.jpg',
21+
# qr: 'qr.png',
2122
# file_name: 'invoice.pdf'
2223
# )
2324
module InvoicePrinter
@@ -69,6 +70,7 @@ def self.labels
6970
# bold_font - bold font file to use
7071
# stamp - stamp & signature (image)
7172
# logo - logotype (image)
73+
# qr - QR image (image)
7274
# background - background (image)
7375
# page_size - :letter or :a4
7476
# file_name - output file
@@ -79,6 +81,7 @@ def self.print(
7981
bold_font: nil,
8082
stamp: nil,
8183
logo: nil,
84+
qr: nil,
8285
background: nil,
8386
page_size: :letter,
8487
file_name:
@@ -90,6 +93,7 @@ def self.print(
9093
bold_font: bold_font,
9194
stamp: stamp,
9295
logo: logo,
96+
qr: qr,
9397
background: background,
9498
page_size: page_size
9599
).print(file_name)
@@ -103,6 +107,7 @@ def self.print(
103107
# bold_font - bold font file to use
104108
# stamp - stamp & signature (image)
105109
# logo - logotype (image)
110+
# qr - QR image (image)
106111
# background - background (image)
107112
# page_size - :letter or :a4
108113
def self.render(
@@ -112,6 +117,7 @@ def self.render(
112117
bold_font: nil,
113118
stamp: nil,
114119
logo: nil,
120+
qr: nil,
115121
background: nil,
116122
page_size: :letter
117123
)
@@ -122,6 +128,7 @@ def self.render(
122128
bold_font: bold_font,
123129
stamp: stamp,
124130
logo: logo,
131+
qr: qr,
125132
background: background,
126133
page_size: page_size
127134
).render

lib/invoice_printer/pdf_document.rb

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ module InvoicePrinter
1313
# font: 'font.ttf',
1414
# bold_font: 'bold_font.ttf',
1515
# stamp: 'stamp.jpg',
16-
# logo: 'example.jpg'
16+
# logo: 'example.jpg',
17+
# qr: 'qr.png'
1718
# )
1819
class PDFDocument
1920
class FontFileNotFound < StandardError; end
2021
class LogoFileNotFound < StandardError; end
2122
class StampFileNotFound < StandardError; end
23+
class QRFileNotFound < StandardError; end
2224
class InvalidInput < StandardError; end
2325

24-
attr_reader :invoice, :labels, :file_name, :font, :bold_font, :stamp, :logo
26+
attr_reader :invoice, :labels, :file_name, :font, :bold_font, :stamp, :logo, :qr
2527

2628
DEFAULT_LABELS = {
2729
name: 'Invoice',
@@ -74,6 +76,7 @@ def initialize(
7476
bold_font: nil,
7577
stamp: nil,
7678
logo: nil,
79+
qr: nil,
7780
background: nil,
7881
page_size: :letter
7982
)
@@ -83,6 +86,7 @@ def initialize(
8386
@bold_font = bold_font
8487
@stamp = stamp
8588
@logo = logo
89+
@qr = qr
8690
@page_size = page_size ? PAGE_SIZES[page_size.to_sym] : PAGE_SIZES[:letter]
8791
@pdf = Prawn::Document.new(background: background, page_size: @page_size.name)
8892

@@ -105,6 +109,14 @@ def initialize(
105109
end
106110
end
107111

112+
if used? @qr
113+
if File.exist?(@qr)
114+
@qr = qr
115+
else
116+
raise QRFileNotFound, "QR image file not found at #{@qr}"
117+
end
118+
end
119+
108120
if used?(@font) && used?(@bold_font)
109121
use_font(@font, @bold_font)
110122
elsif used?(@font)
@@ -176,6 +188,7 @@ def build_pdf
176188
build_total
177189
build_stamp
178190
build_logo
191+
build_qr
179192
build_note
180193
build_footer
181194
end
@@ -855,6 +868,26 @@ def build_logo
855868
end
856869
end
857870

871+
# Insert a QR image at the right bottom of the document
872+
#
873+
# If a note is present, position it on top of it.
874+
def build_qr
875+
if @qr && !@qr.empty?
876+
bottom = @document.note.empty? ? 75 : (75 + note_height)
877+
# Place QR at page width minus its fit width to keep it at the right edge.
878+
879+
image_info = Prawn::Images::PNG.new(File.read(@qr))
880+
image_width = image_info.width.to_f
881+
882+
if image_width > x(50)
883+
image_width = x(50)
884+
end
885+
886+
left = @pdf.bounds.right - image_width
887+
@pdf.image(@qr, at: [left, bottom], fit: [x(50), y(50)])
888+
end
889+
end
890+
858891
# Insert a stamp (with signature) after the total table
859892
def build_stamp
860893
if @stamp && !@stamp.empty?

0 commit comments

Comments
 (0)