SubTable is a helper component for grouping.
<h:form>
<div class="card">
<p:dataTable var="team" value="#{subTableView.teams}">
<f:facet name="header">
NBA Teams
</f:facet>
<p:columnGroup type="header">
<p:row>
<p:column rowspan="2" headerText="Team"/>
<p:column colspan="2" headerText="Stats"/>
</p:row>
<p:row>
<p:column headerText="Wins"/>
<p:column headerText="Losses"/>
</p:row>
</p:columnGroup>
<p:subTable var="stats" value="#{team.stats}">
<f:facet name="header">
<h:outputText value="#{team.name}"/>
</f:facet>
<p:column>
<h:outputText value="#{stats.season}"/>
</p:column>
<p:column>
<h:outputText value="#{stats.win}"/>
</p:column>
<p:column>
<h:outputText value="#{stats.loss}"/>
</p:column>
<p:columnGroup type="footer">
<p:row>
<p:column footerText="Totals: " class="text-right font-bold"/>
<p:column footerText="#{team.allWins}" class="font-bold"/>
<p:column footerText="#{team.allLosses}" class="font-bold"/>
</p:row>
</p:columnGroup>
</p:subTable>
</p:dataTable>
</div>
</h:form>
package org.primefaces.showcase.view.data.datatable;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;
import java.util.ArrayList;
import java.util.List;
import io.quarkus.runtime.annotations.RegisterForReflection;
import org.primefaces.showcase.domain.Stats;
import org.primefaces.showcase.domain.Team;
@Named
@RequestScoped
@RegisterForReflection(serialization = true)
public class SubTableView {
private List<Team> teams;
@PostConstruct
public void init() {
teams = new ArrayList<Team>();
Team lakers = new Team("Los Angeles Lakers");
lakers.getStats().add(new Stats("2005-2006", 50, 32));
lakers.getStats().add(new Stats("2006-2007", 44, 38));
lakers.getStats().add(new Stats("2007-2008", 40, 42));
lakers.getStats().add(new Stats("2008-2009", 45, 37));
lakers.getStats().add(new Stats("2009-2010", 48, 34));
lakers.getStats().add(new Stats("2010-2011", 42, 42));
teams.add(lakers);
Team celtics = new Team("Boston Celtics");
celtics.getStats().add(new Stats("2005-2006", 46, 36));
celtics.getStats().add(new Stats("2006-2007", 50, 32));
celtics.getStats().add(new Stats("2007-2008", 41, 41));
celtics.getStats().add(new Stats("2008-2009", 45, 37));
celtics.getStats().add(new Stats("2009-2010", 38, 44));
celtics.getStats().add(new Stats("2010-2011", 35, 47));
teams.add(celtics);
}
public List<Team> getTeams() {
return teams;
}
}
package org.primefaces.showcase.domain;
import java.io.Serializable;
import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public class Stats implements Serializable {
private static final long serialVersionUID = 1L;
private String season;
private int win;
private int loss;
public Stats() {
// default constructor
}
public Stats(String season, int win, int loss) {
this.season = season;
this.win = win;
this.loss = loss;
}
public int getWin() {
return win;
}
public void setWin(int win) {
this.win = win;
}
public int getLoss() {
return loss;
}
public void setLoss(int loss) {
this.loss = loss;
}
public String getSeason() {
return season;
}
public void setSeason(String season) {
this.season = season;
}
}