Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Rappresentazione dati in excel

Creazione di un foglio excel e inserimento dei dati nelle relative celle
Creazione di un foglio excel e inserimento dei dati nelle relative celle
Link copiato negli appunti

La rappresentazione dei dati è una tipica funzione di interfaccia, quindi, in ambiente Java, un'operazione svolta dalle pagine JSP. La forma che solitamente utilizziamo è quella degli elenchi, che hanno il compito di introdurre in maniera schematica i dati da mostrare all'utente.

Le tabelle, in questo particolare tipo di rappresentazione, sono lo strumento più adatto, in quanto sono state pensate proprio a questo scopo. In questo articolo ci occuperemo di realizzare un componente che automatizzi la rappresentazione dei dati che la nostra applicazione manipola.

L'idea è quella di creare uno strato di logica software che si occupi di gestire automaticamente la rappresentazione di tutte le entità (in forma di Javabeans) in modo da riutilizzare lo stesso componente lungo tutta l'applicazione con tutti gli oggetti contenitore possibili, senza ogni volta avere la preoccupazione di gestirne la rappresentazione specifica.

Ci occuperemo di un altro aspetto di rappresentazione, ossia quello dell'operazione di esportazione dei dati in un foglio di calcolo (excel). Attraverso l'utilizzo delle API Jakarta POI svilupperemo uno strato di logica che si occuperà di creare un file excel con la formattazione dei dati in forma tabellare, indipendentemente dal tipo di dati utilizzato.

Export dei dati

Esistono diversi progetti open source, dedicati all'integrazione tra Java e la suite di Office, per la creazione di documenti di lavoro. Noi utilizzeremo il progetto Jakarta POI e la parte relativa alla gestione dei file in formato excel.

L'idea che seguiremo sarà: utilizzare uno strumento capace di leggere a runtime le proprietà dei Javabean passati come riferimento, in modo da astrarre al livello più alto, e quindi scrivere le informazioni relative in forma strutturata. Per poter fare ciò diventa indispensabile fare uso della Reflection di Java. Attraverso di essa riusciamo a recuperare una lista di proprietà contenute in qualsiasi oggetto e effettuare la chiamata ai metodi accessori (get e set) attraverso la loro ispezione.

Utilizzando le API del progetto POI, quindi, effettueremo la creazione del documento excel e la scrittura dei dati recuperati tramite Reflection. L'idea è semplice e davvero potente, in quanto alla fine dello sviluppo sarete in grado di utilizzare il software creato con tutti i tipi di oggetti manipolati all'interno della vostra applicazione.

Immaginate quindi di avere un gestionale con entità come Utente, Ordine, Fattura, ecc potrete utilizzare la stessa classe per effettuare l'export della lista di dati in excel. Vediamo quindi la pratica:

Listato 1. Esporta un metodo pubblico per effettuare l'operazione di creazione del foglio di lavoro excel

package it.html.excel;

import org.apache.poi.hssf.usermodel.*;

import it.html.sm.bridge.reflection.ReflectionUtils;
import it.html.sm.javabeans.DataManager;

import java.io.*;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;

//La classe esporta un metodo pubblico per effettuare l'operazione di creazione
//del foglio di lavoro excel, il cui scopo è quello di esportare gli elementi
//contenuti in lista.

public class ExcelExporter{

  //Variabili di istanza: il percorso fisico del file e la lista di beans da rappresentare
  private String nameFile;
  private Collection list;

  //La variabile che virtualizza il foglio di lavoro excel
  private HSSFWorkbook wb;

  public ExcelExporter(String path,String nomeFile,Collection list){
    this.list = list;
    //Il nome fisico del file
    this.nameFile = path + File.separator + nomeFile;
  }
  ..//
}

Creiamo una classe concreta che contenga il riferimento ad una Collection generica ed il nome del file excel che vogliamo creare. Inoltre manteniamo il riferimento a un oggetto di tipo HSSFWorkbook, che è l'oggetto padre da cui recupereremo tutte le funzioni per la formattazione del file excel.

