/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or any later version. * * Squale is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ /* * Cr�� le 1 sept. 04 * * Pour changer le mod�le de ce fichier g�n�r�, allez � : * Fen�tre>Pr�f�rences>Java>G�n�ration de code>Code et commentaires */ package org.squale.welcom.outils.excel; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.Locale; import java.util.Vector; import jxl.CellView; import jxl.format.Border; import jxl.format.BorderLineStyle; import jxl.write.DateFormat; import jxl.write.DateTime; import jxl.write.Label; import jxl.write.Number; import jxl.write.WritableCellFormat; import jxl.write.WritableFont; import jxl.write.WritableSheet; import jxl.write.WritableWorkbook; import jxl.write.WriteException; import jxl.write.biff.RowsExceededException; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.validator.GenericValidator; import org.apache.struts.util.MessageResources; import org.squale.welcom.outils.Util; import org.squale.welcom.struts.lazyLoading.font.WFontSimulator; import org.squale.welcom.taglib.field.util.LayoutUtils; /** * @author M327836 Pour changer le mod�le de ce commentaire de type g�n�r�, allez � : * Fen�tre>Pr�f�rences>Java>G�n�ration de code>Code et commentaires */ public class ExcelTable { /** logger */ private static Log log = LogFactory.getLog( ExcelTable.class ); /** * Collection a exporter */ private Collection table; /** * Liste des ent�tes a inclure dans le tableau */ private Vector header; /** * hashtable contenant les dateformats */ private final Hashtable writableCellFormat = new Hashtable(); /** * Internationnalisaton */ protected MessageResources resources = null; /** * Locale que la requete */ protected Locale localeRequest = Locale.FRENCH; /** Nombre magique pour la taille des cellules */ private static final double C4 = 3.3; /** * Contruction d'un export table, sous excel */ public ExcelTable() { this( null, null ); } /** * Constructieur d'un export table avec internalionnalisation * * @param res : Bundle * @param loc : locale de la requete */ public ExcelTable( final MessageResources res, final Locale loc ) { header = new Vector(); resources = res; localeRequest = loc; } /** * Ajoute une colonne * * @param key : c'est la cl� du libell� de la colone d�clar� dans l'Application ressources.properties. * @param property : c'est le nom de la propri�t� de bean de la collection � aller chercher. * @param type : type des �lements de la colone (voir constantes de HeaderElement) * @param dateformat : format de la date (simplaeDateFormat) */ public void addHeader( final String key, final String property, final int type, final String dateformat ) { header.add( new HeaderElement( key, property, type, dateformat ) ); } /** * Ajoute une colonne dans l'ent�te * * @param key : c'est la cl� du libell� de la colone d�clar� dans l'Application ressources.properties. * @param property : c'est le nom de la propri�t� de bean de la collection � aller chercher. */ public void addHeader( final String key, final String property ) { header.add( new HeaderElement( key, property ) ); } /** * Ajoute une colonne dans l'ent�te * * @param key : c'est la cl� du libell� de la colone d�clar� dans l'Application ressources.properties. * @param property : c'est le nom de la propri�t� de bean de la collection � aller chercher. * @param type : NUMBER,TEXT,DATE */ public void addHeader( final String key, final String property, final int type ) { header.add( new HeaderElement( key, property, type ) ); } /** * Genere la table au format excel * * @param workbook : Classeur Excel * @throws WriteException : Problmem lors de l'ecriture du flux */ public void writeTable( final WritableWorkbook workbook ) throws WriteException { final int fontSize = 10; final WritableSheet sheet = workbook.createSheet( "Liste", 0 ); final WritableFont arial10pt = new WritableFont( WritableFont.ARIAL, fontSize, WritableFont.NO_BOLD ); final WritableCellFormat allThin = new WritableCellFormat( arial10pt ); allThin.setBorder( Border.ALL, BorderLineStyle.THIN ); allThin.setWrap( true ); // header writeHeader( fontSize, sheet ); final double sizeMax[] = new double[header.size()]; int j = 1; for ( final Iterator iter = table.iterator(); iter.hasNext(); ) { final Object element = iter.next(); int i = 0; for ( final Enumeration e = header.elements(); e.hasMoreElements(); ) { final HeaderElement elem = (HeaderElement) e.nextElement(); final double tmpSize = writeCell( sheet, allThin, element, elem, j, i ); if ( tmpSize > sizeMax[i] ) { sizeMax[i] = tmpSize; } i++; } j++; } // Definition de la largeur des colonnes // On utilise la taille max des cellules + la taille du header for ( int i = 0; i < header.size(); i++ ) { final CellView cv = new CellView(); double maxSize = sizeMax[i]; String libelle = resources.getMessage( localeRequest, ( (HeaderElement) header.get( i ) ).getKey() ); double headSize = WFontSimulator.getSize( libelle ); if ( headSize > maxSize ) { maxSize = headSize; } int colSize = (int) ( maxSize / C4 ); cv.setSize( colSize ); sheet.setColumnView( i, cv ); } } /** * Ecrit le format des cellule * * @param dateFormat dateFormat * @return Cellule format� */ private WritableCellFormat getWritableCellFormat( final String dateFormat ) { final Object returnValue = writableCellFormat.get( dateFormat ); if ( returnValue == null ) { final DateFormat customDateFormat = new DateFormat( dateFormat ); final WritableCellFormat wcl = new WritableCellFormat( customDateFormat ); try { wcl.setBorder( Border.ALL, BorderLineStyle.THIN ); } catch ( final WriteException e ) { log.error( e, e ); } writableCellFormat.put( dateFormat, wcl ); return wcl; } return (WritableCellFormat) returnValue; } /** * Ecrit la valeur d'une cellule * * @param sheet : Feuille Excel * @param cellFormat : Formateg de la cellule * @param element : Element a �crire * @param headerElement : Colonne * @param posY : Position Y de la feuille * @param posX : POsition X de la feuille * @throws WriteException : Probleme sur l'ecriture du flux * @throws RowsExceededException : Trop de lignes * @return : retourne la taille estime en font verdana */ private double writeCell( final WritableSheet sheet, final WritableCellFormat cellFormat, final Object element, final HeaderElement headerElement, final int posY, final int posX ) throws WriteException, RowsExceededException { final Object val = getValue( element, headerElement ); try { if ( val != null ) { switch ( headerElement.getType() ) { case HeaderElement.DATE_HEURE: final DateTime dateHeureCell = new DateTime( posX, posY, (Date) val, getWritableCellFormat( headerElement.getDateHeureFormat() ) ); sheet.addCell( dateHeureCell ); return WFontSimulator.getSize( headerElement.getDateHeureFormat() ); case HeaderElement.DATE: final DateTime dateCell = new DateTime( posX, posY, (Date) val, getWritableCellFormat( headerElement.getDateFormat() ) ); sheet.addCell( dateCell ); return WFontSimulator.getSize( headerElement.getDateFormat() ); case HeaderElement.NUMBER: final Number number = new Number( posX, posY, Double.parseDouble( (String) val ), cellFormat ); sheet.addCell( number ); return WFontSimulator.getSize( number.getContents() ); default: final Label label = new Label( posX, posY, (String) val, cellFormat ); sheet.addCell( label ); return WFontSimulator.getSize( label.getContents() ); } } else { final Label label = new Label( posX, posY, "-", cellFormat ); sheet.addCell( label ); } } catch ( final NumberFormatException nfex ) { nfex.printStackTrace(); String strVal = "-"; if ( val != null ) strVal = (String) val; final Label label = new Label( posX, posY, strVal, cellFormat ); sheet.addCell( label ); } return 0; } /** * Retourne la valeur d'un element Renvoie une date ou une string selon le cas * * @param element : Object * @param headerElement :Property de la colonne * @return : Valeur de l'objet */ private Object getValue( final Object element, final HeaderElement headerElement ) { try { Object value = LayoutUtils.getProperty( element, headerElement.getProperty() ); Object retour = ""; if ( value instanceof Date ) { retour = (Date) value; } else if ( ( headerElement.getType() == HeaderElement.DATE_HEURE || headerElement.getType() == HeaderElement.DATE ) && value instanceof String ) { try { retour = new Date( Long.parseLong( (String) value ) ); } catch ( final NumberFormatException nfe ) { // On a pas un long dans la cha�ne donc on va la parser avec un dateformat // On g�re les deux cas possibles pour �viter au maximum les soucis SimpleDateFormat sdf = null; sdf = Util.formatDtHr; sdf.setLenient( false ); try { retour = sdf.parse( (String) value ); } catch ( final ParseException pe ) { sdf = Util.formatDt; sdf.setLenient( false ); try { retour = sdf.parse( (String) value ); } catch ( final ParseException pe2 ) { log.error( pe2, pe2 ); return null; } } } } else { retour = BeanUtils.getProperty( element, headerElement.getProperty() ); } return retour; } catch ( final Exception ex ) { log.error( ex, ex ); return null; } } /** * Ecrit l'entete des colonne pour l'export excel * * @param fontSize : Taille de la font * @param sheet : Feuille xls * @throws WriteException : Erreur lors de l'�criture de la feuille * @throws RowsExceededException : Trop de lignes */ private void writeHeader( final int fontSize, final WritableSheet sheet ) throws WriteException, RowsExceededException { for ( int i = 0; i < header.size(); i++ ) { final WritableFont arial10ptBold = new WritableFont( WritableFont.ARIAL, fontSize, WritableFont.BOLD ); final WritableCellFormat allThinBold = new WritableCellFormat( arial10ptBold ); allThinBold.setBorder( Border.ALL, BorderLineStyle.THIN ); String libelle = resources.getMessage( localeRequest, ( (HeaderElement) header.get( i ) ).getKey() ); if ( GenericValidator.isBlankOrNull( libelle ) ) { libelle = ( (HeaderElement) header.get( i ) ).getKey(); } final Label label = new Label( i, 0, libelle, allThinBold ); sheet.addCell( label ); } } /** * @return Liste des colonnes du tableau */ public Vector getHeader() { return header; } /** * @return Collection a afficher */ public Collection getTable() { return table; } /** * @param collection Force la liste des en-t�te a afficher */ public void setHeader( final Vector collection ) { header = collection; } /** * @param collection Force la collection */ public void setTable( final Collection collection ) { table = collection; } /** * @return retourne le Bundle pour l'internationnalisation */ public MessageResources getResources() { return resources; } /** * @param pResources Force le bundle */ public void setResources( final MessageResources pResources ) { this.resources = pResources; } /** * @return recupere la locale utilis� */ public Locale getLocaleRequest() { return localeRequest; } /** * @param locale locale utilis� pour les ent�tes */ public void setLocaleRequest( final Locale locale ) { localeRequest = locale; } /** * Classe definissant une collection d'ent�te * * @author M327837 Pour changer le mod�le de ce commentaire de type g�n�r�, allez � : * Fen�tre>Pr�f�rences>Java>G�n�ration de code>Code et commentaires */ public class HeaderElement { /** * Definit le type STRING de la colonne */ public final static int STRING = 1; /** * Definti le type NUMBER de la colonne */ public final static int NUMBER = 2; /** * Definit DATE comme type */ public final static int DATE = 3; /** * Definit DATE comme type */ public final static int DATE_HEURE = 4; /** * Clef dans l'application resources */ private String key; /** * Property du bean pour afficher la colonne */ private String property; /** * Type par default de la colonne (STRING) */ private int type = STRING; /** * Format Date sur l'export */ private String dateFormat = Util.stringFormatDt; /** * Format Date + heure sur l'export */ private String dateHeureFormat = Util.stringFormatDtHr; /** * Contructeur d'une colonne */ public HeaderElement() { } /** * Creation d'une colonne * * @param pKey : Clef dans l'application resources * @param pProperty : Property du bean pour afficher la colonne * @param pType : Type par default de la colonne * @param pDateformat : Format Date sur l'export */ public HeaderElement( final String pKey, final String pProperty, final int pType, final String pDateformat ) { this.key = pKey; this.property = pProperty; this.type = pType; this.dateFormat = pDateformat; } /** * Creation d'une colonne * * @param pKey : Clef dans l'application resources * @param pProperty : Property du bean pour afficher la colonne */ public HeaderElement( final String pKey, final String pProperty ) { this( pKey, pProperty, STRING, Util.stringFormatDt ); } /** * Creation d'une colonne * * @param pKey : Clef dans l'application resources * @param pProperty : Property du bean pour afficher la colonne * @param pType : Type par default de la colonne */ public HeaderElement( final String pKey, final String pProperty, final int pType ) { this( pKey, pProperty, pType, Util.stringFormatDt ); } /** * @return clef de l'entete de la colonne */ public String getKey() { return key; } /** * @return property Nom de la poperty a attaqu� sur le bean pour l'affichage des valeurs */ public String getProperty() { return property; } /** * @param string clef de l'entete de la colonne */ public void setKey( final String string ) { key = string; } /** * @param string Nom de la poperty a attaqu� sur le bean pour l'affichage des valeurs */ public void setProperty( final String string ) { property = string; } /** * @return format de la date pour affichage de la colonne, default jj/mm/yyyy */ public String getDateFormat() { return dateFormat; } /** * @param format format de la date pour affichage de la colonne */ public void setDateFormat( final String format ) { dateFormat = format; } /** * @return type de la colonne (STRING/NUMBER/DATE) */ public int getType() { return type; } /** * @param string type de la colonne (STRING/NUMBER/DATE) */ public void setType( final int string ) { type = string; } /** * @return format de la date pour affichage de la colonne */ public String getDateHeureFormat() { return dateHeureFormat; } /** * @param format format de la date pour affichage de la colonne */ public void setDateHeureFormat( String format ) { dateHeureFormat = format; } } }