Share |

sabato 9 gennaio 2010

Java: Leggere Files Excel

Mi capita spesso di dover estrapolare dati da files excel che vengono uploadati da una action Struts. Questa li elabora, li ripresenta in forma tabellare all'interno di una pagina JSP prima di essere inviate CICS aziendale tramite componenti generalmente chiamati Resource Adapters.

Tralasciando la fase di upload, per la quale il framework Struts ed altri mettono a disposizione innumerevole documentazione ed altrettante maniere di eseguirlo, per ciò che riguarda l'elaborazione di un file excel, ad oggi nel mondo Java, che io sappia esistono solo le librerie POI create dalla Jakarta Apache.

Dunque, dopo che il file è stato caricato ed è consistente, è possibile iniziare a trattarlo. Nel mio caso, trattandosi di una Web Application ho riposto le librerie POI nella cartella WEB-INF/lib del mio progetto. Le librerie da me utilizzate sono:

  • poi-2.5.1-final-20040804.jar;
  • poi-contrib-2.5.1-final-20040804.jar;
  • poi-scratchpad-2.5.1-final-20040804.jar


Per chiarezza, le POI sono le librerie utilizzate nel progetto OpenOffice.

Dunque passiamo all'esempio: la classe che qui riporto contiene il minimo necessario per comprendere i passaggi fondamentali alla base del processo di lettura di files excel, infatti ne riceve uno in input, lo legge riga dopo riga, cella dopo cella e ne scrive il contentuto sulla console Java.


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFRow;

public class ExcelConPOI {

public static void main( String [] args ) {
//Poichè andiamo a lavorare con il Filesystem
//dobbiamo prevenire una possibile IOException
try {
//Apriamo uno stream per recuperare il file
InputStream input = new FileInputStream("C://esempio.XLS");

//e lo rendiamo utilizzabile dalle librerie POI
POIFSFileSystem fs = new POIFSFileSystem( input );

//un file excel è un WorkBook contenente diversi fogli
HSSFWorkbook wb = new HSSFWorkbook(fs);

//di cui ne leggiamo il primo
HSSFSheet sheet = wb.getSheetAt(0);

Iterator rows = sheet.rowIterator();

//Iteriamo su tutte le righe del foglio
while( rows.hasNext() ) {    
HSSFRow row = (HSSFRow) rows.next();
System.out.println( "N. Riga = " + row.getRowNum() );

Iterator cells = row.cellIterator();
while( cells.hasNext() ) {

//Per ogni riga scorriamo tutte le celle
HSSFCell cell = (HSSFCell) cells.next();
System.out.println( "N. Cella = "
+ cell.getCellNum() );

/*Per ogni cella verifichiamo la tipologia
*del dato che contiene e lo scriviamo
*nel canale di output */
switch ( cell.getCellType() ) {
case HSSFCell.CELL_TYPE_NUMERIC:
System.out.println(
cell.getNumericCellValue() );
break;
case HSSFCell.CELL_TYPE_STRING:
System.out.println(
cell.getStringCellValue() );
break;
default:
System.out.println(
"unsuported cell type" );
break;
}
}
}     
} catch ( IOException ex ) {
ex.printStackTrace();
}
}
}

Le librerie utilizzate sono open source e molto pratiche, infatti non è stato per niente difficile capirle ed utilizzarle ed ovviamente permettono di fare molte altre cose tra le quali creare files excel ben formattati e complessi e preparare le fasi di stampa degli stessi.

Alla prossima,
MA.

