Monday, November 04, 2019

PL/ZPL: Printing to Zebra Printers from PL/SQL




  This requires a little background.  For a while now I have been interested in getting APEX to print directly to a Zebra Printer.  Now there are a few printing solutions available to APEX and I dare not compare to those but in my primary field of Asset Management we always have a need for direct printing to a very specialized set of devices; namely Zebra Printers.
  A year ago I found my first solution, and it’s pretty ugly for me and I wasn’t really secure in publishing it since it has its own issues.  In the last few days I had occasion to revisit the solution and try again.  Time has the benefit of perspective and so I have another solution as well, yet not the one I was looking for.
  Those who know me, know that APEX is not my primary skillset.  I’m passionate about it but in my daily life IBM Maximo pays the bills.  Within this system in recent version came an ability to script some components via Javascript and or Python (in the form of the Jython library).  So I was looking originally for a way to print these labels from Maximo using this type of scripting and have mostly found the solution, and might have a final once IBM finishes troubleshooting a python issue I keep running up against. 
  To compensate for this I set up a VM with Oracle XE and created a patch solution using PL/SQL triggered Python to send ZPL2 code to the printers to get results.  Now I dislike using more disparate tech than required to get the job done but at the time this was it.  I came back to this solution and had a minute to do some thinking and had an idea.  Research showed me that Oracle had a package that did similar work to the Python “socket” module, which is my current issue in Maximo.  What this knowledge did do is provide a super simple solution to my complex problem for Oracle and APEX.  I ran with it and today had a stunningly fast printing of my example tags. 
  This solution takes a lot from other’s work and twists it to my goal and I will try to give credit where credit is due. 
  The first task is to get the ZPL code for the label to be able to print it.  I have always preferred to not write my own ZPL since it 1500 page reference should speak for itself on how complex it can get.  Instead I use the Zebra Designer and then print the design to a file and then just grabbing the ZPL code to be used.  The gif below shows that export.
 Now that you have the ZPL, you have to get it to the printer.
PL/SQL-Batch-Python-ZPL Printing
  Ugh!  Just looking at that string is hard.
  From Oracle it is possible to trigger a python script from pl/sql through DBMS_SCHEDULER.  From there the job triggers a .CMD, .BAT, .SH (for unix) which triggers the python script to do the work.  There is less explanation here than there code I am releasing on gitlab to let you see how it’s done.
  Essentially the package has a set of DBMS_SCHEDULER creation procedures that use some metadata tables to send parameters to the python script that does the printer communication.  It’s ugly but effective.
PL/SQL-ZPL Printing
  This solution came down to a single line in the python documentation here: https://docs.python.org/3/library/socket.html “module provides access to the BSD socket interface”
  From there I searched for BSD Oracle and came to the ‘Pavan’ archive article on UTL_TCP. 
  The solution presented here takes this example directly and twists it slightly to do what I was doing in the Python script.  
  At the end of all this I found a better solution than I originally had and this one really looks like it can help.  If you are interested grab it, add it to your toolset and get back to work. 

  As a final note this blog is titled "Precision Guesswork".  If what you see here isn't pretty that's why.

Cheers!

Resources:
Labelary (great place to see ZPL results and to tweak your labels)

Zebra Designer (demo Licenses can be acquired here)

ZPLII (The great big book of everything)


python Docs (socket) (Where this tangent started)

utl_tcp (credit where it is due)

2 comments:

Thoughts, Questions, Comments, Snide Remarks , Good Jokes?