神刀安全网

Generate Barcodes with JRuby and Barcodes4J

Generate Barcodes with JRuby and Barcodes4J

Ruby has a very vibrant ecosystem that provides solutions for almost all common problems. But one particularly lagging area is barcode generation. Ruby only has solutions for generating QR Codes, which are undoubtedly popular, but do not enjoy mass acceptance in industry segments. Older barcode symbologies, such as Code 128, DataMatrix, and PDF417, enjoy more acceptance in business applications than QR Codes. What should we do if need to generate a Code 128 in a Ruby/Rails application?

Fortunately we have a solution: JRuby. JRuby allows us to leverage excellent Java libraries and use them in Ruby applications. One such library is Barcode4J which is popular in the Java world for generating barcodes. Today, we will learn how to integrate and use Barcode4J in Ruby. So, let’s get started.

Basic Rails appliation

We will create a basic Rails application. The application will use JRuby, Rails 4.2, and SQLite as thedatabase to keep things simple. First of all, install JRuby with RVM or rbenv .

Switch to JRuby and gem install the latest Rails gem. Now create a new Rails application, like so:

rails new barcode4j_rails -T 

After the application is generated, switch to the application directory and check out how it’s working:

rails s 

Point your favorite browser to http://localhost:3000 and we should see the default Rails page.

Integrating Barcode4J

We will now integrate Barcode4J into our Rails app. First, download the Barcode4J files from the Barcode4J Project Page page. We will be using the 2.1.0 version. Download barcode4j-2.1.0-bin.zip and unzip the file. Copy barcode4j.jar from the build folder into lib/barcode4j in our application directory. Also, copy all files from the lib folder into lib/barcode4j .

Finally, our directory structure should look as follows:

barcode4j_rails   - app   ...   - lib     - barcode4j       - barcode4j.jar       ... 

Now that we have all required files in place, create a class named barcode_generator.rb in lib directory with following code:

# Load all Java libraries related to Barcode4J Dir.entries("#{Rails.root}/lib/barcode4j").each do |lib|   require "barcode4j/#{lib}" if lib =~ //.jar$/ end  require 'java'  # Load all class references java_import Java::java.io.ByteArrayOutputStream java_import Java::java.awt.image.BufferedImage java_import Java::org.krysalis.barcode4j.impl.code128.Code128Bean java_import Java::org.krysalis.barcode4j.impl.datamatrix.DataMatrixBean java_import Java::org.krysalis.barcode4j.impl.code39.Code39Bean java_import Java::org.krysalis.barcode4j.impl.pdf417.PDF417Bean java_import Java::org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider java_import Java::org.krysalis.barcode4j.tools.UnitConv  class BarcodeGenerator   def self.generate(symbology, data)     # Create a ByteArrayOutputStream object for storing the image     bos = ByteArrayOutputStream.new      # Set DPI     dpi = 160      bean = nil      # Set the Canvas object for barcode rendering     canvas = BitmapCanvasProvider.new(bos, "image/x-png", dpi, BufferedImage::TYPE_BYTE_BINARY, false, 0)      # Set barcode symbology     case symbology     when "code128"       bean = Code128Bean.new     when "datamatrix"       bean = DataMatrixBean.new     when "code39"       bean = Code39Bean.new     when "pdf417"       bean = PDF417Bean.new     end      # Configure the barcode generator     bean.set_module_width(UnitConv.in2mm(2.8 / dpi))     bean.do_quiet_zone(true)      # Generate barcode      bean.generateBarcode(canvas, data)     canvas.finish()      # Convert image to byte array for streaming     bytes = bos.toByteArray     bos.close      return String.from_java_bytes(bytes)   end end 

We have created a simple utility class that can generate four types of barcodes, sending send back an image file in PNG format. All we have to pass is the symbology and data for the barcode. Let’s break down the inner workings of the class.

First, we load all .jar files into the classpath:

Dir.entries("#{Rails.root}/lib/barcode4j").each do |lib|   require "barcode4j/#{lib}" if lib =~ //.jar$/ end 

Then, import all required references:

java_import Java::java.io.ByteArrayOutputStream java_import Java::java.awt.image.BufferedImage java_import Java::org.krysalis.barcode4j.impl.code128.Code128Bean java_import Java::org.krysalis.barcode4j.impl.datamatrix.DataMatrixBean java_import Java::org.krysalis.barcode4j.impl.code39.Code39Bean java_import Java::org.krysalis.barcode4j.impl.pdf417.PDF417Bean java_import Java::org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider java_import Java::org.krysalis.barcode4j.tools.UnitConv 

