Sun. Oct 24th, 2021

Requirement: This post describes the usage of af:fileDownloadActionListener to generate the file on run-time. Here we will be exporting the Departments ViewObject data in a plain text file with the click of the Download button.

Explanation: The fileDownloadActionListener tag is a declarative way to allow an action source (<commandButton>, <commandLink>, etc.) to programmatically send the contents of a file to the user, optionally with a specific content type and filename. Since file downloads must be processed with an ordinary request – not XMLHttp AJAX requests – this tag forces partialSubmit to be false on the parent component if it supports that attribute.

The fileDownloadActionListener uses the native (browser built-in) filedownload popup, so this popup cannot be configured.

Solution: For the solution of the above requirement follow the steps as shown below:

Step 1: Create an ADF Fusion Web Application.

Step 2: Create ADF Business Components from Tables for the DEPARTMENTS table present in the HR schema of the Oracle Database 11g XE Edition.

Step 3: Create a demo.jspx page. Drag and drop af:panelCollection

Drag and drop af:toolbar inside the toolbar facet

Inside the af:toolbar drag and drop af:button and text=”Download”

Drag and drop af:fileDownloadActionListener inside the af:button and set filename=”Departments”,
contentType=”text/plain;charset=UTF-8″, and method=”#{FileDownloadBean.fileDownloadActionListener}”

Drag and drop DepartmentsVO1 from the AppModuleDataControl on the demo.jspx page as an ADF Table.

Thus, the complete code for the demo.jspx code is shown below:

<?xml version='1.0' encoding='UTF-8'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1" xmlns:f="http://java.sun.com/jsf/core"
          xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
    <jsp:directive.page contentType="text/html;charset=UTF-8"/>
    <f:view>
        <af:document title="demo.jspx" id="d1">
            <af:messages id="m1"/>
            <af:form id="f1">
                <af:panelCollection id="pc1">
                    <f:facet name="menus"/>
                    <f:facet name="toolbar">
                        <af:toolbar id="t2">
                            <af:button text="Download" id="b1">
                                <af:fileDownloadActionListener filename="Departments"
                                                               contentType="text/plain;charset=UTF-8"
                                                               method="#{FileDownloadBean.fileDownloadActionListener}"/>
                            </af:button>
                        </af:toolbar>
                    </f:facet>
                    <f:facet name="statusbar"/>
                    <af:table value="#{bindings.DepartmentsVO1.collectionModel}" var="row"
                              rows="#{bindings.DepartmentsVO1.rangeSize}"
                              emptyText="#{bindings.DepartmentsVO1.viewable ? 'No data to display.' : 'Access Denied.'}"
                              rowBandingInterval="0"
                              selectedRowKeys="#{bindings.DepartmentsVO1.collectionModel.selectedRow}"
                              selectionListener="#{bindings.DepartmentsVO1.collectionModel.makeCurrent}"
                              rowSelection="single" fetchSize="#{bindings.DepartmentsVO1.rangeSize}" id="t1">
                        <af:column headerText="#{bindings.DepartmentsVO1.hints.DepartmentId.label}" id="c1">
                            <af:outputText value="#{row.DepartmentId}"
                                           shortDesc="#{bindings.DepartmentsVO1.hints.DepartmentId.tooltip}" id="ot1">
                                <af:convertNumber groupingUsed="false"
                                                  pattern="#{bindings.DepartmentsVO1.hints.DepartmentId.format}"/>
                            </af:outputText>
                        </af:column>
                        <af:column headerText="#{bindings.DepartmentsVO1.hints.DepartmentName.label}" id="c2">
                            <af:outputText value="#{row.DepartmentName}"
                                           shortDesc="#{bindings.DepartmentsVO1.hints.DepartmentName.tooltip}"
                                           id="ot2"/>
                        </af:column>
                        <af:column headerText="#{bindings.DepartmentsVO1.hints.ManagerId.label}" id="c3">
                            <af:outputText value="#{row.ManagerId}"
                                           shortDesc="#{bindings.DepartmentsVO1.hints.ManagerId.tooltip}" id="ot3">
                                <af:convertNumber groupingUsed="false"
                                                  pattern="#{bindings.DepartmentsVO1.hints.ManagerId.format}"/>
                            </af:outputText>
                        </af:column>
                        <af:column headerText="#{bindings.DepartmentsVO1.hints.LocationId.label}" id="c4">
                            <af:outputText value="#{row.LocationId}"
                                           shortDesc="#{bindings.DepartmentsVO1.hints.LocationId.tooltip}" id="ot4">
                                <af:convertNumber groupingUsed="false"
                                                  pattern="#{bindings.DepartmentsVO1.hints.LocationId.format}"/>
                            </af:outputText>
                        </af:column>
                    </af:table>
                </af:panelCollection>
            </af:form>
        </af:document>
    </f:view>
