Tuesday, November 12, 2013

Generate PDF of a Table using ADF

How to download Oracle ADF tables in PDF format


          At this task we are going to convert ADF BC tables into PDF files and make it downloadable to users. It looks like very easy but it is not. To successfully complete this task I had to use several libraries such as apache fop library.
 
  • What is Apache FOP library.....??



          FOP stands for Formatting Object Processor. Apache FOP is a Java application which reads a Formatting Object (FO) tree and renders the resulting pages to a specific output. Currently supported outputs are:
           PDF, PS, PCL, AFP, XML, Print, AWT and PNG, and to a lesser extend RFT and TXT.
          Developers use Apache FOP libraries to change the output file format very commonly because it’s free and open source. You can download the Apache FOP library as a JAR file from the below link. (There are different links to download FOP.jar; but most of the jar files do not contain all the libraries required for this conversion.)


  •  How to convert ADF BC tables into PDF files
 
           If we try to analyse the process goes here we can simply represent it as below.

          First of all we want to get the table data and write it into a XML file. We can do it through JDeveloper framework. There is an inbuilt method called “printXML” at ViewObjectImpl class. It will generate the XML to the VO data. So if we can access the ViewObjectImpl class anyway we can generate the XML file. <VO>Impl class is a one which extends the ViewObjectImpl class. So we can generate the <VO>Impl class and generate the XML file.

  • Implement the <VO>Impl and <Application_Module>Impl classes for your MODEL project. (We need those method at those classes to generate the XML file.)
    (<VO>.xml à Java à Java Classes à click on "pencil" icon.)

  • Create a Java class at “View Controller” project to create a managed-bean. We are going to do all the coding inside this bean. All the required codes are mentioned at the end of this article.
     
  • We can access the <VO>Impl class through this path:
    (FacesContext à ExternalContext à AdfFacesContext à HttpServletRequest à BindingContext à DCDataControl à ApplicationModule à AppModuleImpl à ViewObjectImpl)
     
  • When we are creating the Node object we have two options. You can select the one which suits your requirement. (refer code while "// Print the XML" )
    Parameter
    Description
    XML_OPT_ALL_ROWS
    All rows will be rendered in XML
    XML_OPT_ASSOC_CONSISTENT
    attribute accessors that return a RowSet should set the AssociationConsistent flag on, so that new (unposted) rows for the RowSet are also included in the output.
    XML_OPT_CHANGES_ONLY
    For internal framework use only.
    XML_OPT_LIMIT_RANGE
    Rows in the current range will be rendered in XML
  • Then we have to generate the PDF using  a style sheet. Before genarate PDF files you should have to build the style sheet. Then we can generate the output file using FOP libraries (we can select the output format). Output format depends on the MimeConstant you select. There are several output formats supported by FOP libraries as follows. (refer code while "// Generate PDF" )

    MIME Constant
    Output Format
    MIME_PDF
    pdf
    MIME_PLAIN_TEXT
    txt
    MIME_PNG
    png
    MIME_FOP_AREA_TREE
    xml
    MIME_POSTSCRIPT
    ps
    MIME_AFP
    afp
    MIME_TIFF
    tiff
  •   
  • Then insert a Command Button next to your ADF BC table. Create a web page backing bean and write an Action Method. Then set that action method as the “action” property of the created command button. Inside the action method we have to write some codes which will make the generated pdf file to be downloadable.
     
  • When user press the command button pdf file shold be generated and downloadable. To do that  we have to go through the Context layers of the framework, get the http servlet response and set the content type of the response.
     
  • Here we have set the content type as “application/pdf” because we have generated a pdf file. That parameter depends on your file type. (refer code while "// download the PDF" )

      
All the required codes are given below.....

 
// Access the <VO>Impl
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
AdfFacesContext context = AdfFacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
BindingContext ctx = DCUtil.getBindingContext(request);
DCDataControl dc = ctx.findDataControl("AppModuleDataControl");
ApplicationModule service = (ApplicationModule)dc.getDataProvider();
ApplicationModule am = service.findApplicationModule("AppModule");
AppModuleImpl amImpl = (AppModuleImpl)am;
ViewObjectImpl VOImlp = (EmpVOImpl)amImpl.findViewObject("EmpVO1");
HashMap viewDefMap = new HashMap();

// Print the XML
Node n = VOImlp.writeXML(XMLInterface.XML_OPT_ALL_ROWS, viewDefMap);
java.io.File file = new java.io.File(<path to save XML file>);
PrintWriter output = null;
try {  output = new java.io.PrintWriter(file);
          ((XMLNode)n).print(output);
} catch (Exception e) { System.out.println(e.getMessage());
} finally {
try {output.close(); } catch (Exception e) { System.out.println(e.getMessage()); } } }

// Generate PDF
File xmlfile = new File(<path to generated XML file>);
File xsltfile = new File(<path to styleSheet>);
File pdffile = new File(<path to save PDF file>);
FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
OutputStream out = new java.io.FileOutputStream(pdffile);
out = new java.io.BufferedOutputStream(out);
try {
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
TransformerFactory factory = new TransformerFactoryImpl();
Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));
transformer.setParameter("versionParam", "2.0");
Source src = new StreamSource(xmlfile);
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);
} finally { out.close(); }

// download the PDF
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse)externalContext.getResponse();
File file = new File(dir1, pdffile1);
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
          response.reset();
          response.setContentType("application/pdf");
          response.setContentLength((int)file.length());
response.setHeader("Content-disposition","inline;filename=\""+pdffile1+"\"");
output = new BufferedOutputStream(response.getOutputStream(),DEFAULT_BUFFER_SIZE);
          byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
          int length;
          while ((length = input.read(buffer)) > 0) {
              output.write(buffer, 0, length); }
          output.flush(); } finally { close(output); close(input); }
facesContext.responseComplete();

   USEFULL SITE relating to this

No comments:

Post a Comment