我有一个与演示非常相似的
参考演示,想象一下汽车拥有价格属性。
我该如何按指定列对汽车价格进行汇总并在汇总行中显示?
p:dataTable
。
不幸的是,演示使用随机生成的值来展示p:summaryRow
。参考演示,想象一下汽车拥有价格属性。
我该如何按指定列对汽车价格进行汇总并在汇总行中显示?
p:dataTable
。
不幸的是,演示使用随机生成的值来展示p:summaryRow
。我和你有同样的问题,并从primefaces博客中找到了正确的用法SummaryRow from primefaces forum
这是一些示例,展示了正确计算总价、数量等的方法...
监听器获取组属性,即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;
}
}
}
}
}
这是我的解决方案:
<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);
}
...
@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;
}
...
3 - 创建一个方法来按组累积值:
...
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>
...
summaryRow
:
...
<p:summaryRow>
<p:column colspan="1" style="text-align:right">
<h:outputText value="Total:" />
</p:column>
<p:column>
<h:outputText value="#{inscricaoBean.getAcumulatedValue()}" />
</p:column>
</p:summaryRow>
...
好的,这是一种粗糙的完成任务的方式。我认为你可以改进,但这是我看到你的问题时想到的第一件事。
希望能有所帮助。
sortBy =“#{car.brand}”
值传递到p:summaryRow
中,然后在支持方法中使用流来计算价格小计。<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>
.
public double brandSubtotal(String brand) {
return cars.stream().filter(c -> c.getBrand().equals(brand)).mapToDouble(c -> c.getPrice()).sum();
}
p:summaryRow
中的监听器来设置一个后备 bean 属性,然后使用 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>
.
public void computeSubtotal(String brand) {
subTotal = cars.stream().filter(c -> c.getBrand().equals(brand)).mapToDouble(c -> c.getPrice()).sum();
}
public double getSubTotal () {
return subTotal ;
}
通过使用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>