2 Replies Latest reply: Jul 31, 2013 11:31 AM by scott.wesley RSS

    Render PDF via application process

    scott.wesley

      I'm using Anton's as_pdf3 package to generate a PDF

       

      I've had success using a privileged process and using this

      htp.p('<div style="">');
      htp.p('<embed height="550px" width="450px" name="statement" ');
      htp.p(' src="SAGE.WS_RENDER_PDF_INSTRUCTIONS?p_plug_id='||:P7_PLUG_ID||'"');
      htp.p(' type="application/pdf" />');
      htp.p('</div>');
      

      And the procedure generates a PDF nicely - well, my formatting could use work...

       

      But inspired by a need, and ideas from this blog, I thought I might be able to avoid wwv_flow_epg_include_mod_local, ie be able to accomplish this on apex.oracle.com

       

      1) Create region with staticID "renderPDF", using template 'div region with id'

       

      2) Create onLoad dynamic action, executing this JavaScript

      var get = new htmldb_Get(null,&APP_ID.,'APPLICATION_PROCESS=renderPDF',&APP_PAGE_ID.);
      $('#renderPDF').text(get.get());
      get = null;
      

       

      3) That calls this onDemand application process "renderPDF":

      htp.p('<div style="">');
      htp.p('<embed height="550px" width="450px" name="statement" ');
      htp.p(' src="');
      ws_render_pdf_instructions(p_id=>:P7_ID);
      htp.p('" type="application/pdf" />');
      htp.p('</div>');
      

       

      I've made a few variations of this but since the procedure ends with, it doesn't matter what is surrounding the procedure call.

        OWA_UTIL.MIME_HEADER('application/pdf', FALSE);
        HTP.P ('Content-length: '||DBMS_LOB.GETLENGTH(l_lob));
        OWA_UTIL.HTTP_HEADER_CLOSE;
        WPG_DOCLOAD.DOWNLOAD_FILE(l_lob);
      

       

      But it outputs raw PDF

      <div id="renderPDF" style="width:500px;" class="">%PDF-1.3
      %����
      1 0 obj
      &lt;&lt;/Creati...
      

      (chrome says it's surrounded by double quotes)

       

      Can anyone see what I'm doing wrong? Is there a variation of the JavaScript that I should be using instead? A better way...?

       

      Cheers,

       

      Scott

        • 1. Re: Render PDF via application process
          jrimblas

          I'm not sure what's wrong, lots of moving parts.  Here's something you might like, but may not address the embedded problem you have.

          I like this technique instead of grating execute to a procedure.

          Instead of calling the package to get the PDF you call an APEX page:

           

          htp.p('<div style="">');  
          htp.p('<embed height="550px" width="450px" name="statement" ');  
          htp.p(' src="f?p=&APP_ID.:200:&SESSION.::::P200_ID:'|| :P7_PLUG_ID||'"');  
          htp.p(' type="application/pdf" />');  
          htp.p('</div>'); 
          

           

          Here p200 is used for downloading the PDF.  The page only has a "Generate PDF Download" process "On Load: Before Header"

          The code something like this:

           

          WS_RENDER_PDF_INSTRUCTIONS(p_plug_id => :P200_ID);
          apex_application.stop_apex_engine;
          

           

          You make sure you do your owa_util.mime_header call in the package and download the PDF (or any blob really).

          I like this because no grants are needed. PLUS APEX security still applies.  ONLY those authenticated to the app can run p200, plus you can add Authorization Schemes to the page.

          I do se the template of the page to something simple like PopUp page, BUT it doesn't matter because the page template never downloads. The stop_apex_engine call takes care of that.

           

          Hope this helps.

          Thanks

          -Jorge

          • 2. Re: Render PDF via application process
            scott.wesley

            Ahh, I've seen that technique before - this is a great implementation of it - thanks Jorge!