JRBean ... DataSource

1 resposta
alessandro.moreira

Saudações,

Tenho encontrado em minhas buscas exemplos usando JRBeanCollectionDataSource ou JRBeanArrayDataSource mas sempre tendo suas EJBQL retornando um Bean, isto permite que o mapeamento dos fields do JasperReport se dê pelos nomes das propriedades, vejamos:
propriedade=textFields, ouja, se tiver um Bean a seguir:

public class Pessoa {
    private String nome;
    ...
}

e fizer um EJBQL abaixo:

List listaNome = em.createQuery("select p from Pessoa p").getResultList();

posso mapear os campos com a proprieades do Bean da seguinte forma: autor=$F{autor}.

Mas como faria o mapeamento no caso de querer apenas algumas propriedades do Bean e não todo o Bean. Por exemplo:

List<Object[]> listaNome = em.createQuery("select p.id as id, p.nome as nome from Pessoa p").getResultList();

Se eu usar:

JRBeanCollectionDataSource sourcePessoa = new JRBeanCollectionDataSource(listaNome);

ou

JRBeanArrayDataSource sourcePessoa = new JRBeanArrayDataSource(listaNome.toArray());

e no relatório tentar obter os campos [color=green]$F{id}[/color] e [color=green]$F{nome}[/color] obtenho a exception:

Agradeço pela ajuda! Isto está atrasando minha tarefa.

1 Resposta

alessandro.moreira

Fico triste que tantos passem mas que não tenho obtido ajuda. Mas bem, estou postando a solução que implementei. Dentro da API do JasperReports não encontrei solução senão fazer uma especialização.

Criei uma especialização do JRDataSource. Veja o código abaixo.

public class JRArrayDataSource implements JRDataSource {

        private Iterator<Object[]> iterator;
        private Object[] cursor;
        private int indice;

        public JRArrayDataSource(List<Object[]> array) {
            super();
            iterator = array.iterator();
        }

        public Object getFieldValue(JRField jrField) throws JRException {
            indice++;
            if (indice < cursor.length) {
                return cursor[indice];
            }
            return null;
        }

        public boolean next() throws JRException {
            boolean retorno = iterator.hasNext();
            if (retorno) {
                cursor = iterator.next();
                indice = -1;
            }
            return retorno;
        }
    }

O que faço aki é iterar a Lista e depois passar ir lendo o array e retornando o valor.
O importante é observar a sequencia dos campos no relatório. A ordem de criação deve bater com a ordem dos elementos no array, aí o mapeamente é feito sem problemas.

Veja o código da geração do relatório abaixo:

public static void gerarRelatorio() throws JRException {
        List<Object[]> array = new ArrayList<Object[]>();
        array.add(new Object[]{new Integer(1), "Alessandro Moreira", "Caldeirão Furado, 13", "32321010"});
        array.add(new Object[]{new Integer(2), "Wolverine", "Escola Xavier, X", "55551234"});
       
        JRArrayDataSource arrayDataSource = new JRArrayDataSource(array);
       
        JasperPrint print = JasperFillManager.fillReport("relatorio/relatorioCliente.jasper", new HashMap<Object, Object>(), arrayDataSource);


        JasperViewer view = new JasperViewer(print);
        view.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        view.setSize(500, 600);

        view.setLocationRelativeTo(null);
        view.setVisible(true);
    }

Espero que seja útil e bom Java para todos.

Criado 27 de abril de 2009
Ultima resposta 28 de abr. de 2009
Respostas 1
Participantes 1