From my controller I create pdf:
def show
@order = Order.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @order }
format.pdf do
pdf = InvoicePdf.new(@order, view_context)
send_data pdf.render, filename: "invoice_#{@order.order_number}.pdf",
type: "application/pdf",
disposition: "inline",
size: 10
end
end
end
invoice_pdf.rb:
require 'barby'
require 'barby/barcode/code_39'
require 'barby/outputter/prawn_outputter'
class InvoicePdf < Prawn::Document
def initialize(order, view)
super({
:top_margin => 70,
:page_size => 'A4',
:font_size => 10,
:text => 8
})
@order = order
@view = view
order_number
barcode
end
def order_number
text "Order #{@order.order_number}"
end
def barcode
barcode = Barby::Code39.new @order.order_number
barcode.annotate_pdf(XXXX)
end
end
How should I modify my barcode method or the options marked as XXXX to embed barcode into PDF document?
EDIT
In your InvoicePdf
class, change the barcode
method to:
def barcode
barcode = Barby::Code39.new @order.order_number
barcode.annotate_pdf(self)
end
The annotate_pdf
method takes a Prawn::Document
as its argument, which is self
here.
Original Answer
If you want to create a new pdf with your barcode, you can just do:
def barcode
_barcode = Barby::Code39.new(@order.order_number)
outputter = Barby::PrawnOutputter.new(_barcode)
outputter.to_pdf
end
Note that you can specify pdf options (including height, margins, page size, etc.) on the new PrawnOutputter
or on the to_pdf
call. See the documentation for more details: https://github.com/toretore/barby/wiki/Outputters and http://rdoc.info/github/toretore/barby/Barby/PrawnOutputter.
And if you want to write it to a file do:
File.open("my_file.pdf","w") { |f| f.print barcode }
Note that you can also just call _barcode.to_pdf
, which seems to have the same effect as creating a new PrawnOutputter
, but this functionality is not described in the Barby documentation.
If you have an existing pdf document (as a Prawn::Document
) that you want to write a barcode to, note that you could do:
def barcode(p_pdf)
_barcode = Barby::Code39.new(@order.order_number)
_barcode.annotate_pdf(p_pdf)
end
In my case, barcode.annotate_pdf(self)
was throwing some errors because it wasn't recognizing attributes like fill_color
, so I ended up creating the Barby barcode as a PNG image and then inserting it in the PDF. Something like this:
require 'barby'
require 'barby/barcode/code_128'
require 'barby/outputter/png_outputter'
...
pdf = Prawn::Document.new(page_size: 'A4', margin: 20)
# Print data as text
order = "Order ##{@data.order_number} "
pdf.text_box order, size: 12, at: [0, pdf.cursor], width: 550
# Print data as image
barcode = Barby::Code128.new @data.order_number
barcode_blob = Barby::PngOutputter.new(barcode).to_png
# barcode.png is stored in tmp directory
File.open("tmp/barcode.png", 'wb'){|f| f.write barcode.to_png }
pdf.image "#{Rails.root.to_s}/tmp/barcode.png", image_width: 50, image_height: 50, position: :center
...
pdf.render
Option #2: Using StringIO instead of tmp File
# Print data as image
barcode = Barby::Code128.new @data.order_number
barcode_blob = Barby::PngOutputter.new(barcode).to_png
barcode_io = StringIO.new(barcode_blob)
barcode_io.rewind
pdf.image(barcode_io, image_width: 50, image_height: 50, position: :center)
...
pdf.render
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With