Tuesday, October 5, 2010

QRcodes in SAP transactions with a Zebra Crossing (ZXing) Part 1

Following up to my post on QRcodes in smartforms and sapscript which can be found here

Ever since coming across a QR code in my passport I have wanted to integrate them into SAP. I like the idea of a "quick response" of data into a mobile device as I hate typing on mobile phones. Now this is a technical solution and a demonstration of using QR codes in an ABAP transaction. The solution requires a SAP system with a java stack. The QR codes can generated and used in any web application or custom ABAP transaction. No need to rely on external web sites to generate the codes.

If your still unsure about QR codes, then try the wikipedia link
Or download The Weather Channel Android App from TV!

I am more of an system administrator/integrator than a developer so I found,
*) a Zebra crossing to do the actual QR code generation, ZXing (Zebra Crossing) (later versions now exist than the one I use)
*) the custom ABAP code is based on SAP program "SAPHTML_DEMO1"
*) GuiXT is used to link standard SAP transactions to the custom code.

The purpose of the ABAP transaction is to map the location of any customer/contact and provide a "quick response" of the map url to a mobile phone via the QR code. I made some attempts to use vCard and MEcard formats to send contact details via QR codes. However from my experience the actual applications that scan QR codes vary widely in their adoption of formats for contact information. So here I will just focus on URL's for mapping a customer's location.


So first things first we need the QR code and to get it I made a journey into the world of Java/JSP/servlets and the SAP Java engine.

To get to my Zebra Crossing I had to use an Ant. So after a trip to Apache Ant I managed to build the key component of ZXing "core" I needed. The getting started section at the ZXing website is here. Within the ZXing "core" component is the base QR code used to generate the QR code in for my ABAP transaction. ZXing has many options/sections and platforms but all I needed was the core component to generate the QR code as I was not going to decode/scan anything.

Now as stated previously I am not a developer so I needed some clues in how to use my newly aquired core.jar file. Now searching the web provided so many options that it took some time to actually get to a working version.

Java images: JSP vs Servlet

Now I had for a long time a working version based purely in JSP. There are many examples "out there" where the image is done via pure JSP. Now this works however in the SAP java engine a warning message about output streams is generated. So checking further into the information available and the way forward was to split the actual image generation into a servlet.

With the SAP Netweaver Developer Studio I built the following into an application.

To get started with the NWDS I used this SDN blog. For this application I did not follow the authorisation part in the blog as this service is for anyone to use (anonymous user).

I am not a Java developer so I needed some help to get started and complete the process.

So I found on the web,
getting started: - initial start to the QRCodeWriter.java in ZXing here
Help splitting the code into a JSP and Servlet:- SAP note 1218520

JSP (at last I found somewhere that lets me format code to cut n paste into blogger)

<%@ page language="java" %>
<%response.sendRedirect( "/QRplutus/servlet/QRimg?" + request.getQueryString());


package servlet;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.zxing.*;
import com.google.zxing.common.ByteMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
public class QRimg extends HttpServlet {
protected void doGet(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String pw = request.getParameter ("w");
String ph = request.getParameter ("h");
int width;
int height;
if ( pw == null ) {
width = 200;
width = Integer.parseInt(pw);
if ( ph == null ) {
height = 200;
height = Integer.parseInt(ph);
String text = request.getParameter ("t");
if ( text == null ) {
text = "**ERROR No text passed to encode";
QRCodeWriter writer = new QRCodeWriter();
ByteMatrix matrix = null;
try {
matrix = writer.encode(text, BarcodeFormat.QR_CODE, width, height);
} catch (WriterException e) {
// TODO Auto-generated catch block
byte[][] matrixByte = matrix.getArray();
BufferedImage bimg = new BufferedImage(width,height,BufferedImage.TYPE_BYTE_GRAY);
byte[] linearbuffer = new byte[width*height];
int i=0;
for(int y=0;y<height;y++)
for(int x=0;x<width;x++)
bimg.getRaster().setDataElements(0, 0, width, height, linearbuffer);
ImageIO.write(bimg, "jpeg", response.getOutputStream());

JSP & Servlet can be found here text file can be downloaded which contains the above code.

To generate the QR code, once deployed, then the following url can be used based on the above example.


Obviously hostname is the hostname of the SAP server
5xx00 should match the instance number of the SAP java engine, e.g. 50000
t= is the text to encode
w= and h= control the height and width of the QR code.

You can find the whole SAP EAR file here, which you could deploy to a SAP java engine via SDM install tool.
End of part One,

Link to part Two will appear later..........

Monday, October 4, 2010

Solaris: printing postscript on modern networked HP printers

My first attempts at using the Barcode Writer In Pure Postscript involved a unix script and direct printing on networked HP printers.

While the Unix scripts will be dusted off soon, the postscript file printing to HP printers is documented here.

I am fairly used to creating standard HP print queues in Solaris for SAP printing, however as my interest was in postscript I wanted a simple way to print postscript output. Unix printing is covered in great detail on the web and openprinting.org is the way to go to set it up properly.

However I like to keep things as simple as possible.

I still need to do more investigation as to why "low level postscript" is accepted on HP printers and the future of print device pswrite in ghostscript is unclear to me.

However my simple approach was to basically print postscript files to our office jetdirect HP printers using one common print filter/device pswrite in ghostscript

1) Create a printer

lpadmin -p {printer name} -v /dev/null -m netstandard -o dest={IP address}:9100 -o protocol=tcp -o banner=never -T PS -I postscript

2) Use pswrite as the Ghostscript DEVICE option

Edit file /etc/lp/interfaces/{printer name} and change the following lines

if [ -z "${FILTER}" ]

Change to a one liner

FILTER="/usr/sfw/bin/gs -q -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pswrite -sOutputFile=- -"

enable print_queue
accept print_queue

Set the printer up in SAP and BWIPP device type can now print directly to HP printers.....

The same standard filter works for our HP office printers, a colour HP LaserJet 4700 and black and white HP LaserJet 4250.

Google +