0

I'm trying to export values from dataTable to Excel with dataExporter component of Primefaces.

I'm using primefaces 3.5 and jsf 2.2;

My dataTable and commandlink are following:

<p:dataTable id="tableTemp" binding="#{ledgerComplMB.tableTemp}" value="#{ledgerComplMB.listaTemp}"
         var="q" emptyMessage="No Registry" paginator="true" rows="10" 
         rowsPerPageTemplate="10,50,200,500"
         paginatorTemplate=" {CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
         scrollable="true" scrollWidth="100%" scrollRows="10"
         filteredValue="#{ledgerComplMB.listaTempFilter}"
         filterDelay="1500" resizableColumns="true" editable="true">

<f:facet name="header">
    <p:commandButton id="btGravar" icon="ui-icon-disk"
                     value="Write data" actionListener="#{ledgerComplMB.gravar}"
                     disabled="${empty ledgerComplMB.listaTemp}" style="width:200px;"  />

    <p:commandButton id="btLimpar" value="Clean data"
                     actionListener="#{ledgerComplMB.limpar}" icon="ui-icon-trash"
                     disabled="${empty ledgerComplMB.listaTemp}"
                     style="width:200px;font-weight: bold;margin-left: 20px"/>

    <br />
    <h:outputText
        value="Total: #{fn:length(ledgerComplMB.listaTemp)}"
        rendered="#{not empty ledgerComplMB.listaTemp}" />
</f:facet>

<p:ajax event="rowEdit"
        oncomplete="dlgConfirma.show()" update=":form:dialogConfirmacao" />

<p:column exportable="false" style="width:30px">
    <p:rowEditor />
      </p:column>

<p:column filterBy="#{q.ledger.accountNumber}" filterMatchMode="exact"  style="width:100px">
    <f:facet name="header">AccountNumber</f:facet>
    <h:outputText value="#{q.ledger.accountNumber}" />
</p:column>

<p:column filterBy="#{q.ledger.vendor}" filterMatchMode="exact" style="width:100px">
    <f:facet name="header">Vendor</f:facet>                                      
    <p:cellEditor>
        <f:facet name="output">
            <h:outputText value="#{q.ledger.vendor}" />
        </f:facet>
        <f:facet name="input">
            <p:inputText value="#{q.ledger.vendor}" />
        </f:facet>
    </p:cellEditor>
</p:column>

</p:dataTable>


<p:commandLink id="exp1" ajax="false">
      <p:graphicImage library="img" name="pdf.png" />
<p:dataExporter type="xlsx" target="tableTemp" fileName="#{ledgerComplMB.retornaDataExport}"  />  

When I request the export only the header values appear.

miroslav_mijajlovic
  • 1,703
  • 17
  • 31
Rodolfo
  • 23
  • 1
  • 9

1 Answers1

1

The only solution that I've found is to make your own class that extends Exporter and to override method protected String exportValue(FacesContext context, UIComponent component).

You should only add to existing code following lines:

else if (component instanceof CellEditor) {
 return exportValue(context, ((CellEditor) component).getFacet("output")); 
}

That happens because CellEditor is not exportable. I haven't check if it is still an issue in PrimeFaces 4.0. This was repported as an issue issue4013 by BalusC In case of export to Excel file here is what I wrote and it workse (this is in class that extends ExcelExporter):

@Override
protected String exportValue(FacesContext context, UIComponent component) {
        if (component instanceof HtmlCommandLink) { // support for PrimeFaces
                                                    // and standard
                                                    // HtmlCommandLink
            HtmlCommandLink link = (HtmlCommandLink) component;
            Object value = link.getValue();

            if (value != null) {
                return String.valueOf(value);
            } else {
                // export first value holder
                for (UIComponent child : link.getChildren()) {
                    //if (child instanceof ValueHolder) {
                        return exportValue(context, child);
                    //}
                }

                return "";
            }
        } else if (component instanceof CellEditor) { // Handle in-cell editable datatables
            return exportValue(context,
                    ((CellEditor) component).getFacet("output"));
        } else if (component instanceof ValueHolder) {

            if (component instanceof EditableValueHolder) {
                Object submittedValue = ((EditableValueHolder) component)
                        .getSubmittedValue();
                if (submittedValue != null) {
                    return submittedValue.toString();
                }
            }

            ValueHolder valueHolder = (ValueHolder) component;
            Object value = valueHolder.getValue();
            if (value == null)
                return "";

            // first ask the converter
            if (valueHolder.getConverter() != null) {
                return valueHolder.getConverter().getAsString(context,
                        component, value);
            }
            // Try to guess
            else {
                ValueExpression expr = component.getValueExpression("value");
                if (expr != null) {
                    Class<?> valueType = expr.getType(context.getELContext());
                    if (valueType != null) {
                        Converter converterForType = context.getApplication()
                                .createConverter(valueType);

                        if (converterForType != null)
                            return converterForType.getAsString(context,
                                    component, value);
                    }
                }
            }

            // No converter found just return the value as string
            return value.toString();
        } else {
            // This would get the plain texts on UIInstructions when using
            // Facelets
            String value = component.toString();

            if (value != null)
                return value.trim();
            else
                return "";
        }

}
Community
  • 1
  • 1
miroslav_mijajlovic
  • 1,703
  • 17
  • 31
  • I tried this approach before but unsuccessful because the dataTable in this method have just one line. However, in the xhtml, it has many lines. – Rodolfo Oct 04 '13 at 17:04
  • Which method has one line? – miroslav_mijajlovic Oct 04 '13 at 21:41
  • the method is exportAll(FacesContext context, DataTable table, Sheet sheet) of ExcelExporter class from org.primefaces.component.export package. – Rodolfo Oct 05 '13 at 22:14
  • I've updated my answer with extension of excel reporter that works for me. – miroslav_mijajlovic Oct 07 '13 at 06:31
  • How I pass my dataTable to method exportAll? – Rodolfo Oct 07 '13 at 16:41
  • Here is how you're going to find your datatable: `ValueExpression targetEL = ef.createValueExpression("path to your datatable");`. `String tableId = (String) target.getValue(elContext);` `UIComponent component = event.getComponent().findComponent(tableId);` And then: `ExcelExporter exp = new ExcelExporter();` exporter.export(FacesContext.getCurrentInstance(), (DataTable) component, someFileName, ...) See about this method in http://www.primefaces.org/docs/api/3.5/org/primefaces/component/export/ExcelExporter.html – miroslav_mijajlovic Oct 08 '13 at 06:44
  • Thanks! My solution was a merge between your tips with this code: http://stackoverflow.com/questions/14411389/pdataexporter-does-not-recognize-pcelleditor – Rodolfo Oct 18 '13 at 14:13