Primefaces p:数据表汇总行计算

Primefaces p:数据表汇总行计算,primefaces,datatable,Primefaces,Datatable,我有一个p:dataTable非常类似于。 不幸的是,showcase为p:summaryRow使用随机生成的值 参考陈列柜,想象汽车具有价格属性 <p:summaryRow listener="#{dtSummaryRowView.computeSubtotal(car.brand)}"> <p:column colspan="3" style="text-align:right">

我有一个
p:dataTable
非常类似于。 不幸的是,showcase为
p:summaryRow
使用随机生成的值

参考陈列柜,想象汽车具有价格属性

    <p:summaryRow listener="#{dtSummaryRowView.computeSubtotal(car.brand)}">
        <p:column colspan="3" style="text-align:right">
            <h:outputText value="Total:" />
        </p:column>
        <p:column>
            <h:outputText value="#{dtSummaryRowView.subTotal}">
                <f:convertNumber type="currency" currencySymbol="$" />
            </h:outputText>
        </p:column>
    </p:summaryRow>

我如何总结按指定列分组的汽车的价格,以便在摘要行中显示该价格?

我将建议一种可能的方法,可能不是最完美的方法,但我相信它会有所帮助

步骤如下:

1-声明一个类别atribute以累积组总值:

...
@Named(value = "myBean")
@YourScope

public class InscricaoBean implements Serializable {
...

//in this example i will use a int type

private int acumulatorAux = 0;
...
2-创建一个函数以返回每个组的总值:

...
public int getAcumulatedValue() {
        int aux = acumulatorAux ;
        acumulatorAux = 0;
        return aux;
    }
...
...
public void acumulateValue(int value)
    {
        acumulatorAux += value;
    }
...
3-创建一种方法来累积每个组的值:

...
public int getAcumulatedValue() {
        int aux = acumulatorAux ;
        acumulatorAux = 0;
        return aux;
    }
...
...
public void acumulateValue(int value)
    {
        acumulatorAux += value;
    }
...
4-在JSF页面上,您需要为每一行调用
acumulateValue
方法,类似于:

...
<p:dataTable value="#{myBean.getList()}" var="testVar">
       <p:column headerText="Header" sortBy="#{testVar.name}">
            #{inscricaoBean.acumulateValue(testVar.value)}
            <h:outputText value="#{testVar.name}" />
       </p:column>
 ...
嗯,这是完成这项任务的一个糟糕的方法。我认为你可以提高,但这是我第一次看到你的问题


希望能有所帮助。

我和你有同样的问题,并且在primefaces博客上找到了正确的用法

这是一个例子,说明如何正确计算总价,计算

侦听器获取group属性,该属性是sortBy值,可用于计算总计或任何其他操作

<p:summaryRow listener="#{backingBean.calculateTotal}"> 
                        <p:column colspan="3" style="text-align:right"> 
                            Total: 
                        </p:column> 

                        <p:column> 
                            #{backingBean.total}
                        </p:column> 
                    </p:summaryRow>

/* listener method in your bean */
public void calculateTotal(Object o) {
    this.total = 0.0d;
    String name = "";
    if(o != null) {
        if(o instanceof String) {
            name = (String) o;
            for(MyRowObject p : (List<MyRowObject>) dataTableModel.getWrappedData()) { // The loop should find the sortBy value rows in all dataTable data.
                switch(sortColumnCase) { // sortColumnCase was set in the onSort event
                    case 0:
                        if(p.getcolumn0data().getName().equals(name)) {
                            this.total += p.getcolumn0data().getValue();
                        }
                        break;
                    case 1:
                        if(p.getcolumn1data().getName().equals(name)) {
                            this.total += p.getcolumn1data().getValue();
                        }
                        break;
                }
            }
        }
    }
}

总数:
#{backingBean.total}
/*bean中的侦听器方法*/
公共void calculateTotal(对象o){
该值为0.0d;
字符串名称=”;
如果(o!=null){
如果(字符串的o实例){
name=(字符串)o;
对于(MyRowObject p:(List)dataTableModel.getWrappedData()){//,循环应该在所有dataTable数据中找到sortBy值行。
开关(sortColumnCase){//sortColumnCase是在onSort事件中设置的
案例0:
if(p.getcolumn0data().getName().equals(name)){
this.total+=p.getcolumn0data().getValue();
}
打破
案例1:
if(p.getcolumn1data().getName().equals(name)){
this.total+=p.getcolumn1data().getValue();
}
打破
}
}
}
}
}
这是我的解决方案:

<p:dataTable var="elem" value="#{unitSubStatusChart.resultList}" tableStyleClass="app-table-auto">
    <et:defaultPaginator />

    <p:column headerText="#{bundle['class']}" sortBy="#{elem.dtype}">
        <e:outputIconText icon="#{icons[elem.dtype]}" value="#{bundle[elem.dtype]}" />
    </p:column>
    <p:column headerText="#{bundle['status']}" sortBy="#{elem.status}">
        <h:outputText value="#{bundle[elem.status]}" />
    </p:column>
    <p:column headerText="#{bundle['subStatus']}" sortBy="#{elem.subStatus}">
        <h:outputText value="#{bundle[elem.subStatus]}" />
    </p:column>
    <p:column headerText="#{bundle['count']}">
        <h:outputText value="#{elem.count}" />
    </p:column>

