Join several Arraylist in one collection

Asked

Viewed 1,060 times

0

It is possible to join 3 Arraylist in a collection and then send as datasource for a report. Or have another way to do this?

I have 3 Arraylist of 3 objects, I wanted the information of these lists all together in a report.

Method of generating the report:

public void gerarRelatorio(List list, int numeroRelatorio) {

    JasperReport report = null;

    try {
        InputStream inputStreamReal = getClass().getResourceAsStream("/br/com/xml/relatorio/RelatorioXml.jrxml");
        report = JasperCompileManager.compileReport(inputStreamReal);
    } catch (JRException ex) {
        Logger.getLogger(frmPegaXml.class.getName()).log(Level.SEVERE, null, ex);
    }

    try {
        JasperPrint print = JasperFillManager.fillReport(report, null, new JRBeanCollectionDataSource(list));
        JasperExportManager.exportReportToPdfFile(print,
                "C:\\relatorios1/RelatorioClientes" + "0000" + numeroRelatorio + ".pdf");
    } catch (JRException ex) {
        Logger.getLogger(frmPegaXml.class.getName()).log(Level.SEVERE, null, ex);
    }

}

Code where you pass the values from the 3 lists to one and send to the report:

JFileChooser chooser = new JFileChooser();
// Possibilita a seleção de vários arquivos
chooser.setMultiSelectionEnabled(true);

// Apresenta a caixa de diálogo
chooser.showOpenDialog(null);

//ListaAuxiliar <----------------
List<List> listaAuxiliar = new ArrayList<List>();

// Retorna os arquivos selecionados. Este método retorna vazio se
// o modo de múltipla seleção de arquivos não estiver ativada.
File[] files = chooser.getSelectedFiles();

for (File argumento : files) {
    System.err.println("Argumentos: " + argumento.getPath());
    caminho = argumento.getPath();
    LeitorXml parser = new LeitorXml();
    LeitorXml1 parser1 = new LeitorXml1();
    LeitorXml2 parser2 = new LeitorXml2();

    try {
        /* List<Cliente> */
        listaContatos = (ArrayList<UnimedGuia>) parser.realizaLeituraXML(caminho);
        listaContatosCabecalho = (ArrayList<UnimedGuiaCabecalho>) parser1.realizaLeituraXML(caminho);
        listaContatosLote = (ArrayList<UnimedGuiaLote>) parser2.realizaLeituraXML(caminho);

        System.out.println("Valores: " + listaContatos);
        System.out.println("Valores1: " + listaContatosCabecalho);
        System.out.println("Valores2: " + listaContatosLote);

        //Adiciona todas as listas  <--------------------
        lista.add(listaContatos);
        lista.add(listaContatosCabecalho);
        lista.add(listaContatosLote);

        listaAuxiliar.add(lista);
        //System.err.println("Lista Auxiliar: "+ listaAuxiliar1);
        System.out.println("Teste Ao Juntar Listas: "+lista);

    } catch (ParserConfigurationException e) {
        System.out.println("O parser não foi configurado corretamente.");
        e.printStackTrace();
    } catch (SAXException e) {
        System.out.println("Problema ao fazer o parse do arquivo.");
        e.printStackTrace();
    } catch (IOException e) {
        System.out.println("O arquivo não pode ser lido.");
        e.printStackTrace();
    }

}

//Enviar o relatório
int nRel = 0;
for (List lst : listaAuxiliar) {
    System.out.println("Numero do rel: " + nRel);
    System.out.println("LST: "+lst);
    gerarRelatorio(lst, nRel);

    nRel++;
}

Isso

is what appears in Exit, when I give System.out.println("LST: "+lst); and then when it enters the method to generate the report it gives that:

ERRO:

  • Guys, the debate here was very extensive and it was moved to the chat. Please resolve the doubts there, and edit the question when everything is clear. Thank you.

1 answer

1


Understand the requirements

From the information available, I could not understand how the information is read and how exactly it should be displayed.

It is a common mistake for programmers to try to change the code to arrive at a satisfactory result without having in mind very clearly what the goal to be achieved and how to treat the available data to reach this goal.

From what I can derive from the context, the idea is something like this:

Read N XML files with guide information, each Guide being composed of some basic information, header and batch, consolidate this information into a single list and generate a report.

Dividing the process into steps

