my barcode4j on grails’s jasper plugin

Here are my details step to integrate barcode system (barcode4j) to grails barcode plugin:

  • create maven project on netbeans using the quicktype archetypeserch
  • get the groupid for barcode4j from http://mvnrepository.com/
  • than add library for the project by right click on project libraries and fill the groupid. Version field are autocomplete, so choose latest version and press ok
  • Then on the project libraries we will find bracode4j and it dependenciessince i never user barcode4j before, then on my libraries i got negative mark on barcode4j item which mean I didn’t have it on my local collection, than right click on the libraries and choose ‘download all libraries’.
  • on app.java i fill these code:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import org.krysalis.barcode4j.impl.code39.Code39Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.UnitConv;

public class App
{
    public static void main( String[] args )
    {
		try{
			Code39Bean bean = new Code39Bean();
			final int dpi = 150;

			bean.setModuleWidth(UnitConv.in2mm(1.0f/dpi));
			bean.setFontSize(1.8);
			bean.setBarHeight(4);
			bean.doQuietZone(true);
			File outputFile = new File("out.jpg");
            OutputStream out = new FileOutputStream(outputFile);
			try{
				BitmapCanvasProvider canvas = new BitmapCanvasProvider(out, "image/jpeg", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);
				bean.generateBarcode(canvas, "2WMFG79-7-7-8");
				canvas.finish();
			}
			finally{
				out.close();
			}
		} catch (Exception e){
			e.printStackTrace();
		}
	}
}
  • and after run the file i got out.jpg file which contain barcode image. So I already got all needed libraries and on the right track ….
  • than to make it work with jasper report I need scriptlet which generate barcode image for given field
  • here is my Scriptlet.java and add jasperreports library before wite it
import java.awt.image.BufferedImage;

import net.sf.jasperreports.engine.JRDefaultScriptlet;
import net.sf.jasperreports.engine.JRScriptletException;

import org.krysalis.barcode4j.impl.code39.Code39Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
import org.krysalis.barcode4j.tools.UnitConv;

public class Scriptlet extends JRDefaultScriptlet{

	public BufferedImage generateBarcode1() throws JRScriptletException{
		String value = (String) this.getFieldValue("bookName");
		BufferedImage barcodeImg = null;
		Code39Bean bean = new Code39Bean();
		final int dpi = 300;
		bean.setModuleWidth(UnitConv.in2mm(0.5f/dpi));
		bean.doQuietZone(true);
		bean.setFontSize(1.4);
		bean.setBarHeight(2);
		bean.doQuietZone(false);
		try {
			BitmapCanvasProvider provider = new BitmapCanvasProvider(dpi, BufferedImage.TYPE_BYTE_GRAY, true, 0);
			bean.generateBarcode(provider, value);
			provider.finish();
			barcodeImg = provider.getBufferedImage();
		} catch (Exception e) {
		}
		return barcodeImg;
	}

}

and here is my jrxml file:

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report name" columnCount="3" printOrder="Horizontal" pageWidth="595" pageHeight="842" columnWidth="185" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" scriptletClass="Scriptlet">
    <queryString>
        <![CDATA[]]>
    </queryString>
    <field name="id" class="java.lang.Long"/>
    <field name="version" class="java.lang.Long"/>
    <field name="bookName" class="java.lang.String"/>
    <field name="description" class="java.lang.String"/>
    <background>
        <band/>
    </background>
    <title>
        <band height="79">
            <staticText>
                <reportElement stretchType="RelativeToBandHeight" mode="Transparent" x="121" y="0" width="434" height="79"/>
                <textElement textAlignment="Center" verticalAlignment="Middle">
                    <font size="30" isBold="true"/>
                </textElement>
                <text><![CDATA[Generated Tags]]></text>
            </staticText>
            <image hyperlinkType="None">
                <reportElement x="0" y="0" width="135" height="79"/>
            </image>
        </band>
    </title>
    <columnHeader>
        <band height="22"/>
    </columnHeader>
    <detail>
        <band height="50">
            <image scaleImage="Clip" hAlign="Center" vAlign="Middle" isUsingCache="true" onErrorType="Blank" hyperlinkType="None">
                <reportElement x="0" y="0" width="184" height="38"/>
                <imageExpression class="java.awt.Image"><![CDATA[$P{REPORT_SCRIPTLET}.generateBarcode1()]]></imageExpression>
            </image>
        </band>
    </detail>
    <columnFooter>
        <band height="24"/>
    </columnFooter>
