DataTable column headers and footers can be combined for grouped display.
<div class="card">
<h:form>
<p:dataTable id="tblSales" var="sale" value="#{dtGroupView.sales}">
<f:facet name="header">
<h:outputText value="Product Sales"/>
</f:facet>
<p:columnGroup type="header">
<p:row>
<p:column rowspan="3" headerText="Product"/>
<p:column colspan="4" headerText="Sale Rate"/>
</p:row>
<p:row>
<p:column colspan="2" headerText="Sales"/>
<p:column colspan="2" headerText="Profit"/>
</p:row>
<p:row>
<p:column headerText="Last Year"/>
<p:column headerText="This Year"/>
<p:column headerText="Last Year"/>
<p:column headerText="This Year"/>
</p:row>
</p:columnGroup>
<p:column>
<h:outputText value="#{sale.manufacturer}"/>
</p:column>
<p:column>
<h:outputText value="#{sale.lastYearProfit}%"/>
</p:column>
<p:column>
<h:outputText value="#{sale.thisYearProfit}%"/>
</p:column>
<p:column>
<h:outputText value="#{sale.lastYearSale}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</p:column>
<p:column>
<h:outputText value="#{sale.thisYearSale}">
<f:convertNumber type="currency" currencySymbol="$"/>
</h:outputText>
</p:column>
<p:columnGroup type="footer">
<p:row>
<p:column colspan="3" style="text-align:right" footerText="Totals:"/>
<p:column style="text-align:left" footerText="$#{dtGroupView.lastYearTotal}"/>
<p:column style="text-align:left" footerText="$#{dtGroupView.thisYearTotal}"/>
</p:row>
</p:columnGroup>
<f:facet name="footer">
<h:outputText value="Data between 2013-2014"/>
</f:facet>
</p:dataTable>
<p:dataTable id="tblPlayers" var="player" value="#{dtGroupView.players}" style="margin-top:40px">
<f:facet name="header">
<h:outputText value="Dynamic Columns"/>
</f:facet>
<p:columnGroup type="header">
<p:row>
<p:column rowspan="2" headerText="Player"/>
<p:column colspan="#{dtGroupView.yearCount}" headerText="Goals"/>
</p:row>
<p:row>
<ui:repeat value="#{dtGroupView.years}" var="year">
<p:column headerText="#{year}"/>
</ui:repeat>
</p:row>
</p:columnGroup>
<p:column>
<h:outputText value="#{player.name}"/>
</p:column>
<p:columns value="#{dtGroupView.years}" var="year">
<h:outputText value="#{player.getGoals(year)}"/>
</p:columns>
<f:facet name="footer">
<h:outputText value="Data between 2010-2014" styleClass="p-text-bold" />
</f:facet>
</p:dataTable>
</h:form>
</div>
@Named("dtGroupView")
@ViewScoped
public class GroupView implements Serializable {
private final static String[] manufacturers;
private List<Sale> sales;
private final static String[] playerNames;
private List<Integer> years;
private List<Player> players;
static {
manufacturers = new String[10];
manufacturers[0] = "Bamboo Watch";
manufacturers[1] = "Black Watch";
manufacturers[2] = "Blue Band";
manufacturers[3] = "Blue T-Shirt";
manufacturers[4] = "Brown Purse";
manufacturers[5] = "Chakra Bracelet";
manufacturers[6] = "Galaxy Earrings";
manufacturers[7] = "Game Controller";
manufacturers[8] = "Gaming Set";
manufacturers[9] = "Gold Phone Case";
}
static {
playerNames = new String[10];
playerNames[0] = "Lionel Messi";
playerNames[1] = "Cristiano Ronaldo";
playerNames[2] = "Arjen Robben";
playerNames[3] = "Franck Ribery";
playerNames[4] = "Ronaldinho";
playerNames[5] = "Luis Suarez";
playerNames[6] = "Sergio Aguero";
playerNames[7] = "Zlatan Ibrahimovic";
playerNames[8] = "Neymar Jr";
playerNames[9] = "Andres Iniesta";
}
@PostConstruct
public void init() {
sales = new ArrayList<>();
for(int i = 0; i < 10; i++) {
sales.add(new Sale(manufacturers[i], getRandomAmount(), getRandomAmount(), getRandomPercentage(), getRandomPercentage()));
}
years = new ArrayList<>();
years.add(2010);
years.add(2011);
years.add(2012);
years.add(2013);
years.add(2014);
players = new ArrayList<>();
for(int i = 0; i < 10; i++) {
players.add(new Player(playerNames[i], generateRandomGoalStatsData()));
}
}
public List<Sale> getSales() {
return sales;
}
private int getRandomAmount() {
return (int) (Math.random() * 100000);
}
private int getRandomPercentage() {
return (int) (Math.random() * 100);
}
public String getLastYearTotal() {
int total = 0;
for(Sale sale : getSales()) {
total += sale.getLastYearSale();
}
return new DecimalFormat("###,###.###").format(total);
}
public String getThisYearTotal() {
int total = 0;
for(Sale sale : getSales()) {
total += sale.getThisYearSale();
}
return new DecimalFormat("###,###.###").format(total);
}
public List<Integer> getYears() {
return years;
}
public int getYearCount() {
return years.size();
}
public List<Player> getPlayers() {
return players;
}
private Map<Integer,Integer> generateRandomGoalStatsData() {
Map<Integer,Integer> stats = new LinkedHashMap<>();
for (int i = 0; i < 5; i++) {
stats.put(years.get(i), getRandomGoals());
}
return stats;
}
private int getRandomGoals() {
return (int) (Math.random() * 50);
}
}