Crimson Solutions - Net.Data, RPG, RPGLE, software testing Crimson Solutions - Net.Data, RPG, RPGLE, software testing Crimson Solutions - Net.Data, RPG, RPGLE, software testing

AS400 PCL Printing

This is one man's explanation of how to implement advanced printer functionality on your AS400 without the need to buy AFP or special printers. You can use just a basic printer - I've used a HP deskjet - running as a SCS printer under TCP/IP to perform the actions below. This article assumes that you know how to set up such a printer, and have already done so.
The areas covered in this examples are just the basics for changing font, aligning column position, etc. Note that this article is intended for technical AS400 people, and the examples given cover the usage within DDS and RPG.

What is this PCL printing then ?

PCL is the printing language used by HP printers, and many others. When you print to your laserjet or deskjet from windows, the text, images, fonts etc are converted by the printer driver into a language format that the printer can understand. Even when printing from your AS400 via a remotely attached TCP/IP writer, the AS400 itself via the device type does the conversion for you.

so why do you need to learn it ? Well, the AS400 without AFP on a SCS printer implements only a standard set of instructions. Things like mixing fonts on a page, drawing boxes, etc are just not implemented. So, we can send PCL commands direct to the printer, without translation by the AS400, to achieve some of these goals.

How do I send codes to a PCL printer from my AS400 ?

IBM conveniently provide a mechanism to send data directly to a printer via DDS, using the keyword TRNSPY. This sends a byte string without alteration through to the printer. You can "conveniently" send this in the form of a hex string, an example of this is below:

A* Reset all - <ESC>E                                               
A                                  1  1DFT(X'1B45') TRNSPY        

We've also learned out first PCL command, "Reset all". PCL defines this command as being made up of the escape key followed by a capital E. Looking these codes up in our ASCII table reference we see that the escape key is 1Bh and the letter capital E is 45h. So, by use of the TRNSPY keyword, we send these bytes of to the printer.

Obviously "Reset all" is just an instruction to prepare the printer for what we really want. So let's try a more interesting example, setting the margin. This is more interesting in that we also get to send the printer a numeric value of our choice - a "variable" so to speak, although in our code this will be hard coded. Let's set a top margin of 1, meaning 1/10 of an inch. The format for sending a "set top margin" command is as follows:
Again, the code starts with the escape character. The ampersand and lower case letter L signify the instruction "set the top margin". The number 1 is the value, and the letter E in this case is the terminator for the instruction. All we need to do now is convert these value byte for byte using the ascii table and substitute into the hex string sent to the printer, like this.
A* Set Top Margin to 1 - <ESC>&l1E                              
A                                  1  1DFT(X'1B266C3145') TRNSPY

So what other codes are there ?

In short, loads, of which I have only used a few, as my needs were few. For my project I needed to specify a proportional font, some margins, some column positioning (to correspond with the pre-printed form I was using and that's about it really. So, following now is the full code I used for the record format that initialised the printer.

A          R PCLSTART                                             
A* Reset all - <ESC>E                                             
A                                  1  1DFT(X'1B45') TRNSPY        
A* set to A4 - <ESC>&l26A                                         
A                                  1  1DFT(X'1B266C323641') TRNSPY
A* Set to Portrait - <ESC>&l0O                                    
A                                  1  1DFT(X'1B266C304F') TRNSPY  
A* Set Top Margin to 1 - <ESC>&l1E                                
A                                  1  1DFT(X'1B266C3145') TRNSPY  
A* Set font to arial - <ESC>(s16602T                              
A                                  1  1DFT(X'1B2873313636303254') 
A                                      TRNSPY                     
A* Set font size to 12 - <ESC>&k4S                                
A                                  1  1DFT(X'1B266B3453') TRNSPY  
A* Set font spacing to proportional - <ESC>(s1P                   
A                                  1  1DFT(X'1B28733150') TRNSPY  

Having setup the page defaults, I then used the column positioning PCL commands to get my text in exactly the right place on the page. The command is <ESC>*p, followed by the number of units across, followed by a capital X. For my needs I needed 100 units, so the DDS looked like this. Note the use of the PCL before the normal DDS, and also the use of "+ 1" for the field position.

A* Set horizontal cursor position - <ESC>*p100X                      
A                                    01DFT(X'1B2A7031303058') TRNSPY 
A            MYFIELD       70       + 1SPACEA(1) 

It's also a good idea to finish the printing with another reset command, ie <ESC>E. I set up a separate record format for this in the DDS

A          R PCLEND                                       
A* Reset all - <ESC>E                                     
A                                 65 80DFT(X'1B45') TRNSPY

PCL Reference material

HP have produced some very useful PCL reference material in the form of a 2-part PDF guide. You can download the guide in two parts from hp. Here is the HP PCL5 Programmer's guide pt1, and here is part two.

This article was submitted by me, Vince Lewis. I hope that the hints and tips above prove useful to you

© 2005 Crimson Solutions