Torno a scrivere di excel per terminare la panoramica sull'argomento. Ho già pubblicato un articolo su come estrarre dati da file .xls. Salto a piè pari gli accenni alle librerie POI, perché già presenti nel suddetto articolo, e passo alla descrizione logica dell'esempio che vi esporrò.
Siccome un comune file excel è composto generalmente non solo da uno o più fogli di lavoro ma prima di tutto da un workBook che li contiene, ho deciso di implementare una factory class per la creazione di workbooks e successivamete un'altra per la gestione dei fogli di lavoro. Poi preso da convulsioni ne ho create altre 2 ancora per gestire la creazione delle celle ed il loro style. Tutte queste factory class le ho racchiuse in un package di nome core. Il tutto è poi utilizzato in una banale classe composta dal solo metodo main() che genera e salva sul File System locale il documento excel creato.
Dunque passiamo all'esempio: andando in ordine logico, come ho esposto sopra, partiamo con la classe WorkBookFactory.
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class WorkBookFactory {
public static HSSFWorkbook createDefaultWorkBook(){
return new HSSFWorkbook();
}
public static HSSFWorkbook createComplexWorkBook(int nSheet
,String[] titleSheet,String header,String footer){
//Creo un WorkBook
HSSFWorkbook wb = new HSSFWorkbook();
//Creo n fogli da aggiungere al WorkBook
HSSFSheet[] sheets = new HSSFSheet[nSheet];
//Aggiungo n Sheet al WorkBook
for(int i=0; i<nSheet; i++){
sheets[i] = wb.createSheet(titleSheet[i]);
//Aggiungo Header e Footer ad ogni Sheet
sheets[i] = SheetFactory.addDefaultHeader(sheets[i],header);
sheets[i] = SheetFactory.addDefaultFooter(sheets[i],footer);
}
return wb;
}
}
Come si è potuto notare, all'interno della classe WorkBookFactory ho fatto riferimento a dei metodi statici della classe SheetFactory: questi due metodi creano header e footer del documento. Si può verificare la loro presenza provando a fare un'anteprima di stampa del documento excel.
Passiamo adesso alla seconda classe in ordine logico, appunto la suddetta classe SheetFactory:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFFooter;
import org.apache.poi.hssf.usermodel.HSSFHeader;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.util.Region;
public class SheetFactory {
//Crea un header per la stampa
public static HSSFSheet addDefaultHeader(HSSFSheet s,String header){
HSSFHeader hd = s.getHeader();
hd.setCenter(header);
return s;
}
//Crea un footer per la stampa
public static HSSFSheet addDefaultFooter(HSSFSheet s,String footer){
HSSFFooter f = s.getFooter();
f.setCenter(footer);
return s;
}
//Genera una tabella semplice con dei dati
public static HSSFSheet addDefaultTable(HSSFSheet s,List rows
,int colTop,int rowTop){
Iterator it = rows.iterator();
int y = rowTop;
while(it.hasNext()){
short x = (short)colTop;
HSSFRow row = s.createRow(y);
Object[] obj = (Object[])it.next();
for(int j=0; j<obj.length; j++){
HSSFCell c = row.createCell(x);
c = CellFactory.createDefaultCell(c,obj[j]);
x++;
}
y++;
}
return s;
}
//Genera una tabella formattata con dello stile
public static HSSFSheet addTableWithStyle(HSSFSheet s
,String tableTitle,List rows,int colTop,int rowTop
,HSSFCellStyle st,HSSFFont font){
boolean hasTitle = false;
Iterator it = rows.iterator();
int y = rowTop;
//Titolo Tabella
if(tableTitle != null && tableTitle.length() > 0){
HSSFRow rtit = s.createRow(y);
HSSFCell ctit = rtit.createCell((short)colTop);
ctit = CellFactory.createCellWithStyle(ctit,tableTitle,st,font);
Region r = new Region(y,(short)colTop,colTop+1
,(short)( ( (Object[])rows.get(0) ).length+1) );
s.addMergedRegion(r);
hasTitle = true;
}
while(it.hasNext()){
short x = (short)colTop;
HSSFRow row = s.createRow((hasTitle) ? y+1:y);
Object[] obj = (Object[])it.next();
for(int j=0; j<obj.length; j++){
HSSFCell c = row.createCell(x);
c = (y == rowTop)
? CellFactory.createCellWithStyle(c,obj[j],st,font)
: CellFactory.createDefaultCell(c,obj[j]);
x++;
}
y++;
}
return s;
}
//Simula la base dati con cui caricare i dati nel documento .xls
//Crea 6 celle per ogni riga e restituisce una lista di 4 righe.
public static List caricamentoManuale(){
List rows = new ArrayList();
String[] colTitle = {"Col 1","Col 2","Col 3","Col 4","Col 5","Col 6"};
Object[] cellValue1 = {"Genova",new Double("1.1"),new Double("1.2")
,new Double("1.3"),new Double("1.4"),new Double("1.5")};
Object[] cellValue2 = {"Roma",new Double("2.1"),new Double("2.2")
,new Double("2.3"),new Double("2.4"),new Double("2.5")};
Object[] cellValue3 = {"Milano",new Double("3.1"),new Double("3.2")
,new Double("3.3"),new Double("3.4"),new Double("3.5")};
rows.add(colTitle);
rows.add(cellValue1);
rows.add(cellValue2);
rows.add(cellValue3);
return rows;
}
}
All'interno della classe SheetFactory ho fatto riferimento a metodi statici della classe CellFactory:
il metodo createDefaultCell(HSSFCell c,Object value) che restituisce celle 'normali' ed il metodo
createCellWithStyle(HSSFCell c,Object value,HSSFCellStyle st,HSSFFont font) che restituisce celle formattate con un certo style.
Vediamo come è composta ora la classe CellFactory:
import java.util.Date;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
public class CellFactory {
//Crea una cella senza alcuno style.
//Gestisce il cast degli oggetti + utilizzati
public static HSSFCell createDefaultCell(HSSFCell c,Object value){
if(value instanceof Date) {
c.setCellValue((Date)value); }
else if(value instanceof Double) {
c.setCellValue(((Double)value).doubleValue());}
else c.setCellValue((String)value);
return c;
}
//Crea una cella con uno style predefinito.
//Gestisce il cast degli oggetti + utilizzati
public static HSSFCell createCellWithStyle(HSSFCell c,Object value
,HSSFCellStyle st,HSSFFont font){
c.setCellStyle(CellStyleFactory.getDefaultIntestazione(st,font));
createDefaultCell(c,value);
return c;
}
}E analiziamo anche la classe CellStyleFactory:
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.util.HSSFColor;
public class CellStyleFactory {
public static HSSFCellStyle getDefaultIntestazione(HSSFCellStyle s
, HSSFFont font){
HSSFFont f = font;
f.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
f.setUnderline(HSSFFont.U_SINGLE);
//Prima di settare il colore di sfondo
//devo dichiarare il Pattern usato per riempire la cella
s.setFillPattern(HSSFCellStyle.FINE_DOTS);
s.setFillBackgroundColor(HSSFColor.ORANGE.index);
s.setFont(f);
s.setAlignment(HSSFCellStyle.ALIGN_CENTER);
s.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);
return s;
}
}Non rimane che assemblare il tutto e dare origine alla creazione del file excel.
Di ciò se ne occupa una banale classe, la CreateNewXLS_Example : questa, è composta semplicemente di un costruttore e del metodo main() nel quale creerò fisicamente il file excel contenente 3 fogli di dati. Buona visione.
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import core.SheetFactory;
import core.WorkBookFactory;
public class CreateNewXLS_Example {
public static void main(String[] args) {
HSSFWorkbook wb = WorkBookFactory.createComplexWorkBook(
3,new String[]{"Foglio 1","Foglio 2","Foglio 3"}
,"Default Header - solo per la Stampa"
,"Default Footer - solo per la Stampa");
//Lo style ed il font sono ricavati direttamente dal WorkBook
HSSFCellStyle style = wb.createCellStyle();
HSSFFont font = wb.createFont();
try{
//Creo il file fisico nel filesystem locale
FileOutputStream fileOut =
new FileOutputStream("c://CreateNewXLS_Example.xls");
//Simulo la ricezione dei dati da caricare
List rows = SheetFactory.caricamentoManuale();
//Riempio i fogli con ogni riga che ho a disposizione
//al 1o foglio gli aggiungo degli style
for(int f=0; f<wb.getNumberOfSheets(); f++){
HSSFSheet s = wb.getSheetAt(f);
if(f==0)
s = SheetFactory.addTableWithStyle(
s,"These Dicks!! che Titolo",rows,2,2,style,font);
else
s = SheetFactory.addDefaultTable(s,rows,2,2);
}
//Scrittura del xls e chiusura dell'outputStream
wb.write(fileOut);
fileOut.close();
System.out.println("Fine creazione file.");
}
catch(IOException io){
System.out.println("Eccezione durante la creazione del file:\n\t"
+ io.getMessage());
io.printStackTrace(System.out);
}
}
}Et voilat. Direi che non è stato assolutamente complicato creare il tutto e, ovviamente, si possono creare file meno banali di quello qui presentato. Il tutto è gestito dal programmatore in modo trasparente ed efficiente.
Alla prossima, MA
0 commenti:
Posta un commento
Non ti è chiaro qualcosa?
No problem, posta il tuo dubbio ;)
..... e ricordati di firmarlo!