21 September, 2012

Oracle Forms : Print Report Directly

Usually we display Oracle Reports in Oracle Forms in PDF format and then the user print it through Adobe Reader  program or any other  PDF reader program.

But the requirement is to print Oracle Report directly without  displaying the report at screen.

To achieve this requirement in Oracle Forms 6i it is easy as you you set DESTTYPE parameter in report file to PRINTER and It will work correctly, But this feature not work with Oracle Forms 10g.

Some developers use java bean for this purpose but I will produce the below workaround to print report directly without using java bean.
1- Run Report and save it as PDF file at application server.
    I will share folder c:\temp at application server for everyone for read only and save reports PDF files in this folder. The share path of the folder is \\ApplicationServer_IP\Temp\
2- Silent Print of PDF file at user machine using PDF reader programs like Adobe Reader
3- Close PDF reader program after printing.

Some Developers may use ORARRP utility and do its required configuration at server and client machine for direct printing too.
Procedure Code
I create Procedure (Program Unit) in Oracle Forms to do the previous steps

 PROCEDURE PRINT_DRIRECTLY (IN_SERVER_NAME  VARCHAR2,  
               IN_REP_NAME    VARCHAR2,  
               IN_OBJ_NAME    VARCHAR2)  
 IS  
   LC$REP            VARCHAR2 (100);  
   LC$REP_STATUS     VARCHAR2 (20);  
   LC$LN$ADOBE_PATH  VARCHAR2 (500);  
   LN$PROCESS_ID     WEBUTIL_HOST.PROCESS_ID;
   REPID             REPORT_OBJECT;  
   LC$FILE_PATH      VARCHAR2 (1024);  
   LC$TEMP_PATH CONSTANT VARCHAR2 (256)  
      := '\\ApplicationServer_IP\Temp\' ;  
 BEGIN  
   LC$FILE_PATH := LC$TEMP_PATH || 'ReportName.pdf';  
   REPID := FIND_REPORT_OBJECT (IN_OBJ_NAME);  
   
   SET_REPORT_OBJECT_PROPERTY (REPID, REPORT_FILENAME, IN_REP_NAME);  
   
   SET_REPORT_OBJECT_PROPERTY (REPID, REPORT_SERVER, IN_SERVER_NAME);  
   
   SET_REPORT_OBJECT_PROPERTY (REPID, REPORT_EXECUTION_MODE, BATCH);  
   
   SET_REPORT_OBJECT_PROPERTY (REPID, REPORT_COMM_MODE, SYNCHRONOUS);  
   
   SET_REPORT_OBJECT_PROPERTY (REPID, REPORT_DESTYPE, FILE);  
   
   --File name must be unique otherwise it will override the old file with same name  
   
   SET_REPORT_OBJECT_PROPERTY (REPID, REPORT_DESNAME, LC$FILE_PATH);  
   
   SET_REPORT_OBJECT_PROPERTY (REPID, REPORT_DESFORMAT, 'pdf');  
   
   LC$REP := RUN_REPORT_OBJECT (REPID);  
   
   LC$REP_STATUS := REPORT_OBJECT_STATUS (LC$REP);  
   
   WHILE LC$REP_STATUS IN ('RUNNING', 'OPENING_REPORT', 'ENQUEUED')  
   LOOP  
    LC$REP_STATUS := REPORT_OBJECT_STATUS (LC$REP);  
   END LOOP;  
   
   IF LC$REP_STATUS = 'FINISHED'  
   THEN  
    IF WEBUTIL_FILE_TRANSFER.IS_AS_READABLE (LC$FILE_PATH)  
    THEN  
      -- Try to get the correct instaled version of Adobe Reader program  
   
      FOR I IN REVERSE 5 .. 13  
      LOOP  
       BEGIN  
         LC$LN$ADOBE_PATH :=  
          CLIENT_WIN_API_ENVIRONMENT.  
          READ_REGISTRY (  
             'HKEY_LOCAL_MACHINE\SOFTWARE\Adobe\Acrobat Reader\'  
            || I  
            || '.0\Installer',  
            'Path',  
            TRUE);  
       EXCEPTION  
         WHEN NO_DATA_FOUND  
         THEN  
          --If path not exists in Registery, it will raise NO_DATA_FOUND EXCEPTION  
   
          NULL;  
       END;  
   
       IF LC$LN$ADOBE_PATH IS NOT NULL  
       THEN  
         EXIT;  
       END IF;  
      END LOOP;  
   
      BEGIN  
       LN$PROCESS_ID :=  
         WEBUTIL_HOST.  
         NONBLOCKING (  
            '"'  
          || LC$LN$ADOBE_PATH  
          || 'Reader\AcroRd32.exe" /H /P '  
          || LC$FILE_PATH);  
      EXCEPTION  
       WHEN OTHERS  
       THEN  
         NULL;  
      END;  
   
      --sleep for sometime until printing is finished  
   
      DBMS_LOCK.SLEEP (3);  
   
      -- Teminate Adobe Reader Program Process  
   
      IF NOT WEBUTIL_HOST.ID_NULL (LN$PROCESS_ID)  
      THEN  
       WEBUTIL_HOST.TERMINATE_PROCESS (LN$PROCESS_ID);  
      END IF;  
    ELSE  
      MESSAGE (
            LC$FILE_PATH || ' is unreadable path at application server');
    END IF;  
   END IF;  
 END PRINT_DRIRECTLY;  

