IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Documents Java Discussion :

[POI] J'obtiens "0" sur les cellules vides


Sujet :

Documents Java

  1. #1
    Candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut [POI] J'obtiens "0" sur les cellules vides
    Bonjour,

    j'utilise POI 3.5 pour lire un fichier XLS (j'ai eu le même problème avec l'API JXL). Pour les colonnes où sont stockés des numériques, quand la cellule est vide, POI tient absolument à me refiler un int qui vaut 0. Impossible d'avoir un "" malgré diverses feintes pour reformater la cellule.

    Franchement je me fiche pas mal si la cellule est un String, une date ou un numérique, je voudrais parser tout mon fichier en String et faire les traitements moi-même ! Je ne veux surtout pas de "switch case" sur les CellType. Car à ce moment le problème est déjà là : ma cellule vide est remplie par un 0.

    Comment faire ?

  2. #2
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Par définition les types primitifs (int, double, float, long, short) ne peuvent pas ne pas avoir de valeur.

    Le code suivant affichera 0;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int a;
    System.out.println(a);
    Donc ton problème ne vient pas de POI mais de ta compréhension des mécanismes de java...

    Tu devrais plutôt aller voir du coté du type CELL_TYPE_BLANK...
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  3. #3
    Candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Merci pour ma compréhension du java... J'ai bien compris pourquoi j'avais "0". Etonnant l'arrogance dans le monde des développeurs.

    Pour reformuler le problème, c'est que Excel (le problème ne vient pas directement de POI) donne automatiquement un format à une cellule. Si une colonne contient des numériques et des cellules vides, les cellules vides prendront le format numérique.

    Et alors quand je récupère le workbook avec POI, impossible de voir ces cellules vides autrement que "0".

    C'est sûr qu'agir directement sur l'XLS pour le reformarter, le transformer en csv ou je ne sais quoi aiderait mais bon...

    EDIT : enfin merci sinok d'avoir répondu. Désolé de me vexer bêtement, c'est moi l'arrogant... qui a perdu toute la journée sur ce problème

  4. #4
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Le CELL_TYPE_BLANK ne fonctionne pas dans ton cas?
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  5. #5
    Candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Les cellules en question sont de type 0, soit CELL_TYPE_NUMERIC.

    Je pense que mon cas est dû au fichier xls lui-même. Mais je suis étonné de ne pas retrouver ce problème sur les forums.

  6. #6
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Etrange ton problème, après quelques test de mon coté, pour les cellules vides deux cas se présentent: dans le cas ou le contenu a été effacé via un delete alors que la cellule était en édition, dans ce cas, c'est analysé comme un type String

    Dans le cas où le delete(suppr) est effectué quand la cellule est sélectionnée mais pas en édition, la cellule disparaît purement et simplement.

    De fait je ne retrouve absolument pas le comportement que tu décris avec la dernière version stable de POI.

    Cf le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    package poi;
     
    import java.io.IOException;
     
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.ss.usermodel.WorkbookFactory;
     
     
     
    public class BlankTest {
     
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Module de remplacement de méthode auto-généré
            try {
                Workbook wb = WorkbookFactory.create(BlankTest.class.getClass().getResourceAsStream("/poi.xls"));
                Sheet sheet = wb.getSheetAt(0);
                System.out.println("nbLignes= "+sheet.getLastRowNum());
                System.out.println("nbLignesPhy= "+sheet.getPhysicalNumberOfRows());
                for (int i = 0; i<sheet.getPhysicalNumberOfRows();i++) {
                    Row r = sheet.getRow(i);
                    System.out.println("nbCols= "+r.getLastCellNum());
                    System.out.println("nbColsPhy= "+r.getPhysicalNumberOfCells());
                    for(int j = 0; j < r.getLastCellNum(); j++) {
                        Cell c = r.getCell(j);
     
     
                        if(c == null) {
                            System.out.print("null ");
                        } else {
     
                            System.out.print("col indx: "+c.getColumnIndex()+" ");
                            System.out.print("cell type: "+c.getCellType()+" ");
                            if(c.getCellType() == Cell.CELL_TYPE_BLANK) {
                                System.out.print("vide");
                            } else if (c.getCellType() == Cell.CELL_TYPE_NUMERIC) {
                                System.out.print("numeric "+c.getNumericCellValue());
                            } else if (c.getCellType() == Cell.CELL_TYPE_STRING) {
                                System.out.print("String "+c.getStringCellValue());
                            }
                            System.out.print(" ");
                        }
                    }
                    System.out.println();
                }
     
            } catch (InvalidFormatException e) {
                // TODO Bloc catch auto-généré
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Bloc catch auto-généré
                e.printStackTrace();
            }
        }
    }
    Utilisé sur le fichier excel en PJ
    Fichiers attachés Fichiers attachés
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    pourriez vous attacher un fichier qui pose problème? ainsi que les coordonées d'une cellule à problème.

  8. #8
    Candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Effectivement sinok, ton fichier fonctionne.
    Quand je le parse avec mon code, pour B2, j'ai une cell null et alors c'est bon. Pourtant quand je vérifie le format de la cellule B2 dans excel, il me met bien un numérique (alors que A3 est vu comme un texte).
    Dans mon fichier, les cellules problématiques sont vues comme "standard".

    J'essaie de vous mettre mon fichier en pièce jointe mais il est trop gros pour developpez.net. du coup j'en crée un autre plus petit en faisant un copier/coller de la première ligne, mais sur ce nouveau fichier, le problème n'apparait plus...
    Je vais essayer de vous mettre un lien vers mon fichier original (pas évident avec la police Internet de mon entreprise).

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Points : 532
    Points
    532
    Par défaut
    Si tu ne souhaite jamais obtenir un 0, tu peux formater ta cellule en CELL_TYPE_BLANK comme le dit sinok.
    Sinon tu pourrais pas tout formater en String et parser en Integer ?

  10. #10
    Candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    @oneagaindoguys

    Oui mais quelles cellules je mets en CELL_TYPE_BLANK ? Celles où je trouve "0" ? Et pour les vrais "0" rentrés par l'utilisateur alors... Tu vois le problème.

    Et sinon quand tu dis, reformate tout en String, tu veux dire dans Excel, je reformate toutes les cellules avant de les envoyer à mon programme ? J'aurais bien aimé ne pas retravailler le fichier d'entrée. Sinon dans le même genre d'idée, je pourrais transformer le fichier en CSV.
    Mais si tu veux dire par là, reformate toutes tes cellules une fois que POI a chargé son workbook, eh ben il est trop tard. Les cellules vides contiennent déjà des "0" et les formater en String n'y change rien.

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par ouechTonton Voir le message

    J'essaie de vous mettre mon fichier en pièce jointe mais il est trop gros pour developpez.net. du coup j'en crée un autre plus petit en faisant un copier/coller de la première ligne, mais sur ce nouveau fichier, le problème n'apparait plus...
    Essayez l'inverse, prenez votre fichier de départ et virez en ce qui est trop gros pour l'attache

  12. #12
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    540
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2009
    Messages : 540
    Points : 532
    Points
    532
    Par défaut
    Citation Envoyé par ouechTonton Voir le message
    @oneagaindoguys

    Oui mais quelles cellules je mets en CELL_TYPE_BLANK ? Celles où je trouve "0" ? Et pour les vrais "0" rentrés par l'utilisateur alors... Tu vois le problème.

    Et sinon quand tu dis, reformate tout en String, tu veux dire dans Excel, je reformate toutes les cellules avant de les envoyer à mon programme ? J'aurais bien aimé ne pas retravailler le fichier d'entrée. Sinon dans le même genre d'idée, je pourrais transformer le fichier en CSV.
    Mais si tu veux dire par là, reformate toutes tes cellules une fois que POI a chargé son workbook, eh ben il est trop tard. Les cellules vides contiennent déjà des "0" et les formater en String n'y change rien.
    Effectivement, une fois converti, le zéro est déjà là, donc tout convertir en String n'est pas une solution.
    Pour savoir quels "0" garder, c'était au cas où il n'y avait jamais un "0" dans le document. Dans quels cas supprimer tous les zéro aurait été suffisant.

    Sinon, j'ai eu un problème similaire dans mon entreprise. J'ai imposé à tout le monde d'utiliser une modèle de document ou tout est formaté en texte. Exel rajoutait des ".0" quand un nombre était entré.

  13. #13
    Candidat au Club
    Inscrit en
    Novembre 2007
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Novembre 2007
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    @tchize_

    ça y est, j'ai pu diminuer la taille du fichier original. Alors par exemple, j'ai le souci pour la cellule Q2
    Fichiers attachés Fichiers attachés

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    je relance l'affaire car mon problème est dans le même ordre d'idée (et pas moyen de trouver la solution sur le net) :

    j'ai un fichier Excel qui contient des nombres mais les cellules n'ont pas été formatées en Numeric.

    Je récupère donc un String avec un getStringCellValue() mais quand je fais un Double.valueOf dessus, il m'annonce un java.lang.NumberFormatException alors qu'il y a bien un chiffre dedans.

    J'ai essayé de formater ma cellule en Numeric mais ça donne la même exception.

    J'ai essayé avec un new Bigdecimal(cell.getStringCellValue()) et là, il m'annonce aussi l'exception mais je récupère la bonne valeur tout de même.

    Je ne comprends pas tout.

  15. #15
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Citation Envoyé par number6six Voir le message
    mais quand je fais un Double.valueOf dessus, il m'annonce un java.lang.NumberFormatException alors qu'il y a bien un chiffre dedans.
    Ce serait bien de donner l'exception en question
    Citation Envoyé par number6six Voir le message
    J'ai essayé avec un new Bigdecimal(cell.getStringCellValue()) et là, il m'annonce aussi l'exception mais je récupère la bonne valeur tout de même.
    Pardon oO?
    Tu ne peux pas avoir à la fois eu une exception et avoir obtenu une objet du constructeur

  16. #16
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Ce serait bien de donner l'exception en question

    Pardon oO?
    Tu ne peux pas avoir à la fois eu une exception et avoir obtenu une objet du constructeur
    désolé, je croyais l'avoir mise mais...

    voilà déjà la fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC)
    	retour = cell.getNumericCellValue();
    else
    	try {
    		retour = Double.valueOf(cellule.getStringCellValue());
    	} catch (Exception e) {
    		System.out.println("Erreur :"+e);
    	}
    et puis en voulant t'afficher quelque chose de clair, j'ai clarifié mon problème et en fait, le problème ne venait pas de Double.valueOf en tant que tel mais le fait qu'une cellule TYPE_BLANK n'est pas de TYPE_STRING, d'où l'exception Erreur :java.lang.NumberFormatException: empty String

    voilà donc la fonction corrigée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    private double StringToDouble(Cell cellule) {
    	double retour = 0;
    	if (cellule.getCellType() == Cell.CELL_TYPE_NUMERIC){
    		retour = cellule.getNumericCellValue();}
    	else if (cellule.getCellType() == Cell.CELL_TYPE_BLANK)
    		{ retour = 0; }
    	else 
    	try {
    		retour = Double.valueOf(cellule.getStringCellValue());
    	} catch (Exception e) {
    		System.out.println("Erreur :"+e);
    	}
    	return retour;
    }
    au delta près que ce n'est pas très beau car je n'ai jamais trop su comment faire avec des variables retour

    merci pour la réponse rapide

  17. #17
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Voilà la version "propre"


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    private double getCellDouble(Cell cellule) {
    	if (cellule.getCellType() == Cell.CELL_TYPE_NUMERIC)
    		return cellule.getNumericCellValue();
    	else if (cellule.getCellType() == Cell.CELL_TYPE_BLANK)
    		return 0;
    	else try {
    		return Double.valueOf(cellule.getStringCellValue());
    	} catch (Exception e) {
    		e.printStackTrace();
    	        return 0;
    	}
    }

  18. #18
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    propre, merci

    et en plus, j'ai compris un autre truc :
    en effet, Eclipse indiquait que ma méthode ne renvoyait pas de valeur
    j'ai donc créé une variable que j'envoyais à la fin en return , et plus d'alarme d'Eclipse
    en fait, il fallait que je mette return partout dans les if et plus besoin de la variable
    merci

Discussions similaires

  1. [DataGridView] ToolTips sur les cellules
    Par Ticoche dans le forum Windows Forms
    Réponses: 2
    Dernier message: 04/01/2008, 09h18
  2. Filtrer sur les données vides dans un formulaire
    Par jevany dans le forum Access
    Réponses: 7
    Dernier message: 29/05/2006, 08h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo