Rodolfo
Rodolfo

Reputation: 23

Export editable dataTable to Excel with Primefaces shows only header

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.

Upvotes: 0

Views: 4091

Answers (1)

miroslav_mijajlovic
miroslav_mijajlovic

Reputation: 1731

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 "";
        }

}

Upvotes: 1

Related Questions