ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Java print PDF

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Java print PDF

    I've been trying for a while to print PDF files natively. I tried using FTP, but it seems none of our printers know how to handle them. I tried the Ghostprint utility on the YiP's site, but it chokes on the graphic PDF's I need to print. Most recently, I stumbled on to pdfbox, which is a Java utility for handling PDF files. I wrote a little Java app using it and from my PC it works perfectly. Under IBMi, not so much. The PrinterJob.lookupPrintServices() method that's supposed to return a list of available printers returns an empty set running under IBMi. I tried using ISeriesPrintServiceLookup. That returned the printer, but the margins are off while printing.

    Any suggestions?

    Code:
    import java.awt.print.PrinterJob;
    import java.io.File;
    
    import javax.print.DocPrintJob;
    import javax.print.PrintService;
    
    import org.apache.pdfbox.pdmodel.PDDocument;
    import org.apache.pdfbox.pdmodel.PDPageable;
    
    import com.ibm.as400.access.AS400;
    import com.ibm.as400.javax.print.ISeriesPrintServiceLookup;
    
    public class PrintPDF {
    
    
        public static void main( String[] args ) throws Exception
        {
        	String nameOS = System.getProperty("os.name");
        	String pdfFilePath = null;
        	if (nameOS.equals("OS/400")) {
        		System.out.println("IBMi");
        		pdfFilePath = "/tmp/Test.PDF";
            	System.out.println(printPdfFile(pdfFilePath, getIbmPrinter("PRT_NAME")));    		
        	}
        	else {
        		System.out.println("WinTel");
        		pdfFilePath = "C:\\temp\\Test.PDF";
        		System.out.println(printPdfFile(pdfFilePath, getMsPrinter("PrinterName")));
        	}
        }
    
        public static String printPdfFile(String pdfFile, PrintService printer) {
           	PDDocument document = null;
          	
        	try {
        		//  get PDF
        		document = PDDocument.load( pdfFile );
        		
        		//  setup for printing
        		PrinterJob printJob = PrinterJob.getPrinterJob();
        		printJob.setJobName(new File(pdfFile).getName());
        		printJob.setPrintService(printer);
    			
    			//  print PDF
        		printJob.setPageable(new PDPageable(document, printJob));
                printJob.print();
                
                //  success
                return "0";
                
            }
        	catch (Exception e) {
        		e.printStackTrace();
        		return e.getMessage();
        	}
        	finally {
        		if (document != null) { document = null; }
        	}
        	
        } 
    	   
        private static PrintService getIbmPrinter(String printerName) {
    		AS400 ibmiSystem = null;
    		
    		//  find printer
    		ibmiSystem = new AS400();
    		ISeriesPrintServiceLookup ips = new ISeriesPrintServiceLookup(ibmiSystem);
    		PrintService[] services = ips.getPrintServices();
    		ibmiSystem = null;
    		ips = null;
    		for(int i = 0; i < services.length; i++) {
            	if(services[i].getName().indexOf(printerName) != -1) {
            		return services[i];
                }
    		}    
    				
    		return null;
        }
        
        private static PrintService getMsPrinter(String printerName) {
            javax.print.PrintService[] service = PrinterJob.lookupPrintServices(); 
            DocPrintJob docPrintJob=null;
            int count = service.length;
    
            for (int i = 0; i < count; i++) {
                    if (service[i].getName().equalsIgnoreCase(printerName)) {
                    docPrintJob = service[i].createPrintJob();
                    return docPrintJob.getPrintService();
                }
            }
            
            return null;
        }
    }

  • #2
    Re: Java print PDF

    No suggestions. A while back I too was looking for a way to print PDF's natively. I asked a Java programmer who works under IBM i if he had a Java routine that would print PDF's and he replied that he had been looking for something too but hadn't found anything suitable. This is one of those areas where IBM needs to help us.

    Comment


    • #3
      Re: Java print PDF

      Is it necessary to go through print-services? I ask because, if you don't mind just shooting your pdf to a specific output queue, it becomes a simple matter of slapping an InputStream on your pdf and piping it to a SpooledFileOutputStream. The following code--a modified version of an IBM example somewhere online--takes a random pdf from the internet and sends it to a 400 printer. I assume it would also do pdfs that live in the IFS, but haven't tested that. (The way it distinguishes local from web files is admittedly crude.) Also haven't tested with pdfs containing graphics. Change LEXT642 to the output queue of your choice if you want to see it run.

      Code:
      import java.io.FileInputStream;
      import java.io.InputStream;
      import java.net.URL;
      import java.net.URLConnection;
      
      import com.ibm.as400.access.AS400;
      import com.ibm.as400.access.OutputQueue;
      import com.ibm.as400.access.PrintObject;
      import com.ibm.as400.access.PrintParameterList;
      import com.ibm.as400.access.SpooledFileOutputStream;
      
      public class CreateSpooledFile
      {
      
      	private AS400 as400 = null;
      	private static final String DEFAULT_OUTQ = "/QSYS.LIB/QUSRSYS.LIB/";
      	private String strSystemName = null;
      	private String strUserID = null;
      	private String strPassword = null;
      	
      	public static void main(String args[])
      	{
      		final String JM_ONLINE_PDF ="http://www.cbu.edu.zm/downloads/pdf-sample.pdf";
      		final String JM_LOCAL_PDF ="/Users/username/Desktop/Coles DOKWAR 20150818.pdf";
      				
      		CreateSpooledFile splTest = new CreateSpooledFile(args[0], args[1], args[2]);
      		splTest.printPDF(JM_ONLINE_PDF, "LEXT642");
      		System.exit(0);
      	}
      
      	public CreateSpooledFile(String strSystemName, String strUserID, String strPassword)
      	{
      		this.strSystemName = strSystemName;
      		this.strUserID = strUserID;
      		this.strPassword = strPassword;
      	}
      
      	public void printPDF(String strInputFileName, String strOutputQueue)
      	{
      		as400 = new AS400(strSystemName, strUserID, strPassword);
      		OutputQueue outQ = new OutputQueue(as400, DEFAULT_OUTQ + strOutputQueue.toUpperCase() + ".OUTQ");
      		try
      		{
      			PrintParameterList parms = new PrintParameterList();
      			byte[] buf = new byte[2048];
      			int bytesRead;
      			if (strInputFileName == null)
      			{
      				System.exit(0);
      			}
      			parms.setParameter(PrintObject.ATTR_COPIES, 1);
      			parms.setParameter(PrintObject.ATTR_OUTPUT_QUEUE, outQ.getPath());
      			SpooledFileOutputStream osSpool = new SpooledFileOutputStream(as400, parms, null, null);
      			InputStream fisPDF = null;
      			if (strInputFileName.toLowerCase().indexOf("http") == 0)
      			{
      				URL url = new URL(strInputFileName);
      				URLConnection urlConnect = url.openConnection();
      				if (urlConnect.getContentType().equalsIgnoreCase("application/pdf"))
      				{
      					fisPDF = url.openStream();
      				}
      			}
      			else
      			{
      				fisPDF = new FileInputStream(strInputFileName);
      			}
      			do
      			{
      				bytesRead = fisPDF.read(buf);
      				if (bytesRead != -1)
      				{
      					osSpool.write(buf, 0, bytesRead);
      				}
      			}
      			while (bytesRead != -1);
      			osSpool.flush();
      			osSpool.close();
      			fisPDF.close();
      
      		}
      		catch (Exception e)
      		{
      			// Handle error. 
      			System.out.println("Exception occured while creating the spooled file.");
      			System.out.println(e);
      		}
      	}
      
      }

      Comment


      • #4
        Re: Java print PDF

        Footnote: setting ATTR_PRINTER in the parameter list should get you to a specific printer device.

        Comment


        • #5
          Re: Java print PDF

          That code sends the raw PDF to the printer (same as FTP). I don't have a printer that will accept raw PDF files.

          Comment


          • #6
            Re: Java print PDF

            Let me know if you ever find a solution... we had been using PRTSTMF utility to send PDFs directly to HP printers. This worked until the vendor changed the way they produce PDFs - the HP Printers ceased to understand the raw PDF data.

            Comment

            Working...
            X