Introdução ao PrimeFaces
Prof. Bruno Ferreira
Introdução
•
PrimeFaces é uma bibliotecas de componentes ricos
em JavaServer Faces.
•
Os componentes do PrimeFaces possuem
funcionalidade de Ajax integrado, baseado na API de
Ajax do JSF.
•
Para conhecer todos os componentes disponíveis,
acesse
Introdução
Introdução
Outros opções de
Frameworks JSF
Introdução
•
A documentação pode ser obtida em:
http://www.primefaces.org/docs/guide/primefaces_user_guide_5_1.pdf
•
Para usar componentes do PrimeFaces nos projetos
JSF, precisamos importar o jar de componentes
(dependências no pom.xml)
<
dependency
>
<
groupId
>
org.primefaces
</
groupId
>
<
artifactId
>
primefaces
</
artifactId
>
<
version
>
5.1
</
version
>
<
scope
>
compile
</
scope
>
</
dependency
>
Introdução
•
Para usar componentes do PrimeFaces nas páginas
JSF, precisamos importar a biblioteca de componentes
na página XHTML:
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
xmlns:h
=
"http://xmlns.jcp.org/jsf/html"
xmlns:ui
=
"http://xmlns.jcp.org/jsf/facelets"
xmlns:f
=
"http://xmlns.jcp.org/jsf/core"
xmlns:p
=
"http://primefaces.org/ui"
>
<
h:head
>
<
title
>
Exemplo
</
title
>
</
h:head
>
<p:painelGrid>
•
Esse componente é uma versão estendida do
componente padrão do JSF. Ele cria bordas entre as
células e permite criar cabeçalhos e rodapés.
<p:outputLabel>
•
Esse componente é uma extensão do componente de
mesmo nome da biblioteca do JSF. Mas erros de
validação alteram a cor do texto.
•
Ao clicar no texto o curso é direcionado para o campo.
•
Campos requeridos são diferenciados por um “ * ”
<p:inputText>
•
Esse componente também é uma extensão do
componente de mesmo nome da biblioteca do JSF.
•
O campo é renderizado com um skin diferente do
componente padrão. Além disso, em caso de erros
associados ao componente, ele fica destacado para o
usuário.
<p:commandButton>
•
O componente <p:commandButton> é uma versão
mais atraente do botão padrão do JSF, além de ter a
funcionalidade de Ajax integrada.
•
A propriedade icon pode ser usada para definir uma
classe CSS de um ícone do botão. O PrimeFaces já
possui algumas classes de ícones, que podem ser
consultadas em http://jqueryui.com/themeroller/.
Exemplo
<
h:form
>
<
p:messages
/>
<
p:panelGrid
columns
=
"2"
>
<
f:facet
name
=
"header“
>
Cadastro de aluno
</
f:facet
>
<
h:outputLabel
value
=
"Nome"
for
=
"nome"
/>
<
p:inputText
id
=
"nome"
required
=
"true"
label
=
"Nome"
value
=
"#{cadastroAlunoBean.nome}"
/>
<
p:outputLabel
value
=
"E-mail"
for
=
"email"
/>
<
p:inputText
id
=
"email"
required
=
"true"
value
=
"#{cadastroAlunoBean.email}"
/>
<
f:facet
name
=
"footer"
>
<
p:commandButton
value
=
"Cadastrar"
ajax
=
"false"
icon
=
"ui-icon-disk"
iconPos
=
"right"
action
=
"#{cadastroAlunoBean.cadastrar}"
/>
</
f:facet
>
</
p:panelGrid
>
</
h:form
>
<p:commandButton>
•
Quando não desabilitamos o Ajax deve-se especificar
qual componente será redesenhado na página.
<
h:outputText
/>
<
h:outputText
value
=
"#{cadastroAlunoBean.tamNome}"
id
=
"tamNome"
/>
<
f:facet
name
=
"footer"
>
<
p:commandButton
value
=
"Cadastrar"
ajax
=
“true"
icon
=
"ui-icon-disk"
iconPos
=
"right"
action
=
"#{cadastroAlunoBean.cadastrar}"
update
=
"tamNome"
/>
</
f:facet
>
Conta a qtde de
caracteres
<
h:form
id
="frm"
>
<
p:messages
autoUpdate
="true"
/>
<
p:outputLabel
value
="Nome"
for
="nome"
/>
<
p:inputText
id
="nome"
value
="#{cadBean.nome}"
required
="true"
>
<
p:ajax
listener
="#{cadBean.disponibilidade}"
event
="change"
process
="@this"
/>
</
p:inputText
>
<
p:outputLabel
value
="Email"
for
="email"
/>
<
p:inputText
id
=" email "
value
="#{cadBean.email“
required
="true"
/>
<
p:commandButton
value
=“Checar“
action
="#{cadBean.cadastrar}"
/>
</
h:form
>
<p:commandButton>
•
Quando não desabilitamos o Ajax pode-se especificar
qual componente será processado na página.
Os dois campos são
requeridos, mas a
requisição Ajax
deverá processar
somente o primeiro.
<p:ajaxStatus>
•
Com o exemplo anterior podemos dar um feedback
para usuário sobre o andamento das requisições
<
h:head
>
<
style
>
.ajax-status
{
width
:
35px
;
height
:
35px
;
position
:
fixed
;
right
:
10px
;
top
:
60px
; }
</
style
>
</
h:head
>
<
h:form
id
="frm"
>
<
p:ajaxStatus
styleClass
="ajax-status"
>
<
f:facet
name
="start"
>
<
h:graphicImage
library
="imagens"
name
="carregando.gif"
/>
</
f:facet
>
<
f:facet
name
="complete"
>
<
h:outputText
value
=""
/>
</
f:facet
>
</
p:ajaxStatus
>
...
<p:password>
•
Componente para inserção de senha. O exemplo
abaixo pode ser usado para cadastrar uma senha
<
p:outputLabel
value
="Login"
for
="login"
/>
<
p:inputText
id
="login"
required
="true“
value
="#{cadBean.login}"
/>
<
p:outputLabel
value
="Senha"
for
="senha"
/>
<
p:password
id
="senha"
required
="true"
value
="#{cadBean.senha}"
feedback
="true"
weakLabel
="Fraca"
goodLabel
="Boa"
strongLabel
="Forte”
promptLabel
="Informe uma senha"
inline
="true“
match
="confirmacaoSenha"
/>
<
p:outputLabel
value
="Confirme a senha"
for
="confirmacaoSenha"
/>
<
p:password
id
="confirmacaoSenha"
required
="true"
/>
<p:textarea>
•
Componente com extensões do JSF padrão com contador
de caracteres, autocomplete e autoresize (por padrão)
<
p:outputLabel
value
="Sobre você"
for
="sobre"
/>
<
h:panelGroup
>
<
p:inputTextarea
id
="sobre"
value
="#{cadastroBean.sobre}“
cols
="40"
rows
="4"
autoResize
="true"
maxlength
="160“
counter
="contador"
counterTemplate
="Restam {0} caracteres"
completeMethod
="#{cadastroBean.completarTexto}"
/> <
br
/>
<
h:outputText
id
="contador"
/>
</
h:panelGroup
>
public List<String> completarTexto(String consulta) {
List<String> resultados = new ArrayList<String>();
if (consulta.startsWith("Br")) {
resultados.add("Bruno");
resultados.add("Bruno Ferreira"); }
return resultados;
<p:calendar>
•
Componente para manipulação de data e hora
<
p:outputLabel
value
="Data de nascimento"
for
="dataNascimento"
/>
<
p:calendar
id
="dataNascimento"
required
="true“
value
="#{cadastroBean.nasc}"
pattern
="dd/MM/yyyy"
readonlyInput
="true"
navigator
="false"
pages
="1"
m
ode
="popup”
maxdate
="#{cadastroBean.dataHoje}"
locale
="pt"
/>
<!-- mode="inline" pattern="dd/MM/yyyy HH:mm:ss" -->
public
Date getDataHoje() {
return new
Date();
<p:calendar>
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script> PrimeFaces.locales['pt'] = { closeText: 'Fechar', prevText: 'Anterior', nextText: 'Próximo', currentText: 'Começo', monthNames:
['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun', 'Jul','Ago','Set','Out','Nov','Dez'],
dayNames: ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado'], dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'],
dayNamesMin: ['D','S','T','Q','Q','S','S'], weekHeader: 'Semana', firstDay: 0, isRTL: false, showMonthAfterYear: false, yearSuffix: '', timeOnlyTitle: 'Só Horas', timeText: 'Tempo', hourText: 'Hora', minuteText: 'Minuto', secondText: 'Segundo', ampm: false, month: 'Mês', week: 'Semana', day: 'Dia',
allDayText : 'Todo o Dia‘
};
</script> </h:head>
Script para tradução
dos textos do
<p:selectOneListbox>
•
Componente de seleção, estende o padrão JSF
disponibilizando criação de colunas e converters.
<p:outputLabel value="Interesse" for="interesse" /> <p:selectOneListbox id="interesse"
value="#{perfilUsuarioBean.interesse}" required="true"
converter="interesse" var="i" style="width: 200px"> <f:selectItems value="#{perfilUsuarioBean.interesses}"
var="interesse" itemLabel="#{interesse.descricao}"
itemValue="#{interesse}" /> <p:column>
<h:graphicImage library="imagens" name="#{i.nomeIcone}.jpg" /> </p:column>
<p:column>
<h:outputText value="#{i.descricao}" /> </p:column>
<p:selectOneListbox>
public class
Interesse
implements
Serializable {
private
String
descricao
;
private
String
nomeIcone
;
…}
private
Interesse
interesse
;
public static final
List<Interesse>
INTERESSES
=
new
ArrayList<>();
static
{
INTERESSES
.add(
new
Interesse(
"Esportes"
,
"esportes"
));
INTERESSES
.add(
new
Interesse(
"Computação"
,
"computacao"
));
INTERESSES
.add(
new
Interesse(
"Cinema"
,
"cinema"
));
}
Interessa.java
CadastroAlunoBean.java
<p:selectOneListbox>
InteresseConverter.java
@FacesConverter
(
"interesse"
)
public class
InteresseConverter
implements
Converter {
@Override
public
Object getAsObject(FacesContext
context
, UIComponent
comp
,
String
value
) {
if
(
value
!=
null
) {
for
(Interesse
interesse
: CadastroAlunoBean.
INTERESSES
) {
if
(
value
.equals(
interesse
.getNomeIcone())) {
return
interesse
;
} }
}
return null
;
}
@Override
public
String getAsString(FacesContext
context
, UIComponent
comp
,
Object
value
) {
if
(
value
!=
null
) {
Interesse
interesse
= (Interesse)
value
;
return
interesse
.getNomeIcone(); }
return null
; }
}
<p:inputMask>
•
Criando mascará de entrada para os dados. O
primefaces utiliza o JQuery para a formatação.
<p:outputLabel value="Telefone" for="telefone" />
<p:inputMask id="telefone" value="#{cadastroBean.telefone}"
mask="(99) 9999-9999" />
<p:outputLabel value="Telefone comercial" for="telefoneComercial" /> <p:inputMask id="telefoneComercial"
value="#{cadastroBean.telefoneComercial}"
mask="(99) 9999-9999? x9999" /> <p:outputLabel value="Matrícula" for="matricula" />
<p:inputMask id="matricula" value="#{perfilUsuarioBean.matricula}"
mask="aaa*-9999" placeHolder="X" />
Ramal
opcional
Campo
numérico
3 letras, 1
alfanumérico e 4
números
< p:selectBooleanCheckbox >
<
p:outputLabel
value
=""
/>
<
h:panelGroup
>
<
p:selectBooleanCheckbox
id
="aceito"
value
="#{cadastroAlunoBean.aceito}"
/>
<
p:outputLabel
value
="Aceito os termos de serviço"
for
="aceito"
style
="
margin-left
:
5px
"
/>
</
h:panelGroup
>
Campo do tipo
Booleano
<p:selectOneRadio>
<p:outputLabel value="Sexo" for="sexo" />
<p:selectOneRadio id="sexo" value="#{cadastroAlunoBean.sexo}"
required="true” styleClass="sem-bordas"
layout="pageDirection">
<f:selectItem itemLabel="Masculino" itemValue="M" /> <f:selectItem itemLabel="Feminino" itemValue="F" /> </p:selectOneRadio>
<
style
>
.sem-bordas td
{
border
:
none
;
padding
:
5px
;
}
</
style
>
Script CSS com uma
classe para retirar as
bordas das células de
uma tabela
Utilizando
a classe
<p:selectOneRadio >
•
Customizando o layout do componente
<p:outputLabel value="Estado civil" for="estadoCivil" /> <h:panelGroup>
<p:selectOneRadio id="estadoCivil"
value="#{cadastroAlunoBean.estadoCivil}" required="true"
layout="custom">
<f:selectItem itemValue="solteiro" /> <f:selectItem itemValue="casado" />
<f:selectItem itemValue="divorciado" /> </p:selectOneRadio>
<h:panelGrid columns="3" styleClass="sem-bordas"
rowClasses="cel-radio">
<p:radioButton id="opt1" for="estadoCivil" itemIndex="0" /> <p:radioButton id="opt2" for="estadoCivil" itemIndex="1" /> <p:radioButton id="opt3" for="estadoCivil" itemIndex="2" /> <p:outputLabel value="Solteiro" for="opt1" />
<p:outputLabel value="Casado" for="opt2" />
<p:outputLabel value="Divorciado" for="opt3" /> </h:panelGrid>
</h:panelGroup>
.cel-radio td {
text-align: center;
}
Máscara de dinheiro com JQuery
http://plentz.github.io/jquery-maskmoney/
No GitHub baixe o
arquivo chamado
jquery.maskMoney.js e
salve-o na pasta
/webapp/resources /js
Máscara de dinheiro com JQuery
...
<
script
>
function
configurarMoeda() {
$(
".moeda"
).maskMoney({ decimal:
","
, thousands:
"."
,
allowZero:
true
});
}
$(document).ready(
function
() {
configurarMoeda();
});
</
script
>
</
h:body
>
Qdo o documento
carregar execute a
função
configurarMoeda
Todo componente
com a classe CSS
‘moeda’ deve seguir
Máscara de dinheiro com JQuery
Informa qual campo
terá a máscara
Carrega o script JS na
página
.
..
<
h:outputScript
library
="js"
name
="jquery.maskMoney.js"
/
</
h:head
>
<
h:outputLabel
value
="Renda Mensal:"
for
="rendaMensal"
/>
<
p:inputText
id
="rendaMensal"
required
="true"
label
="Renda Mensal:“
value
="#{cadastroAlunoBean.rendaMensal}"
styleClass
="moeda"
/>
<
p:ajaxStatus
styleClass
="ajax-status"
onsuccess
="configurarMoeda()"
>
Para toda requisição
ajax bem sucedida
devemos configurar a
máscara de moeda
novamente
<p:tabView>
<
p:tabView
activeIndex
="1"
orientation
="top"
effect
="fade"
effectDuration
="fast"
>
<
p:tab
title
="Dados pessoais"
disabled
="false"
>
...
</
p:tab
>
<
p:tab
title
="Contato do responsável"
disabled
="false"
>
...
</
p:tab
>
</
p:tabView
>
bottom,
left, right
normal,
slow
clip, slice, explode,
scale, fold, blind
TabView Dinâmica
Para ter os dados atualizados em cada mudança de aba, configure as
duas propriedades abaixo:
<
p:tabView
dynamic
="true"
cache
="false"
>
<
h:outputText
value
="#{cadastroAlunoBean.dataAtual}"
>
<
f:convertDateTime
pattern
="HH:mm:ss"
/>
</
h:outputText
>public
Date getDataAtual() {
return new
Date();
}
Com a configuração acima e esse trecho de código, a
data será atualizada a cada mudança de aba, caso
<p:dataTable>
<p:dataTable value="#{cadastroBean.alunos}" var="aluno">
<p:column headerText="Matrícula" style="text-align: center" width="90"> <h:outputText value="#{aluno.matricula}"/>
</p:column>
<p:column headerText="Nome">
<h:outputText value="#{aluno.nome}"/> </p:column>
<p:column headerText=“Nasc." width="180" style="text-align: center"> <h:outputText value="#{aluno.nasc}">
<f:convertDateTime pattern="dd/MM/yyyy"/> </h:outputText>
</p:column>
<p:column headerText="Renda" width="140" style="text-align: right"> <h:outputText value="#{aluno.rendaMensal}">
<f:convertNumber type="currency" locale="pt_BR"/> </h:outputText> </p:column> </p:dataTable>
Alinhando e
informando o
tamanho da
coluna
<p:dataTable>
<
p:dataTable
value
="#{cadastroAlunoBean.alunos}"
var
="aluno"
sortBy
="#{aluno.matricula}"
sortOrder
="descending"
>
<
p:column
headerText
="Matrícula"
style
="
text-align
:
center
"
width
="90“
sortBy
="#{aluno.matricula}"
....
Para toda coluna que desejamos
permitir a mudança de
ordenação inserimos esse
atributo.
Para informar a ordenação
padrão e o tipo de ordem da
tabela informamos dois
atributos.
<p:dataTable>
<
p:dataTable
value
="#{cadastroBean.alunos}"
var
="aluno"
sortBy
="#{aluno.matricula}"
sortOrder
="descending"
rows
="10"
paginator
="true"
paginatorPosition
="bottom"
rowsPerPageTemplate
="10, 20, 30"
paginatorAlwaysVisible
="false"
>
Nº de linhas
por página
Tabela terá
paginação?
Posição dos
botões de
paginação: both,
top, bottom
Quando o número de linhas não
excede o número máximo por
página, devemos mostrar os
botões?
Opção para
mudar o nº
de linhas por
página
Paginação
<p:dataTable>
<
p:dataTable
value
="#{cadastroAlunoBean.alunos}"
var
="aluno"
>
<
p:column
headerText
="Matrícula"
style
="
text-align
:
center
"
width
="90“
sortBy
="#{aluno.matricula}"
filterBy
="#{produto.codigo}
<
p:column
headerText
="Nome"
style
="
text-align
:
center
"
width
="90“
sortBy
="#{aluno.nome}"
filterBy
="#{produto.nome}
....
Para toda coluna que desejamos
criar um filtro devemos inserir
esse atributo.
Filtro
<p:menubar>
p:menubar
p:submenu
p:submenu
<p:menubar>
<h:form id="frm-menu">
<p:menubar autoDisplay="false">
<p:submenu label="Cadastros">
<p:submenu label="Funcionário">
<p:menuitem value="Novo" outcome="primefaces01" /> <p:menuitem value="Pesquisa" icon="ui-icon-search"
url="http://www.google.com.br" /> </p:submenu>
</p:submenu>
<p:submenu label="Perfil">
<p:menuitem value="Dados pessoais" /> <p:separator/>
<p:menuitem value="Endereços" /> <p:menuitem value="E-mails" /> </p:submenu>
<p:menuitem value="Sair"/> </p:menubar>
</h:form>
O menu será exibido
qdo o mouse for
posicionado encima
da opção
Uma linha de
separação é exibida
<p:growl>
•
Exibe uma mensagem de feedback aos usuários.
<p:growl>
<p:messages>
<p:growl>
Visível até que
o usuário
feche a msg.
Tempo de
exibição (ms)
<p:tab title="Testando mensagens" disabled="false"> <h:form id="msg-form">
<p:growl autoUpdate="true" life="2000" for="msg2"/> <!-- sticky="true" -->
<p:messages autoUpdate="true" for="msg1"/>
<p:commandButton value="Msg1" action="#{cadastroBean.mostraMsg1}" /> <p:commandButton value="Msg2" action="#{cadastroBean.mostraMsg2}"/> </h:form>
</p:tab>
public
String mostraMsg1(){
FacesMessage
msg
=
new
FacesMessage(FacesMessage.SEVERITY_WARN
,
"Erro 2"
,
"Foi detectado um erro"
);
FacesContext.getCurrentInstance().addMessage(
"msg2"
,
msg
);
return null
;
}
Configura em qual componente será
exibida a mensagem.
<p:dialog>
<h:form id="msg-form">
<p:button value="Exibir" onclick="PF('meuDialogo').show(); return false;"/> <p:button value="Ocultar" onclick="PF('meuDialogo').hide(); return false;"/> <p:dialog header="Meu diálogo"
widgetVar="meuDialogo" draggable="false" resizable="false" modal="false" minimizable="true" maximizable="true" showEffect="shake" hideEffect="explode"> Conteúdo do diálogo </p:dialog> </h:form>
Nome interno para o
diálogo
Exemplo
<script> function tratarInclusaoProduto(args) { if (!args.validationFailed) { PF('inclusaoProdutoDialog').hide(); } } </script> <h:form id="frm"><p:button value="Adicionar produto" onclick="PF('inclusaoProdutoDialog').show();
return false;" /> <p:dataTable value="#{produtoBean.lista}" var="produto" id="produtosTable“
emptyMessage="Não existem produtos." style="width: 600px; margin-top: 5px;"> <p:column headerText="Código">
<h:outputText value="#{produto.codigo}"/> </p:column>
<p:column headerText="Nome">
<h:outputText value="#{produto.nome}"/> </p:column>
<p:column headerText="Valor" style="text-align: right; with: 200px"> <h:outputText value="#{produto.valor}">
<f:convertNumber type="currency" locale="pt_BR" /> </h:outputText>
</p:column> </p:dataTable>
//continua nó próximo slide...
Caso, não ocorra erros
de validação, feche o
diálogo. Esse
argumento ‘arqs’ é
fornecido pelo
Primefaces.
Exemplo
<p:dialog header="Inclusão de produto" widgetVar="inclusaoProdutoDialog"
modal="true" resizable="false"> <h:panelGroup id="inclusaoPanel">
<p:messages/>
<h:inputHidden value="produtoBean.produto.codigo" /> <h:panelGrid columns="2">
<p:outputLabel value="Nome" />
<p:inputText value="#{produtoBean.produto.nome}" required="true"
requiredMessage="Informe o nome do produto." /> <p:outputLabel value="Valor" />
<p:inputNumber value="#{produtoBean.produto.valor}" required="true“
decimalSeparator="," thousandSeparator="."
requiredMessage="Informe o nome do produto." /> </h:panelGrid>
<p:commandButton value="Salvar" action="#{produtoBean.salvar}“
update="produtosTable inclusaoPanel"
oncomplete="tratarInclusaoProduto(args)" /> </h:panelGroup> </p:dialog> </h:form>
Componente
disponível a
partir da
versão 6.0
<p:confirmDialog>
<p:column width="40">
<p:commandButton icon="ui-icon-trash" process="@this" title="Excluir">
oncomplete="PF('confirmacao').show(); return false;“
<f:setPropertyActionListener
target="#{produtoBean.produtoSelcionado}" value="#{produto}" /> </p:commandButton>
</p:column>
Para inserir um diálogo de confirmação
iremos criar um botão na tabela para excluir
um registro. Nesse caso o nome do
confirmDialog se chama “confirmacao”
<p:confirmDialog>
Cabeçalho e mensagem de confirmação
<p:confirmDialog header="Exclusão de produto"
message="Tem certeza que deseja excluir o produto?
widgetVar="confirmacao">
<p:commandButton value="Sim" action="#{produtoBean.excluiProduto}"
update=":frm:produtosTable" process="@this"
oncomplete="PF('confirmacao').hide()" />
<p:button value="Não" onclick="PF('confirmacao').hide(); return false;" /> </p:confirmDialog>
Exemplo
Inserindo um botão
dentro da tabela para
chamar o diálogo de
editação o registro
<p:column width="40">
<p:commandButton icon="ui-icon-edit“
oncomplete="PF('inclusaoProdutoDialog').show(); return false;"
process="@this" title="Editar" update=":frm:inclusaoPanel"> <f:setPropertyActionListener
target="#{produtoBean.produto}" value="#{produto}" /> </p:commandButton>
Exportando dados do <p:dataTable>
•
Devemos baixar as dependências responsáveis por
exportar os dados.
<dependency>
<groupId>org.apache.poi</groupId> <artifactId>poi</artifactId>
<version>3.14</version> </dependency>
<dependency>
<groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.14</version>
</dependency> <dependency>
<groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>2.1.7</version>
Exportando dados do <p:dataTable>
•
Usar um componente chamado <p:dataExporter>
dentro de um botão ou link sem usar requisição ajax
e com a propriedade imediate igual a true
....
<p:commandLink process="@this" ajax="false" immediate="true"> <h:outputText value="XLS" />
<p:dataExporter type="xls" target="produtosTable"
fileName="alunos” pageOnly="false" /> </p:commandLink> </h:form>