Next, set the DPI for the barcode image and create a ByteArrayOutputStream object to hold the rendered image. Then, create a BitmapCanvas on which to actually draw the barcode. Like so:

# Create a ByteArrayOutputStream object for storing the image bos = ByteArrayOutputStream.new  # Set DPI dpi = 160  bean = nil  # Set the Canvas object for barcode rendering canvas = BitmapCanvasProvider.new(bos, "image/x-png", dpi, BufferedImage::TYPE_BYTE_BINARY, false, 0) 

Initialize the barcode symbology as provided:

# Set barcode symbology case symbology when "code128"   bean = Code128Bean.new when "datamatrix"   bean = DataMatrixBean.new when "code39"   bean = Code39Bean.new when "pdf417"   bean = PDF417Bean.new end 

Configure the barcode generator for settings such as quiet zone and module width :

# Configure the barcode generator bean.set_module_width(UnitConv.in2mm(2.8 / dpi)) bean.do_quiet_zone(true) 

Next, invoke the actual barcode generation method:

# Generate barcode  bean.generateBarcode(canvas, data) canvas.finish() 

Lastly, convert the barcode image into byte stream and return the image:

# Convert image to byte array for streaming bytes = bos.toByteArray bos.close  return String.from_java_bytes(bytes) 

Now we have our barcode generator in place. Let’s create an initializer in config/initializers/barcode.rb to load the class in Rails:

require 'barcode_generator' 

Testing the Barcode Generator

Now we will create a BarcodesController class in app/controllers with the following code:

class BarcodesController < ApplicationController   def index   end    def generate     send_data BarcodeGenerator.generate(params[:symbology], params[:data]), :type => :png, :disposition => 'inline'   end end 

We defined two actions here. First, an index action to render the actual page of the Barcode Generator, which we will create shortly. Second, a generate action to call and render the barcode image. The generate action invokes the BarcodeGenerate.generate method with the symbology and data parameters from the URL. Then, generate uses the send_data method to stream the image to browser.

Now update config/routes.rb to add routes to those actions:

Rails.application.routes.draw do   root 'barcodes#index'   get '/barcodes/:symbology' => 'barcodes#generate' end 

the last thing to do is to create the actual UI for the Barcode Generator. Create a view in app/views/barcodes/index.html.erb with the following code:

<table border="0">   <tr>     <td colspan="2"><h2>Barcode Generator</h2></td>   </tr>   <tr>     <td><strong>Data:</strong></td>     <td><input name="data" id="data" value="Hello World" /></td>   </tr>   <tr>     <td><strong>Symbology:</strong></td>     <td>       <select name="symbology" id="symbology">         <option value="code128">Code 128</option>         <option value="datamatrix">Datamatrix</option>         <option value="code39">Code 39</option>         <option value="pdf417">PDF 417</option>       </select>      </td>   </tr>   <tr>     <td colspan="2" align="center"><button name="submit" id="submit">Generate Barcode</button></td>   </tr>   <tr>     <td colspan="2" align="center"><img src="" id="barcode_image"></td>   </tr> </table>  <script type="text/javascript">   $(document).ready(function() {     $('button#submit').on('click', function() {       $('img#barcode_image').attr('src', '/barcodes/' + $('select#symbology').val() + '?data=' + $('input#data').val());     })   }); </script> 

We simply create a form with a field for entering data and another for selecting the barcode symbology. When we click the ‘Generate Barcode’ button, we simply update the img tag’s src attribute with the relevent URL to generate our barcode image.

Now, let’s take it for a spin. Start (or restart) the server with rails s and visit http://localhost:3000 . We should see the form with Hello World already in the ‘Data’ field. Click the ‘Generate Barcode’ button and you’ll receive a freshly mintedl Code 128 barcode!

Generate Barcodes with JRuby and Barcodes4J

Change the symbology to ‘Datamatrix’ and click ‘Generate Barcode’ again. Now we should see a Datamatrix barcode. Here’s what it looks like:

Generate Barcodes with JRuby and Barcodes4J

Wrapping Up

Today we learned how to integrate and generate various types of barcodes using Barcode4J. We can improve the generator class by including more symbology specific parameters or more symbologies as well. But that I leave this as an exercise for you. I sincerely hope you liked the tutorial.

Comments and suggestions welcome, as always.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Generate Barcodes with JRuby and Barcodes4J

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址