I metodi pubblici esposti sono il metodo di export e il metodo per recuperare il file creato:

Listato 2. Effettua l'operazione di creazione del file excel

//effettua l'operazione di creazione del file excel, la creazione
//dell'intestazione e il popolamento del foglio di lavoro

public void export(String sheetName) throws IOException{
  if (list.isEmpty())
    throw new NoSuchElementException();
  
  //Inizializziamo il foglio di lavoro
  wb = new HSSFWorkbook();
  //Creiamo un foglio associandogli il nome passato in riferimento
  creaFoglio(sheetName);
  //Apro il flusso in scrittura
  java.io.FileOutputStream fileOut = new java.io.FileOutputStream(nameFile);
  //Scrivo il file con il contenuto
  wb.write(fileOut);
  //e chiudo
  fileOut.close();
}

La logica è molto semplice: effettuiamo un controllo per verificare la lista di oggetti, creiamo una nuova istanza di HSSFWorkbook, richiamiamo il metodo privato creaFoglio(), passando il nome del foglio di lavoro, il cui compito è valorizzare il foglio di lavoro con i dati. Questo è il metodo più importante, quello che definisce la formattazione dei dati all'interno del foglio excel, dopo c'è la scrittura del file sul disco rigido (o su un qualunque stream di scrittura, quindi anche un flusso di output criptato, una socket, ...).

Listato 3. Restituisco il file dove abbiamo salvato i dati

public File getExcelFile(){
  return new File(this.nameFile);
}

Il metodo getExcelFile() si occupa di restituire l'istanza del file appena creato.

Listato 4. Creare un foglio di lavoro con il contenuto

private void creaFoglio(String nomeFoglio){
  //Creiamo un foglio di lavoro sul documento padre (wb)
  HSSFSheet foglioDiLavoro=wb.createSheet(nomeFoglio);
  //Creazione dell'intestazione
  creaIntestazione(foglioDiLavoro);
  //Creazione del contenuto
  int righe=creaContenuto(foglioDiLavoro);
  //Creazione di una riga di statistiche
  creaStatistiche(foglioDiLavoro,righe);
}

Il metodo creaFoglio() ha il compito di definire il singolo foglio di lavoro all'interno della cartella di lavoro excel. Ogni cartella può avere più fogli, e attraverso la chiamata al metodo createSheet() definiamo la creazione di un nuovo foglio di lavoro. Nel nostro caso ne creeremo uno solo e dividiamo i compiti per la creazione dell'intestazione, del contenuto e delle statistiche finali tre metodi distinti.

Listato 5. Inserisce gli elementi formattandoli

private void creaIntestazione(HSSFSheet foglioDiLavoro) {
  //Formattiamo il testo come bold
  HSSFCellStyle stile = wb.createCellStyle();
  HSSFFont font = wb.createFont();
  font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
  stile.setFont(font);
  
  //Recuperiamo un'istanza dalla lista per
  //leggere a runtime il nome delle variabili di istanza

  String fields[] = ReflectionUtils.getStringFields(getFirstFromList());
  //Valorizziamo l'intestazione con il nome della proprietà
  //del bean, per ognuna delle proprietà presenti (sconosciute a tempo di compilazione)

  
  //Ci posizioniamo sulla prima riga (numero 0)
  HSSFRow row = foglioDiLavoro.createRow(0);
  //Iteriamo sugli elementi dell'array
  for(int i=0;i<fields.length;i++){
    HSSFCell cell = row.createCell( (short) i);
    cell.setCellStyle(stile);
    cell.setCellValue(new HSSFRichTextString(fields[i]));
  }
}

La logica di sviluppo è davvero semplice: per prima cosa creiamo uno stile grassetto in modo da far risaltare l'intestazione, e poi scriviamo nella prima riga (riga 0) il nome delle proprietà dei bean presenti nella collezione. Attraverso i metodi della classe ReflectionUtils, recuperiamo prima un array contenente il nome delle proprietà. Badate che il metodo getFirstFromList() ha il compito di recuperare un'istanza dalla Collection, in modo da conoscere il tipo concreto e quindi le relative proprietà. Dopodichè effettuiamo un'iterazione sull'array e creiamo una cella attraverso le API (partendo sempre da 0) per ogni suo elemento.