16 commenti:

  1. grazie per l'articolo, mi p stato molto utile.ora xò ho la necessità di cominciare a leggere da una cella in particolare ma non riesco a capire come si fa a dargli le coordinate.

    RispondiElimina
  2. @alescan.

    Ciao, mi fa molto piacere ti sia stato utile.

    Dunque, passando al tuo quesito dovresti prima individuare la riga nel foglio che contiene la cella, o il set di celle, che vuoi leggere.

    Per fare questo, la classe HSSFSheet espone il metodo getRow(int rowIndex), il quale restituisce l'istanza della riga HSSFRow indicata dall'indice rowIndex (che è zero based) .

    Ora che hai ottenuto la riga in cui c'è la cella da leggere, grazie al metodo getCell(int cellnum) esposto dall'istanza HSSFRow, che restituisce un'istanza di HSSFCell, sei in grado di leggere e modificare il contenuto della cella.

    Puoi approfondire la conoscenza delle API Apache seguendo questo link: http://poi.apache.org/apidocs/index.html.

    Ciao.
    MA

    RispondiElimina
  3. per il getrow ho fatto così:
    HSSFRow riga= sheet.getRow(3);

    e non mi da errori mentre per la cella
    HSSFCell cella=sheet.getCell(3);
    mi dice che non trova il metodo getCell nella libreria org.apache......HSSFSheet

    RispondiElimina
  4. @alescan

    E' corretto sia restituisca un'exception:
    la cella è ricavata dalla riga, non dal foglio.

    Quindi prova così:
    HSSFRow riga = sheet.getRow(3);
    HSSFCell cella = riga.getCell(3);

    Ciao
    MA

    RispondiElimina
  5. Salve,vorrei caricare più di un file excel per volta,senza specificare ogni volta il percorso.Come posso fare?
    Grazie Giacomo

    RispondiElimina
  6. @Anonimo
    Ciao Anonimo :)

    Dunque, dovresti istanziare un nuovo File puntando alla cartella che contiene i .xls da caricare, dopo di che ciclando sulla lista dei files presenti nella cartella, e testando l'estensione, puoi caricarli uno alla volta senza conoscerne il nome a priori.

    Questo dovrebbe bastare per soddisfare la tua richiesta.

    Bye
    MA

    PS: la prossima volta non rimanere Anonimo, perchè altrimenti rischi di perderti la risposta al tuo quesito ;)

    RispondiElimina
  7. Come si utilizza sto script?
    Qualcuno lo ha bello e pronto?
    Io non ne capisco molto, uso mac e come server php il MAMP.

    AIUTO!!!

    RispondiElimina
  8. @Luciano

    Ciao Luciano,
    Mi dispiace ma questa classe Java non la puoi utilizzare in ambiente Apache-MySQL-PHP :(

    Essendo una classe Java hai bisogno di un Java container per le web applications oppure di una Java Runtime Edition (JRE).

    Bye
    MA

    RispondiElimina
  9. Ciao, io ho scaricato il file poi-src.....zip e il poi-src......gz
    ma ..... dove devo estrarli?
    grazie infinite

    RispondiElimina
  10. Ciao Anonimo,
    .gz & .zip: volevi proprio essere sicuro, eh? :D


    Cmq,
    per poter utilizzare le librerie POI, una volta scompattato l'archivio (.zip o .gz), estrai i .jar e posizionali in una cartella a cui si fa riferimento nel classpath.

    Bye
    MA

    RispondiElimina
  11. grazie della velocissima risposta !!!
    ma ... ho estratto l'archivio zip e dentro non c'è nessun jar !!!!!

    RispondiElimina
  12. @Anonimo

    Allora hai scaricato i sorgenti.

    Se non è tua intenzione modificarli, ti consiglio di scaricare la _binary_ release e di seguire le precedenti istruzioni.

    Bye
    MA

    RispondiElimina
  13. WOW ! ! ! !
    grazie mille, funziona !!!!!

    RispondiElimina
  14. Scusa,sono sempre io, posso farti una domanda che non c'entra niente?
    ma per me è importante !!! ho disattivato il sottosistema a 16 bit con un eseguibile scaricato; volendolo riattivare come si fa ?
    Per favore, rispondimi, se puoi !!!!
    ciao, grazie !

    RispondiElimina
    Risposte
    1. @Anonimo

      Mi spiace ma non ho nessuna soluzione apprezzabile! :(

      Io proverei a configurare Java dal pannello di controllo di Windows (o Linux ... )

      Ed eventualmente disinstallare l'eseguibile galeotto!

      PS: non hai un backup recente o un punto di ripristino del OS?

      Bye
      MA

      Elimina
  15. L'eseguibile galeotto non c'entra niente col java: volevo soltanto diminuire la vulnerabilità di windows; il ripristino l'ha fatto prima di disattivare; ma nel caso dovessi avere dei problemi ..... volevo evitare di ricorrere al ripristino...
    cmq sei sempre meravigliosamente disponibile e gentile......grazie lo stesso !
    ciao

    RispondiElimina

Non ti è chiaro qualcosa?
No problem, posta il tuo dubbio ;)

..... e ricordati di firmarlo!