Enregistrer un fichier en format csv

Bonjour,



Est-il possible d'enregistrer des données de types différents (NSString, NSDate, float, etc) se trouvant dans une même NSArray en format csv , afin de pouvoir lire le fichier ainsi créé dans une application telle que Numbers ? SI oui, pourriez-vous s'il vous plaà®t me mettre (ou m'indiquer où trouver) un petit exemple ? Un grand merci image/thumbsup.gif' class='bbc_emoticon' alt=' :D ' />

Réponses

  • Oui c'est possible image/biggrin.png' class='bbc_emoticon' alt=':D' />





    sFileName = /color][color=#713ea3]NSString[/color][color=#000000] [/color]stringWithFormat[color=#000000]:[/color][color=#d12c26]@"DT_Export_%@"[/color][color=#000000], [[/color][color=#713ea3]NSDate[/color][color=#000000] [/color]date[color=#000000] ;


    NSString* path = [NSString stringWithFormat:@%@/%@/%@.csv", NSHomeDirectory(), @Documents, sFileName];


    BOOL success;



    // Crée un objet FileManagerCreate qui va servir à  vérifer le status


    // de la base de données et de la copier si nécessaire


    NSFileManager *fileManager = /color]NSFileManager[color=#000000] [/color][color=#3e1f7c]defaultManager[/color][color=#000000;




    // Vérifie si la BDD a déjà  été créée dans les fichiers system de l'utilisateur


    success = [fileManager fileExistsAtPath:path];



    // Si la BDD existe déjà  "return" sans faire la suite


    if(!success)

    {

    //char *donnees = [data ]


    // Si ce n'est pas le cas alors on copie la BDD de l'application vers les fichiers système de l'utilisateur


    [fileManager createFileAtPath:path contents:nil attributes:nil];


    NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath: path];



    // ici tu mets tes données a exporter séparer d'un ; et de /n

    NSString *donneesExport = @";";



    [handle writeData:[donneesExport dataUsingEncoding:NSUTF8StringEncoding]];


    }
  • Hello,



    Tu as la classe CHCSVParser (lecture et écriture) sur GitHub



    voir ici https://github.com/davedelong/CHCSVParser
  • La mienne est mieux image/biggrin.png' class='bbc_emoticon' alt=':D' />.



    Je savais pas qu'il y avait une class, je vais y jeter un oeil. Merci!
  • Merci infiniment pour vos réponses, rapides, claires et précises. Je vais m'y atteler de ce pas image/implore.gif' class='bbc_emoticon' alt=' o:) ' />
  • Demande de précision à  Bigstorm, à  partir de mon code ci-joint :





    - (NSArray *)filterTheArray:(NSArray *)objects typeOfArray:(NSString *)arrayName

    {

    if (searchString == nil && compteFiltre == nil && posteFiltre == nil && genreFactureFiltre == -1 && beneficiaireFiltre == nil)


    return objects;



    NSMutableArray *filteredObjects = color=#7031a8]NSMutableArray[/color] [color=#3f0b80]arrayWithCapacity[/color]:[objects [color=#3f0b80]count[/color];

    NSEnumerator *objectsEnumerator = [objects objectEnumerator];

    id item;



    if ([arrayName isEqualToString:@mouvement]) {



    while (item = [objectsEnumerator nextObject]) {



    if (item [color=#37595d]mouvementVentile[/color count] > 1 && color=#568186]mainWindow[/color] [color=#3f0b80]firstResponder[/color != prefCompteTable) {



    NSEnumerator *objectsEnumerator = item [color=#37595d]mouvementVentile[/color objectEnumerator];

    id itemVentile;



    while (itemVentile = [objectsEnumerator nextObject]) {



    Mouvements *newMouvement = [color=#568186]Mouvements[/color] [color=#3f0b80]alloc[/color init];

    [newMouvement setNo_mvt:[item no_mvt]];

    [newMouvement setDateMouvement:[item dateMouvement]];

    [newMouvement setCompte:[item compte]];



    if ([itemVentile debitCp] != 0.0)

    [newMouvement setMontantPrim:[itemVentile debitCp]];

    else

    [newMouvement setMontantPrim:[itemVentile creditCp]];



    [newMouvement setMotifPrim:[item motifPrim]];

    [newMouvement setRubrique:[itemVentile rubriqueCp]];

    [newMouvement setMotif:[itemVentile motifCp]];

    [newMouvement setCredit:[itemVentile creditCp]];

    [newMouvement setDebit:[itemVentile debitCp]];



    if ([self respondToFilterOf:0 with:newMouvement] && [self respondToFilterOf:1 with:newMouvement] && [self respondToFilterOf:2 with:newMouvement])

    [filteredObjects addObject:newMouvement];



    [newMouvement release];

    }

    }



    else if ([self respondToFilterOf:0 with:item] && [self respondToFilterOf:1 with:item] && [self respondToFilterOf:2 with:item])


    [filteredObjects addObject:item];

    }

    }

    else if ([arrayName isEqualToString:@facture]) {



    while (item = [objectsEnumerator nextObject]) {

    if ([self respondToFilterOf:3 with:item] && [self respondToFilterOf:4 with:item] && [self respondToFilterOf:5 with:item])


    [filteredObjects addObject:item];

    }



    }



    return filteredObjects;



    }



    puis-je exporter directement la variable filteredObjects ?
  • J'ai fait ça aussi, mais j'ai été très surpris car les tableurs ne se comportent pas tous de la même manière, notamment lorsque des tabulations, des retours à  la ligne ou autres codes sont inclus dans les données.

    J'ai juste un conseil: faire relire le CSV par différents tableurs, Mac et éventuellement PC.

    Excel, Libre office, Open office, Numbers, Ragtime, KOffice, .....
  • Si tu as un MutableArray tu vas être obligé de construire un String en séparant tes éléments avec des ;

    Cela ce fait rapidement dans une boucle for.
  • 'tablier' a écrit:


    J'ai fait ça aussi, mais j'ai été très surpris car les tableurs ne se comportent pas tous de la même manière, notamment lorsque des tabulations, des retours à  la ligne ou autres codes sont inclus dans les données.

    J'ai juste un conseil: faire relire le CSV par différents tableurs, Mac et éventuellement PC.

    Excel, Libre office, Open office, Numbers, Ragtime, KOffice, .....




    Le seul gros problème que j'ai pu rencontrer, c'est lorsque dans ma chaine NSString il y a une partie qui contient un ;

    Il faut vérifier les éléments pour éliminer les ; et les sauts de ligne sinon on peut avoir des surprises...
  • tabliertablier Membre
    avril 2012 modifié #10
    Il faut vérifier les éléments pour éliminer les ; et les sauts de ligne sinon on peut avoir des surprises...
    Ce n'est pas toujours possible car il est valide qu'une phrase contienne des ; cr, lf , tab ....

    Donc la meilleur approche est effectivement de passer par un NString avec un délimiteur de données et un séparateur de valeur. Quelque chose dans le genre:

    "valeur11","valeur12", ...... ,"Valeur1N" CRLF "valeur21","valeur22", ...... ,"Valeur2N" ..... etc

    Peut-être que CR ou LF peuvent être employés seuls.

    Pour ma part, j'avais un panneau de préférences qui permettait à  l'utilisateur de choisir le délimiteur et le séparateur.



    Nota: CSV -> coma separated value -> donc: valeurs séparées par des virgules
  • bonjour, pour le CSV, en général, les champs qui contiennent des virgules sont délimités par des apostrophes, s'il continent eux même des apostrophes, je n'ai pas vérifier mais il convient probablement des les précéder d'un backslash \" (pour analyser les chaines, il est pratique d'utiliser la classe NSScanner).

    Denis
  • Tout d'abord, merci à  Bigstorm, la routine pour créer le fichier fonctionne à  merveille !



    Malheureusement, je rencontre un problème de débutant (cela fait plus de 5 ans que je n'ai plus programmé, et comme je suis 100% autodidacte, c'est grâce à  tous vos conseils que je peux avancer dans mes connaissances image/thumbsup.gif' class='bbc_emoticon' alt='' /> ). Je joins une partie de mon code, ce sera plus explicite et vous pourrez me dire ou je fais la faute !





    - (IBAction)exportAs:(id)sender

    {

    NSEnumerator *objectsEnumerator = color=#568186]filteredArray[/color] [color=#3f0b80]objectEnumerator[/color;

    NSString *stringToExport;





    Mouvements *item;




    while (item = [objectsEnumerator nextObject]) {




    // *** DATES ***




    [stringToExport stringByAppendingString:item [/color][color=#37595d]dateMouvement[/color][color=#000000 descriptionWithCalendarFormat:@%d.%b.%y


    timeZone:nil

    locale:nil]];



    // *** COMPTES ***








    [stringToExport stringByAppendingString:[item rubrique]]; // [item rubrique] renvoi une NSString





    // *** MOTIFS PRIMAIRES ***




    [stringToExport stringByAppendingString:[item motif]]; // [item motif] renvoi une NSString





    // *** CREDITS ***




    [stringToExport stringByAppendingString:/color][color=#7031a8]NSString[/color][color=#000000] [/color]stringWithFormat[color=#000000]:[/color][color=#c82a25]@"%1.2f"[/color][color=#000000],[item [/color][color=#37595d]credit[/color][color=#000000]]; // [item credit] renvoi un // float




    // *** DEBITS ***




    [stringToExport stringByAppendingString:/color][color=#7031a8]NSString[/color][color=#000000] [/color]stringWithFormat[color=#000000]:[/color][color=#c82a25]@"%1.2f"[/color][color=#000000],[item [/color][color=#37595d]debit[/color][color=#000000]];




    }



    Comme résultat, je n'ai strictement rien dans ma variable stringToExport. Je pense que je tourne autour du pot, mais je ne sais plus ou est la faute...



    Merci de me dépanner à  nouveau image/implore.gif' class='bbc_emoticon' alt=' o:) ' />
  • Pour inspecter un objet, je te conseille d'utiliser le débugger.



    Sinon, la méthode stringByAppendingString c'est :

    Returns a new string made by appending a given string to the receiver.



    J'aurai plutôt fait quelque chose comme :

    NSMutableString *stringToExport;



    puis



    [stringToExport appendString:.....]; ou [stringToExport appendFormat:...]; c'est selon.



    La méthode appendString: (de la classe NSMutableString) c'est :

    Adds to the end of the receiver the characters of a given string.





    Dans ton code tu utilises une méthode qui te retourne un string dont tu ne fais rien.
  • <br />
    [stringToExport stringByAppendingString:[[item dateMouvement] descriptionWithCalendarFormat:@&quot;%d.%b.%y&quot;<br />
    timeZone:nil<br />
    locale:nil]];<br />
    

    stringByAppendingString:

    Returns a new string made by appending a given string to the receiver.

    - (NSString *)stringByAppendingString:(NSString *)aString




    Je crois que tu as oublié quelque chose image/biggrin.png' class='bbc_emoticon' alt=':D' />



    En fait, ton code serait correct si tu utilisais NSMutableString ...
  • tabliertablier Membre
    avril 2012 modifié #15
    Je ne suis pas sure, mais ton NSString est un nonMutable donc il ne devrait pas changer!

    D'autre part, (pas sure non plus) il me semble qu'avec un énumérateur tu ne peux pas être sure de l'ordre d'énumération.

    Essayes plus tot comme le dit Kuberman ou comme ci-dessous
    (IBAction)exportAs:(id)sender

    {

    NSEnumerator *objectsEnumerator = [filteredArray objectEnumerator];

    NSString *stringToExport;



    Mouvements *item;



    while (item = [objectsEnumerator nextObject]) {



    // *** DATES ***

    NSString * mouvement = [[item dateMouvement] descriptionWithCalendarFormat:@%d.%b.%y timeZone:nil locale:nil] ;



    // *** COMPTES ***

    NSString * rubric = [item rubrique] ; // [item rubrique] renvoi une NSString



    // *** MOTIFS PRIMAIRES ***

    NSString *motif = [item motif] ; // [item motif] renvoi une NSString



    // *** CREDITS ***

    NSString *credit = [NSString stringWithFormat:@%1.2f,[item credit]] ; // [item credit] renvoi un // float



    // *** DEBITS ***

    NSString * debit = [NSString stringWithFormat:@%1.2f,[item debit]] ;



    // une ligne pour CSV

    stringToExport = [NSString stringWithFormat:@\%@\";,\"%@\";,\"%@\";,\"%@\";,\"%@\";\n", mouvement, rubric, motif, crédit, debit] ;

    }
  • Parfait, en tout cas pour le premier passage de la boucle. Maintenant, comment faire pour qu'aux passages suivants, les données s'ajoutent aux premières, sans les "écraser" ? J'ai essayé en faisant ceci :





    NSString *stringToExport = [color=#7031a8]NSString[/color] [color=#3f0b80]alloc[/color init];



    NSString *aLineOfData;



    début de la boucle



    aLineOfData = [NSString stringWithFormat:@\%@\";,\"%@\";,\"%@\";,\"%@\";,\"%@\";\n", mouvement, rubric, motif, credit, debit] ;



    stringToExport = [aLineOfData stringByAppendingString:aLineOfData];

    fin de boucle



    Mais ça ne fonctionne pas...
  • C'est tout bon. En fait, comme vous le voyez, la faute vient de ma dernière ligne de code, que j'ai corrigé comme cela :



    stringToExport = [stringToExport stringByAppendingString:aLineOfData];



    En tous les cas, un grand merci pour votre aide sans vous... Je serais perdu ! Alors, vive vous image/cliccool.gif' class='bbc_emoticon' alt=' :p ' />
  • Passe ton projet à  l'analyse, car je pense (pas sure) que faire stringByAppendingString dans ce cas, cela doit donner des fuites mémoire. L'autre solution est avec un NSMutableString tell que l'a proposé mpergand. Par exemple:
    IBAction)exportAs:(id)sender

    {

    NSEnumerator *objectsEnumerator = [filteredArray objectEnumerator];

    NSMutableString *stringToExport;

    Mouvements *item;



    stringToExport = [NSMutableString stringWithCapacity:100] ;

    [stringToExport setString:@";"] ;



    while (item = [objectsEnumerator nextObject]) {



    // *** DATES ***

    /size][size=3]stringToExport appendFormat:@&quot;\&quot;%@\&quot;,&quot;, [/size][size=3] [[item dateMouvement] descriptionWithCalendarFormat:@&quot;%d.%b.%y&quot; timeZone:nil locale:nil ;



    // *** COMPTES ***

    /size][size=3]stringToExport appendFormat:@&quot;\&quot;%@\&quot;,&quot;, [/size][size=3] [/size][size=3][item rubrique ; // [item rubrique] renvoi une NSString



    // *** MOTIFS PRIMAIRES ***

    /size][size=3]stringToExport appendFormat:@&quot;\&quot;%@\&quot;,&quot;, [/size][size=3] [/size][size=3][item motif ; // [item motif] renvoi une NSString



    // *** CREDITS ***

    /size][size=3]stringToExport appendFormat:@&quot;\&quot;[/size][size=3]%1.2f[/size][size=3]\&quot;,&quot;, [/size][size=3] [/size][size=3][item credit ; // [item credit] renvoi un float



    // *** DEBITS ***

    /size][size=3]stringToExport appendFormat:@&quot;\&quot;[/size][size=3]%1.2f[/size][size=3]\&quot;\n[/size][size=3]&quot;,[item debit ; // fin de ligne CSV

    }

    }
Connectez-vous ou Inscrivez-vous pour répondre.