Listato 6. Crea e si sposta nella struttura

private int creaContenuto(HSSFSheet foglioDiLavoro){
  String fields[] = ReflectionUtils.getStringFields(getFirstFromList());
  
  //Iteriamo sugli elementi
  Iterator it=list.iterator();
  //contiamo le righe (considerando anche l'intestazione)
  int cont=1;
  while(it.hasNext()){
    Object elem = it.next();
    //spostiamoci sulla riga
    HSSFRow row = foglioDiLavoro.createRow(cont);
    //Iteriamo sugli elementi dell'array
    for(int i=0;i<fields.length;i++){
      //Recuperiamo il valore del campio iesimo via Reflection
      String value = ReflectionUtils.getProperty(fields[i], elem);
      //e lo settiamo
      HSSFCell cell = row.createCell( (short) i);
      cell.setCellValue(new HSSFRichTextString(value));
    }
    cont++;
  }
  //Restituiamo il numero di elementi inseriti
  return cont;
}

Il metodo che gestisce il contenuto è altresì semplice. Qui manterremo uno stile di default e ci preoccuperemo di iterare su ogni elemento della collezione. Quindi, su ogni elemento effettueremo un'iterazione per effettuare la lettura dei metodi getXYZ(), sempre attraverso reflection. Infine scriviamo il contenuto del valore all'interno della cella. Alla fine restituiamo il numero di oggetti inseriti.

Listato 7. Inserisce il contenuto all'interno delle celle

//Aggiungiamo una semplice formula per il conteggio degli elementi inseriti, settandola dopo RIGHE righe
private void creaStatistiche(HSSFSheet foglioDiLavoro, int righe) {
  //Formattiamo il testo come ROSSO
  HSSFCellStyle stile = wb.createCellStyle();
  HSSFFont font = wb.createFont();
  font.setColor(HSSFFont.COLOR_RED);
  stile.setFont(font);
  
  //Aggiungiamo dopo due righe dalla fine
  HSSFRow row = foglioDiLavoro.createRow(righe+2);
  //Creiamo due colonne
  HSSFCell cell = row.createCell( (short) 0);
  cell.setCellStyle(stile);
  HSSFCell cell2 = row.createCell( (short) 1);
  cell2.setCellStyle(stile);
  //un'etichetta
  cell.setCellValue(new HSSFRichTextString("TOTALE:"));
  //ed una formula
  cell2.setCellFormula("COUNT(A2:A"+(righe)+")");
}

Il metodo creaStatistiche() è stato creato per mostrarvi come sia possibile inserire delle formule all'interno del foglio di lavoro. In questo caso creeremo uno stile con font rosso e, dopo esserci posizionati sulle righe alla fine del documento, creeremo una cella contenente la formula "COUNT(A2:Ai)" in modo da contare il numero di righe inserite. È evidente che in questo caso già conosciamo il numero, ma qui potrete inserire tutte le formule più adatte alle vostre specifiche esigenze.

Per valutare il funzionamento del componente potete utilizzare il seguente main:

Listato 8. Testa il risultato

public static void main(String[]args) throws IOException{
  System.out.println("UNIT TEST");
  Collection aList = DataManager.getData();
  
  //Creo la directory di test, se non esiste
  File dir = new File("c:/poitest");
  dir.mkdir();
  
  ExcelExporter ee=new ExcelExporter("c:/poitest","test.xls",aList);
  ee.export("Test Foglio di Stile");
  
  System.out.println("Apri il file: "+ee.getExcelFile().getPath());
}

Dove la classe DataManager simula la creazione di una serie di oggetti di tipo User (un semplice bean con proprietà: id, nome, cognome).

Il risultato dell'esecuzione darà la creazione di un foglio di calcolo mostrato in immagine:

Figura 1. Il risultato dell'esecuzione del test di unità
Il risultato dell'esecuzione del test di unità

Ti consigliamo anche