Use Guidelines
1- You pass three parameters to procedure
     a- IN_SERVER_NAME  : Report service name
     b- IN_REP_NAME : physical file path of report file (rdf , rep files)
     c- IN_OBJ_NAME : Report object name in your form

2- I expect that the installed program at client machine is Adobe reader if there are another program you use, then you should modify the code in below lines

LN$PROCESS_ID :=  
         WEBUTIL_HOST.  
         NONBLOCKING (  
            '"'  
          || LC$LN$ADOBE_PATH  
          || 'Reader\AcroRd32.exe" /H /P '  
          || LC$FILE_PATH);  

3- You should make report file name (Generated PDF file after running report) unique over the application, You should modify the below code to make it unique.

 LC$FILE_PATH := LC$TEMP_PATH || 'ReportName.pdf';  


Thanks
Mahmoud A. El-Sayed

11 comments:

  1. There is another easy way to print Report directly
    we needn't to use pdf anyway for print directly.
    and destype paramter exists in oracle reports 10g
    I use web.show_document command
    and define destype=printer and desname=printername.

    However ,
    thank you for your efforts

    ReplyDelete
    Replies
    1. web.show_document is not safe because you display report parameters in URL

      Delete
    2. There is a way to hide the parameters in URL

      Delete
    3. you cant hide URL parameters in web.show_document

      Delete
  2. hello Mr.Mahmoud
    i have system Point of Sale i need to print direct, this method is correct if system is local , but my system is publish on web and i have more branch connected whit system !!!

    ReplyDelete
  3. Hi Mahmoud,

    Will the report print goes to user default printer or to network printer as the 10g AS are running on web. If it goes directly to users default printer which was specially assigned to him to print invoice directly on his printer instead of network printer. I shall be very grateful if u answer this.

    ReplyDelete
  4. Very Very Good, Excellent, far far better than using 'ORARRP'.

    ReplyDelete
  5. Can I get fmb file ?
    reaz62@yahoo.com is my mail ID

    ReplyDelete
  6. Hi Mahmoud,

    i want to implement same requirement in my form but my report server and other machine,where my pdf file will get saved are linux.

    ReplyDelete
  7. Dear Mohammed
    greetings
    I have followed your steps
    procedure compiled successfully but when I run report it say FRM-41219 unable to find report
    I set the path in declaration to get the report from the folder where I saved but still showing same error
    Please advise
    Thanks
    Nasser

    ReplyDelete
  8. Dear Brother

    Can you please send me the demo.fmb to akbarmscjnu@gmail.com

    ReplyDelete

ADF : Scope Variables

Oracle ADF uses many variables and each variable has a scope. There are five scopes in ADF (Application, Request, Session, View and PageFl...