</jasperReport>

for working with grails’s jasper plugins make sure to remove field description and the name space just like code above (in one declaration, don’t use ireport user interface to add scriptlet class)
than put all library on grails lib and put scriptlet code on scriptlet src/java
and it worked …

This write on netbeans 6.5, grails 1.0.5-SNAPSHOT, jasper plugin 0.9 and iReport 3.1.2
and here are the library which given by maven for my code:

avalon-framework-4.1.4.jar       itext-2.1.0.jar
avalon-framework-impl-4.2.0.jar  jasperreports-3.1.2.jar
barcode4j-2.0.jar                jcommon-1.0.12.jar
bcmail-jdk14-136.jar             jdtcore-3.1.0.jar
bcprov-jdk14-136.jar             jfreechart-1.0.9.jar
commons-beanutils-1.7.0.jar      junit-3.8.1.jar
commons-collections-2.1.jar      postgresql-8.3-604.jdbc4.jar
commons-digester-1.7.jar         xml-apis-1.3.04.jar
commons-logging-1.0.3.jar


my searchable on grails

Within grails, Book class-domain is very common used as sample. And here is my simple implementation of searchable plugin on Book class-domain:

Book.groovy

class Book {

String bookName
Date release
String description

static Searchable = true

}

BookController.groovy

def search = {

   def bookInstanceList
    def searchResult
    if (params.query) {
        searchResult = Book.search('*'+params.query+'*')
        bookInstanceList = searchResult.results
    }
    else
        bookInstanceList = Book.list()
    render(view:'list', model:[bookInstanceList:bookInstanceList, searchResult:searchResult, query:params.query])
}

List view

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <meta name="layout" content="main" />
        <title>Book List</title>
    </head>
    <body>
        <div class="nav">
            <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span>
            <span class="menuButton"><g:link class="create" action="create">New Book</g:link></span>
        </div>
        <div class="body">
            <h1>Book List</h1>
            <g:if test="${flash.message}">
                <div class="message">${flash.message}</div>
            </g:if>
            <div class="list">
                <div class="nav">
                    <g:form name="search" action="search">
                        search: <input type="text" name="query" value="${query}"/>
                        <input type="submit" value="search">
                    </g:form>
                </div>
                <table>
                    <thead>
                        <tr>
                            <g:sortableColumn property="id" title="Id" />
                            <g:sortableColumn property="bookName" title="Book Name" />
                            <g:sortableColumn property="description" title="Description" />
                            <g:sortableColumn property="release" title="Release" />
                        </tr>
                    </thead>
                    <tbody>
                        <g:each in="${bookInstanceList}" status="i" var="bookInstance">
                            <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
                                <td><g:link action="show" id="${bookInstance.id}">${fieldValue(bean:bookInstance, field:'id')}</g:link></td>
                                <td>${fieldValue(bean:bookInstance, field:'bookName')}</td>
                                <td>${fieldValue(bean:bookInstance, field:'description')}</td>
                                <td>${fieldValue(bean:bookInstance, field:'release')}</td>
                            </tr>
                        </g:each>
                    </tbody>
                </table>
            </div>
            <div class="paginateButtons">
                <g:if test="${searchResult}">
                    <g:paginate total="${searchResult.total}" params="[    query:query]"/>
                </g:if>
                <g:else>
                    <g:paginate total="${Book.count()}" />
                </g:else>
            </div>
        </div>
    </body>
</html>

and here is the shoot:

searchable plugin on book domain-class

searchable plugin on book domain-class

The search criteria above is based on word match, for more details about more search criteria or all features on grails searchable please see the documentation on grails plugins site