iReport + XML

Boa tarde

Estou criando um relatório que a base de dados é um XML, porém existem tags que nesse XML podem estar ou não nesse XML, gostaria de saber se é possível fazer a verificação se essas tags existem, pois se caso nao existir simplesmente o relatorio nao imprime, pois os campos já estão declarados, ou seja, preciso saber se existe para declarar o campo de uma forma automatica, se existir declara, senão, nao declara!

Obrigado

Por que não lê o xml com o java e manda pro relatório um JRBeanCollectionDataSource?

Estou pesquisando sobre o JRBeanCollectionDataSource, porém vejo que preciso transformar as minhas classes em um .jar, coisa em quem JSF (desenvolvimento web) não tenho essa opção, só tenho o .war

Como posso fazer para adicionar a minha classe no meu relatorio via classpath para que possa funcionar?

Obrigado

[quote=josivanl]Estou pesquisando sobre o JRBeanCollectionDataSource, porém vejo que preciso transformar as minhas classes em um .jar, coisa em quem JSF (desenvolvimento web) não tenho essa opção, só tenho o .war

Como posso fazer para adicionar a minha classe no meu relatorio via classpath para que possa funcionar?

Obrigado[/quote]
De onde tirou essa idéia?

De vários exemplos que vi na internet onde é citado que o .jar é adicionar no classpath.

Tentei adicionar um caminho de pastas, porém não consigo usar no meu JavaBean Datasource

Minha estrutura:

Pacote de Codigos-fontes

  • Dacte
    • Tags.java

Adiciono o caminha da pasta no classpath: /mnt/dk-cotrescred/xampp/Acesso_externo/src/java/Dacte

Tentei no JavaBean Datasource:

  • Dacte.Tags
  • Tags
  • Dacte.Tags.java
  • Tags.java

Mas todos os modos ocorreram o mesmo erro de não achar o caminho da classe.

Ah, você não explica.
Independente de ser desktop ou web, você vai precisar colocar os jars do iReport no teu classpath.
Para uma aplicação web você pode fazer isso colocando os jars necessários na pasta WEB-INF/lib da tua aplicação. Elas, automaticamente, serão inseridas no classpath.

Desculpa aí a falha no post!

No meu caso é uma aplicação web e já tenho todas as libs do ireport no meu projeto, mas quando vou declarar a minha classe no ireport ele nao acha

Está faltando alguma coisa? Sempre usei conexão de banco de dados direto JDBC no ireport.

o Jar que estava me referindo seria mais ou menos igual a esse exemplo: http://benignosales.wordpress.com/2011/03/13/jsf-2-0-primefaces-ireport/

Obrigado

Você está lendo e interpretando o exemplo ou apenas tentando pegar partes isoladas?
Já criou a classe que vai receber os valores do xml?
Já colocou os objetos desta classe em uma collection (lista)?

Já, já fiz tudo isso, criei a classe, crie o metodo que faz a chamada do relatorio.

Classe:

public class Tags {

    private XMLIde ide = new XMLIde();
    private Complemento compl = new Complemento();
    private Emitente emit = new Emitente();
    private Expedidor exp = new Expedidor();
    private Recebedor receb = new Recebedor();
    private Remetente rem = new Remetente();
    private Destinatario dest = new Destinatario();
    private ValorPrestacaoServico vprest = new ValorPrestacaoServico();
    private Impostos imp = new Impostos();
    private InformacoesCTe inf = new InformacoesCTe();
    private FaturamentoVeic fat = new FaturamentoVeic();
    //** GETS E SETS
}

Funções:

public void criaRelatorioDacte(String relatorio, Map<String, Object> map, List<Object> listaDados) {
        try {
            byte[] arquivo = new byte[0];
            FacesContext context = FacesContext.getCurrentInstance();
            InputStream isJasper = new FileInputStream(getClass().getResource("/RelCooperados/" + relatorio + ".jasper").toString().replace("file:", "").replace("\\", "/"));
            JasperReport jasperReport = (JasperReport) JRLoader.loadObject(isJasper);


            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, map, new JRBeanCollectionDataSource(listaDados));
            
            arquivo = JasperExportManager.exportReportToPdf(jasperPrint);
            HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
            response.setContentType("application/pdf");
            response.setContentLength(arquivo.length);
            OutputStream saida = response.getOutputStream();
            saida.write(arquivo, 0, arquivo.length);
            saida.flush();
            saida.close();
        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_FATAL, "Erro ao visualizar relatório.", ex.getMessage()));
            return;
        }
    }

    public List<Object> getTags(Tags tag) {
        List<Object> reports = new LinkedList<Object>();

        reports.add((Object) tag);

        return reports;
    }