The second point is to define exactly how you intend to do this. If the requirement mentioned above is true, you can think of the following tasks:

  1. Map each XML file to an object or list of domain objects that represent the information of a Guide
  2. Add all information to a list
  3. Generate a report from the list

Mapping the XML

I know there is already a code for this. But it is strange the implementation of the question use 3 different parsers that return 3 different domain objects (UnimedGuia, UnimedGuiaCabecalho and UnimedGuiaLote).

Modeling the Domain Classes

I imagine the 3 classes mentioned above relate in some way.

I may be completely wrong, but it seems UnimedGuia is the "main" entity and may have a header and multiple lots.

If this is the case, it would be better to model the classes like this:

public class UnimedGuia {
    UnimedGuiaCabecalho cabecalho;
    List<UnimedGuiaLote> lotes;
}

If it’s just one batch per tab, it could be like this:

public class UnimedGuia {
    UnimedGuiaCabecalho cabecalho;
    UnimedGuiaLote lote;
}

So at the end you will only need a list of the class UnimedGuia, as each item in the list will already include its header and batch.

Without this relationship, putting Checkbox object in a different list, eventually your logic can get lost and mix lots and headers of different tabs.

Reading the XML correctly

What is in each XML file?

If each XML has only a single tab, then you can return only one simple object and not a list.

Preferably returns the tab already with the header and the(s) batch(s) as mentioned above in the modeling part.

If you have multiple tabs in each XML, then return a list of tabs, but avoid parsing the file multiple times to avoid mixed data problems as mentioned above.

Adding objects to a single list

Consolidating lists is easy, but also confusing if you don’t have well-defined data structures in mind.

First, of course, we need a master list, but before that the most important thing is:

A list of what?

If the answer by a list of guides, then the list will be like this:

List<GuiaUnimed> guias = new ArrayList<>();

Then, at each reading of a guide you need to add it to the main list. If it is a simple tab, use the method add of the list.

Example:

GuiaUnimed guia = parser.lerGuia(arquivo);
guias.add(guia);

However, if several guides are read at the same time, do not use the method add, because this always adds an item to the list. To add multiple items at the same time, use addAll.

Example:

List<GuiaUnimed> guiasLidosDoXML = parser.lerGuias(arquivo);
guias.addAll(guiasLidosDoXML);

The method addAll is equivalent to making a loop in the list of read guides and adding one by one to the main list.

Generating the report

If the idea is to generate only one report, then just pass the list above and that’s it.

On the other hand, if it is necessary to generate multiple reports, then you will need to change the logic I describe in the above topics. However, you will hardly need a list containing multiple lists, as just generate the report within the loop.

  • Before the structure of my project was more or less like this, but as the xml file contains many tags I had this idea. Why Using the DOM API I used this method: NodeList listaContatos = raiz.getElementsByTagName("unimed:demonstrativoAnaliseConta"); But depending on the tag I put it doesn’t take all the information and skip the repeated tags, like the tags with the names of the beneficiaries

  • But I think I will leave the header and the batch as objects, because they do not repeat in xml. The only thing that repeats is the beneficiary that is filled in the Unimedguia Class

  • If I have 2 objects and 1 list, how to pass all of them to the report? I add everything in a single list?

  • @Diegoaugusto If an object is unique in the report you should not pass it as a list on DataSource. Pass it as a parameter in the parameter map.

  • @Diegoaugusto I see that you are having some difficulties in various parts of the code. The problem isn’t exactly in a specific part of the code, like the lists, but it includes a bit of conceptual understanding of your task and goes all the way to Jasper reporting. Maybe it’s better to solve the problem in parts. Create a question about reading the Xmls correctly for your classes with an example of XML and its classes as they are today. Once this is resolved, create another question on how to pass this data to the report.

  • I can already read the xml, get all the tag data and put together a simple report. But this report that I’m trying to put together at the moment is bigger and contains more tags. A tag repeats quite often which is the one that contains the beneficiary’s names. The other tags do not repeat. Briefly what I wanted was the report with the data of the 3 tags and not only of 1 tag, which was how I learned to do.

  • I have not yet tried to go through parameters, but taking into account that I Gero 1 report for each xml read, will it be right?

  • @Diegoaugusto What you pass as Datasource, in this case the list, will detail the report, that is, the items that repeat themselves. What you pass as a parameter does not generate details, but can be accessed from anywhere in the report, as in the header section (header).

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.