</jsp:root>

And, the complete code for the FileDownloadBean.java file is shown below:

package susantotech.com;

import java.io.IOException;
import java.io.OutputStream;

import oracle.jbo.AttributeDef;

import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

import javax.faces.context.FacesContext;

import oracle.adf.model.BindingContext;

import oracle.adf.model.binding.DCIteratorBinding;

import oracle.binding.BindingContainer;

import oracle.jbo.Row;
import oracle.jbo.RowSetIterator;
import oracle.jbo.server.ViewAttributeDefImpl;
import oracle.jbo.server.ViewObjectImpl;

public class FileDownloadBean {
    public FileDownloadBean() {
    }

    public BindingContainer getBindingsCont() {
        return BindingContext.getCurrent().getCurrentBindingsEntry();
    }

    public void fileDownloadActionListener(FacesContext facesContext,
                                           OutputStream outputStream) throws UnsupportedEncodingException, IOException {
        OutputStreamWriter w = new OutputStreamWriter(outputStream, "UTF-8");
        DCIteratorBinding deptIter = (DCIteratorBinding) getBindingsCont().get("DepartmentsVO1Iterator");
        ViewObjectImpl vo = (ViewObjectImpl) deptIter.getViewObject();
        ViewAttributeDefImpl[] attrDefs = vo.getViewAttributeDefImpls();
        int count = 0;
        RowSetIterator rsi = vo.createRowSetIterator(null);
        while (rsi.hasNext()) {
            Row nextRow = rsi.next();
            if (nextRow != null) {
                for (ViewAttributeDefImpl attrDef : attrDefs) {
                    byte attrKind = attrDefs[count].getAttributeKind();
                    if (attrKind != AttributeDef.ATTR_ASSOCIATED_ROW &&
                        attrKind != AttributeDef.ATTR_ASSOCIATED_ROWITERATOR) {
                        String columnName = attrDef.getName();
                        w.write(columnName + " - " + nextRow.getAttribute(columnName) + " ");
                    }
                }
                w.write(System.getProperty("line.separator"));
            }
        }
        w.flush();
    }
}

Save all and run the application. Thus, the ran application is shown below.

Click on the Download button and with the the Departments file is downloaded which is as shown below:

Hence, the solution to our requirement.

If you like the post please comment, share, and do join me on Facebook. Please subscribe to my YouTube Channel for video tutorials.

Thanks & Regards,
Susanto Paul

 341 total views,  1 views today

By Susanto Paul

Susanto is an Oracle ACE, a qualified MCA, MBA, and a highly-skilled Senior Oracle Specialist. He is an enthusiastic Blogger and YouTuber who helps learners to solve their complex problems more efficiently. He has 9+ years of experience in multiple technologies like AWS, Oracle ADF, Oracle APEX, Oracle JET, Oracle VBCS, Oracle IDCS, Oracle PL/SQL, Oracle Integration Cloud, Java, JDBC, Servlets, JSP, Spring, Hibernate, HTML5, CSS3, JavaScript, TypeScript, NodesJS, Angular, MySQL, Oracle WebLogic Server, JUnit, JMeter, Selenium Web Driver, etc. He is a certified: Oracle Certified Professional Java SE 6 Programmer, Oracle ADF 11g Certified Implementation Specialist, Oracle Cloud Platform Application Integration 2020 Certified Specialist, Oracle Cloud Infrastructure Foundations 2020 Certified Associate, and Oracle Cloud Infrastructure Developer 2020 Certified Associate

Leave a Reply

Your email address will not be published. Required fields are marked *