Passagem de dados e classe para chamada do relatorio:

public void converte() throws MalformedURLException, DocumentException {

        URL url = new URL("file:/home/josivan/xml419960.xml"); //xml2101129
        SAXReader reader = new SAXReader();
        final Document document = reader.read(url);

        Tags tags = new Tags();

        tags.setIde(tagIde(document));
        tags.setCompl(tagCompl(document));
        tags.setEmit(tagEmitente(document));
        tags.setExp(tagExpedidor(document));
        tags.setReceb(tagRecebedor(document));
        tags.setRem(tagRemetente(document));
        tags.setDest(tagDestinatario(document));
        tags.setVprest(tagValorPrestador(document));
        tags.setImp(tagImposto(document));
        tags.setInf(tagInformacoesCTe(document));
        tags.setFat(tagFaturamentoVeic(document));
        
        Funcoes funcao = new Funcoes();
        
        funcao.criaRelatorioDacte("Dacte", null, funcao.getTags(tags));

    }

Postei somente as partes dos metodos que interessa.

Mas essa seria a parte de fonte onde eu faço todo o trabalho de coletar os dados das tags do XML e tudo mais.

O que eu queria fazer é conseguir através dessa classe criada Tags que já criasse todos os campos no meu iReport, declarando eles pelo menos.

Obrigado!

Sinceramente, não entendi.
Até onde eu sei, os relatório jasper são programados (ou você desenha no iReport), definindo o que ele irá mostrar e o que irá esperar como parâmetro (P{}) ou campo (F{}).
Quando você utiliza um JRBeanCollectionDataSource, o bean (ou a classe que você está utilizando como tal) deve ter as propriedades com os mesmos nomes dos fields criados.
Ex.: Se você tem a classe Tags e ela possui os atributos nome e idade, no iReport você cria os fields F{nome} e F{idade}. Com isso o jasper automaticamente associará cada propriedade com seu respectivo field, independente de quantos objetos de Tags sejam passados para o mesmo.

Tudo bem quanto a isso.
Como eu nunca usei esse tipo de conexão e na classe Tags eu criei chamadas para as outras classes, eu queria fazer essa importação via o iReport em desenvolvimento para saber como vai se comportar e declarar os campos.
Não sei se consegui me fazer entender.

Um outro exemplo que vi e tentei fazer seria esse: http://albert-myptc.blogspot.com.br/2011/06/how-toi-make-java-bean-datasource.html
Esse exemplo está usando pastas e não .jar.

Porém no passo 6 não consigo fazer com que apareça os campos

É que você quer os campos prontos e isso não vai acontecer com esta abordagem.
Pegue o iReport, crie um relatório em branco, crie cada F{} e cada P{} esperado, compile e faça as coisas funcionarem.

Isso, gostaria que criasse os campos, pq são muitos é uma estrutura de XML gigante.
Não existe nenhuma forma para que essa criação automatica seja feita?

Por ser totalmente alheio à esse tipo de coisa, eu sinceramente não sei.
Talvez lendo a documentação do iReport você encontre algo. Mas acho difícil.

Ok então, vou fazer um teste.
Minha dúvida seria a seguinte, hoje tenho a seguinte estrutura das minhas classes:

public class Tags {

    private XMLIde ide = new XMLIde();

Classe XMLIde

   public class XMLIde {
    ///********* IDE ******

    private String cUF = "";
    private String cCT = "";
    private String CFOP = "";
    private String natOp = "";
}

Para criar um campo no iReport, tentei fazer da seguinte forma: ide.cUF (já que a classe que estou passando na conexão é a Tags que possui o campo ide), porém simplesmente não gera nada e ocorre o seguinte erro:

java.lang.IllegalStateException: PWC3990: getWriter() has already been called for this response