    <p:summaryRow listener="#{unitSubStatusChart.onSummaryRow}">
        <p:column colspan="3" style="text-align:right">
            <h:outputText value="#{bundle.total}:" />
        </p:column>
        <p:column>
            <!-- !!! NOTE THIS VALUE EXPRESSION !!! -->
            <h:outputText value="#{component.parent.attributes.total}" />
        </p:column>
    </p:summaryRow>
</p:dataTable>

这就是听众:

public void onSummaryRow(Object filter)
{
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ELContext elContext = facesContext.getELContext();
    ELResolver elResolver = elContext.getELResolver();

    DataTable table = (DataTable) UIComponent.getCurrentComponent(facesContext);

    UIColumn sortColumn = table.getSortColumn();
    ValueExpression expression = sortColumn.getValueExpression("sortBy");
    ValueReference reference = ValueExpressionAnalyzer.getReference(expression);
    String property = (String) reference.getProperty();

    int total = 0;
    List<?> rowList = (List<?>) table.getValue();
    for(Object row : rowList)
    {
        Object value = elResolver.getValue(elContext, row, property);
        if(filter.equals(value))
        {
            // THIS IS THE ONLY POINT TO CUSTOMIZE
            total += ((UnitResult) row).getCount();
        }
    }

    List<UIComponent> children = table.getSummaryRow().getChildren();
    UIComponent column = children.get(children.size() - 1);
    column.getAttributes().put("total", total);
}
summaryRow上的公共void(对象过滤器)
{
FacesContext FacesContext=FacesContext.getCurrentInstance();
ELContext ELContext=facesContext.getELContext();
ELResolver ELResolver=elContext.getELResolver();
DataTable=(DataTable)UIComponent.getCurrentComponent(facesContext);
UIColumn sortColumn=table.getSortColumn();
ValueExpression=sortColumn.getValueExpression(“sortBy”);
ValueReference=ValueExpressionAnalyzer.getReference(表达式);
String属性=(String)reference.getProperty();
int-total=0;
List rowList=(List)table.getValue();
用于(对象行:行列表)
{
Object value=elResolver.getValue(elContext,row,property);
if(filter.equals(value))
{
//这是唯一需要定制的点
总计+=((UnitResult)行).getCount();
}
}
List children=table.getSummaryRow().getChildren();
UIComponent列=children.get(children.size()-1);
column.getAttributes().put(“总计”,总计);
}

此侦听器没有外部引用:它不依赖于以前的onSort事件/侦听器,也不需要bean中的任何字段。

通过使用Lambda表达式,它在java 1.7和EL 3.0中工作 在您的JSF中,它是这样的:

 <p:summaryRow>
  <p:column colspan="3" style="text-align:right">
   <h:outputText value="Total:" />
  </p:column>
  <p:column>
    <h:outputText value="#{car.stream().map(item->item.price).sum()}">
     <f:convertNumber type="currency" currencySymbol="$" />
    </h:outputText>
  </p:column>
 </p:summaryRow>

一种方法是将
p:summaryRow
中数据表的
sortBy=“#{car.brand}”
值传递到使用流计算价格小计的支持方法中

<h:form>
    <p:dataTable var="car" value="#{dtSummaryRowView.cars}" sortBy="#{car.brand}">
        <p:column headerText="Id" sortBy="#{car.id}">
            <h:outputText value="#{car.id}" />
        </p:column>
        <p:column headerText="Year" sortBy="#{car.year}">
            <h:outputText value="#{car.year}" />
        </p:column>
        <p:column headerText="Brand" sortBy="#{car.brand}">
            <h:outputText value="#{car.brand}" />
        </p:column>
        <p:column headerText="Color" sortBy="#{car.color}">
            <h:outputText value="#{car.color}" />
        </p:column>
        <p:summaryRow>
            <p:column colspan="3" style="text-align:right">
                <h:outputText value="Total:" />
            </p:column>
            <p:column>
                <h:outputText value="#{dtSummaryRowView.brandSubtotal(car.brand)}">
                    <f:convertNumber type="currency" currencySymbol="$" />
                </h:outputText>
            </p:column>
        </p:summaryRow>
    </p:dataTable>
</h:form>
另一种方法是使用
p:summaryRow
中的侦听器设置backingbean属性,然后使用getter显示该属性

    <p:summaryRow listener="#{dtSummaryRowView.computeSubtotal(car.brand)}">
        <p:column colspan="3" style="text-align:right">
            <h:outputText value="Total:" />
        </p:column>
        <p:column>
            <h:outputText value="#{dtSummaryRowView.subTotal}">
                <f:convertNumber type="currency" currencySymbol="$" />
            </h:outputText>
        </p:column>
    </p:summaryRow>

在summaryRow中使用多个列,这是唯一适合我的。