Link to home
Start Free TrialLog in
Avatar of Andrew Matondo
Andrew Matondo

asked on

How to programatically spool a PCL file to an iSeries AS400 OutQ using jt400 sdk?

How does one spool a pcl file to an iSeries As400 server using the jt400 java sdk. I can spool a text file to an as400 outq ok and it prints ok.
a pcl file prints gibberish.

My program runs on a Windows 7 workstation.

Some working code snippets would help in java or .net would be very useful.
Avatar of Gary Patterson, CISSP
Gary Patterson, CISSP
Flag of United States of America image

The AS/400 doesn't "speak" PCL.  When you want to attach a PCL printer to the AS/400, you typically use a feature called "Host Print Transform" to convert native AS/400 SCS documents to PCL.  By configuring a 3812 device description with TRANSFORM(*YES) and specifying a transform object that contains the right conversion tables for your specific printer.  Or you can configure a remote OUTQ in the same fashion - that's a common way to do it with LAN attached printers.

So when you send text, most likely the text is getting converted from Unicode to EBCDIC and printed as a SCS spooled file.  The SCS spooled file gets picked up by host print transform, converted to PCL, and it prints properly.

If you are dealing with a PCL printer, I don't know why you want to try to push the document through the IBM i print stack - it really isn't intended for that and you are going to have to take some steps to avoid the normal output concersion that are done when dealing with a PCL printer.  Why not just print directly to the printer  assuming it is LAN-attached - or to a Windows server that has a queue for the printer?

Anyway, if none of those are an option:  In order to directly print "through" without a bunch of conversion and transform happening, I'd suggest that you create a printer file defined as *USERASCIII (CRTPRTF DEVTYPE(*USERASCII)) and then use that printer file when you create a SpooledFileOutputStream in Java.   Make sure you pass the PCL as ASCIi and not Unicode.

*USERASCII tells the IBM i OS that you know what you are doing - you've already formatted the print stream in PCL, and you want the OS to leave it alone and just pass it to the printer intact.

Maybe if you provided a little more explanation of what you want to accomplish I could give you a better answer.
Avatar of Andrew Matondo
Andrew Matondo

ASKER

Super explanation can I add some code snippet below
Going thru the queue allows holding and reprints and redirection to other PCL printers if needed without changing every workstation.

This works very well for normal text files and prints ok and even preview on the green screen

private static SpooledFile createSpooledFile(AS400 system, string outQName, string fileData, bool hold, bool save)
        {
            SpooledFile spooledFile = null;

            PrintParameterList parms = new PrintParameterList();

           
            parms.setParameter(PrintObject.ATTR_COPIES, 1);

            var outputQueue = new OutputQueue(system, outQName);
            parms.setParameter(PrintObject.ATTR_OUTPUT_QUEUE, outputQueue.getPath());

            parms.setParameter(PrintObject.ATTR_HOLD, hold ? "*YES" : "*NO");
            parms.setParameter(PrintObject.ATTR_SAVE, save ? "*YES" : "*NO");
            parms.setParameter(PrintObject.ATTR_MEASMETHOD, "*ROWCOL");
            parms.setParameter(PrintObject.ATTR_PAGELEN, 66f);
            parms.setParameter(PrintObject.ATTR_PAGEWIDTH, 132f);
            
            parms.setParameter(PrintObject.ATTR_SPOOLFILE, string.Format("FISC{0:HHmmss}", DateTime.Now));
            
            var outputStream = new SpooledFileOutputStream(system, parms, null, null);


            //Create an SCS writer to create the records.
            var scsWtr = new SCS5553Writer(outputStream, 37, system);
            scsWtr.write(fileData);
            scsWtr.close();

            
            spooledFile = outputStream.getSpooledFile();
            

            return spooledFile;
        }

Open in new window


But this does not work for PCL files and prints gibberish this code below is what I want to be fixed.
private static SpooledFile createBinarySpooledFile(AS400 system, string outQName, string fileData, bool hold, bool save)
        {
            SpooledFile spooledFile = null;          

            PrintParameterList parms = new PrintParameterList();

           
            parms.setParameter(PrintObject.ATTR_COPIES, 1);

            var outputQueue = new OutputQueue(system, outQName);
            parms.setParameter(PrintObject.ATTR_OUTPUT_QUEUE, outputQueue.getPath());

            parms.setParameter(PrintObject.ATTR_HOLD, hold ? "*YES" : "*NO");
            parms.setParameter(PrintObject.ATTR_SAVE, save ? "*YES" : "*NO");
            
            parms.setParameter(PrintObject.ATTR_PRTDEVTYPE, "*USERASCII");

            parms.setParameter(PrintObject.ATTR_ALWDRTPRT, "*YES");            
            parms.setParameter(PrintObject.ATTR_CONVERT_LINEDATA, "*NO");            
            parms.setParameter(PrintObject.ATTR_RPLUNPRT, "*NO");

            parms.setParameter(PrintObject.ATTR_PAGES, 1);
            parms.setParameter(PrintObject.ATTR_SCS2ASCII, "*NO");
           
            parms.setParameter(PrintObject.ATTR_SPOOLFILE, string.Format("FISC{0:HHmmss}", DateTime.Now));
                  
            var outputStream = new SpooledFileOutputStream(system, parms, null, null);
            
            outputStream.write(Encoding.UTF8.GetBytes(fileData));
            outputStream.close();

            spooledFile = outputStream.getSpooledFile();


            return spooledFile;
        }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Gary Patterson, CISSP
Gary Patterson, CISSP
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for the follow up. Please find the fileData = "XX.pcl.txt" and the hex dump and
the results of the conversion = "xx.hex.txt" as a hex dump

My AS400 as pre version 7 so I can not get the copy of the spooled file but here the code I added to get a copy via my code
           var cpy = spooledFile.copy();
            var inputStream = cpy.getInputStream();
            var count = inputStream.read(bData);
            inputStream.close();

Open in new window

CreditApplication.hex.txt
CreditApplication.pcl.txt
CreditApplication.Copy.hex.txt
Just for background information (I have no knowledge of AS/400), the .pcl file  (analysis attached) contains valid PJL | PCL | HP-GL/2 (and this appears, as expected,  to match the original .hex analysis).

The copy .hex file is shorter than the original .hex file, but I don't know what all the differences are.

The first difference, at displacement  0x1ed8, is that (within a PCL binary download character sequence), the original 0x3f3f3f3f3f is one-byte shorter (i.e. one of the 0x3f bytes has been removed in the 'copy').

This will mean that (at least) the character download for this character will be corrupted, with other possible follow-on corruptions; so this would explain your 'garbage' output.

I suspect that Gary Patterson is correct in surmising that this is a problem related to encoding; bear in mind that the bytes in the PCL job can be ANY value, including <NUL> (0x00), and you don't want to modify any of them, nor insert or remove any bytes.
CreditApplication.pcl-analysis.txt
Thanks guys for the pointers and I have now fixed it given hints by Gary Paterson.

I have now changed my code like so

private static SpooledFile createBinarySpooledFile(AS400 system, string outQName, byte[] fileData, bool hold, bool save)

Open in new window


this avoids the conversion/encoding line and I now load the input file as binary not as string as I was doing previously before calling the above function. And all 3 files now match(identical).

I will give Gary partial marks for his efforts.
CreditApplication.hex.txt