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

Bases de données Delphi Discussion :

Problème d'exportation du DbGrid vers Excel avec caractères arabe.


Sujet :

Bases de données Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Inscrit en
    Mai 2010
    Messages
    407
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 407
    Par défaut Problème d'exportation du DbGrid vers Excel avec caractères arabe.
    Bonjour à tous,
    j'ai une ancienne application réalisée avec delphi 7 et interbase 7.5.
    le charset de la base de données et None .

    lors de l'exportation du DbGrid vers Excel j'ai un Problème avec les caractères arabe.
    voir l'image ci desous.
    avez vous une idées svp?

    Nom : ExcelError.png
Affichages : 556
Taille : 12,2 Ko

  2. #2
    Membre éclairé

    Inscrit en
    Mai 2010
    Messages
    407
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 407
    Par défaut
    J'ai essayé d'utiliser les fichiers CSV au lieu d'Excel,
    ça marche très bien.
    Le seul problème dont j'ai rencontré est le suivant :
    000001 = qui représente un code d'article de caractére ,
    devient 1 lors de l'exportaion vers csv.

  3. #3
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Ton application D7 est réellement localisé en Arabe ou c'est l'encodage par défaut des applications Ansi (configuration Windows)

    Réellement localisé, cela signifie que tu utilises UTF8String, des composants comme TNT Unicode ...
    Si tu utilises des contrôles Delphi VCL, ils sont donc Ansi donc utilise le CharSet défini par l'OS soit "Windows 1256 Arabic"

    Dans le Excel, il y a deux possibilités !
    Le texte montré, je ne sais pas si c'est de l'UTF8 ou juste un encodage Ansi non utilisé

    Soit c'est du Windows 1256 lu comme du Windows 1252
    Normalement Excel se manipule via WideString, je ferais donc une conversion de Ansi 1256 vers UTF8 vers Unicode car je ne crois pas que Delphi 7 sait convertir du Ansi 1256 vers WideChar (quoi que normalement, il devrait)

    Soir c'est de l'UTF8 déjà
    Et là c'est le composant Excel qui n'a pas compris qu'on lui donnait de l'UTF8



    Faudrait savoir comment tu exportes dans Excel
    Tu peux indiquer le type d'une cellule pour la formater en Texte
    Si tu passes par un CSV, tu peux ajouter un ' en premier caractère d'un nombre, Excel va le traiter comme une chaine
    Evidemment, le Format ou OnGetText doit forcer le padding.



    Sinon, ce n'est pas un TDBGrid vers Excel mais un TDataSet vers Excel ... j'utiliserais AsWideString si ça existe en D7



    Dans TSLTExcelDataSetExporter.ViewInExcel fait en X2 donc très simple même pour le Chinois (ce que j'avais), je forçais les colonnes en type Texte via un Excel OLE via dans ce NumberFormat TEXT_FORMAT
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  4. #4
    Membre éclairé

    Inscrit en
    Mai 2010
    Messages
    407
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 407
    Par défaut
    Merci ShaiLeTroll pour la réponse et pour le suivi.
    Voici le bout de code que j'utilise pour l'exportation du dataset vers Excel :

    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
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    var Tab: _workbook;
        Feuil: _worksheet;
        i,j:Integer;
        S:shortstring;
    begin
       try
         LeDetailBL.Close ;
         LeDetailBL.ParamByName('N').AsString := NumBon.Text ;
         LeDetailBL.Open ;
        ExcelApplication1.Connect;
        ExcelApplication1.Visible[0]:=False;
        Tab:=ExcelApplication1.Workbooks.Add(xlWBATWorksheet,0);
        feuil:=Tab.Worksheets[1] as _worksheet;
     
     
              For i:=0 to LeDetailBL.FieldCount-1 do
              begin
                  with Feuil.Range[MonTableau[i+1]+'12',MonTableau[i+1]+'12'] do
                  begin
                     Value[xlRangeValueDefault]:= LeDetailBL.Fields.Fields[i].DisplayLabel;
                     Font.Name:='times new roman';
                     Font.Size:=10;
                     Font.Bold:=True;
                     With Interior do
                     begin
                          ColorIndex := 15;
                          Pattern := xlSolid;
                          PatternColorIndex := xlAutomatic;
                     End;
                     With Borders do
                     begin
                          LineStyle := xlContinuous;
                          Weight := xlThin;
                          ColorIndex := xlAutomatic;
                     End;
                  end;
              end;
              j:=13;
              LeDetailBL.First;
              While not LeDetailBL.Eof do
              begin
                 For i:= 1 To  LeDetailBL.FieldCount Do
                 begin
                   if i = 1 then
                   begin
                    s := MonTableau[i]+inttostr(j);
                        if LeDetailBL.Fields.Fields[i-1].DataType  in [ftCurrency,ftBCD] then
                        begin
                           Feuil.Range[s,s].Value[xlRangeValueDefault] := LeDetailBL.Fields[i-1].AsCurrency;
                        end
                        else
                            if LeDetailBL.Fields.Fields[i-1].DataType  in [ftDate,ftDateTime]then
                            begin
                               Feuil.Range[s,s].NumberFormat  := 'jj/mm/aaaa';
                               Feuil.Range[s,s].Value[xlRangeValueDefault] := LeDetailBL.Fields[i-1].AsDateTime;
                            end
                            else
                              begin
                                 Feuil.Range[s,s].NumberFormat  := '@';
                                 Feuil.Range[s,s].Value[xlRangeValueDefault] := LeDetailBL.Fields[i-1].AsString;
                              end ;
     
                   end
                   else
                   begin
                     s := MonTableau[i]+inttostr(j);
                        if LeDetailBL.Fields.Fields[i-1].DataType  in [ftCurrency,ftBCD] then
                        begin
                           Feuil.Range[s,s].Value[xlRangeValueDefault] := LeDetailBL.Fields[i-1].AsCurrency;
                        end
                        else
                            if LeDetailBL.Fields.Fields[i-1].DataType  in [ftDate,ftDateTime]then
                            begin
                               Feuil.Range[s,s].NumberFormat  := 'jj/mm/aaaa';
                               Feuil.Range[s,s].Value[xlRangeValueDefault] := LeDetailBL.Fields[i-1].AsDateTime;
                            end
                            else
                              begin
                                 Feuil.Range[s,s].NumberFormat  := '@';
                                 Feuil.Range[s,s].Value[xlRangeValueDefault] := LeDetailBL.Fields[i-1].AsString;
                              end ;
     
                   end;
                 end;
                 LeDetailBL.Next;
                 j:=j+1;
              end;
       finally
            ExcelApplication1.Visible[0]:=true;
            ExcelApplication1.Cells.Select;
            ExcelApplication1.Columns.AutoFit;
            ExcelApplication1.Range['A1','A1'].Select;
            ExcelApplication1.Disconnect;
            LeDetailBL.Close ;
       end;

    pour la varibale MonTableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var MonTableau : array [1..26]of string[1]=('A','B','C','D','E','F','G','H','I','J','K','L',
                           'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');

  5. #5
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Pour info

    C'est calculable

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Chr(Ord('A') + I) + '12'


    Sinon, pour le CharSet Ansi ?
    Il est bien en "Windows 1256 Arabic" ?

    Le problème c'est que ta base de donnée doit être en donnée brute Ansi sans savoir le CharSet
    Du coup lorsque tu fais AnsiString vers Variant, sait-il qu'il doit encodé ?

    Comme ce sujet a déjà été traité, je te laisse lire ceci : ecrire sous Exel avec Delphi7 en arabe pour les différents essais

    J'aurais tendance à vérifier la conversion lors de l'affectation d'un Value
    j'utiliserais MultiByteToWideChar

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Value := StringToOleStrCP (CP_ACP, LeDetailBL.Fields[i-1].AsString)
    Et je simplifierais l'utilisation des Range, cela me semble bien compliqué pour rien
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 593
    Billets dans le blog
    65
    Par défaut
    Citation Envoyé par aimer_Delphi Voir le message
    le charset de la base de données est None .
    ça c'est une très mauvaise habitude.
    Est-ce qu'au moins la colonne a une collation ?

    Sinon, est-ce que changer la fonte de la colonne du tableau Excel donne le bon texte ?
    Si Oui, dans ce cas il faudrait prendre en compte également le type texte dans votre routine
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     if LeDetailBL.Fields.Fields[i-1].DataType  in [ftString]
    trouver un moyen de savoir s'il s'agit d'un texte en arabe et changer la fonte de la cellule en conséquence

  7. #7
    Membre éclairé

    Inscrit en
    Mai 2010
    Messages
    407
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 407
    Par défaut
    Bonjour a tous,

    j'ai trouvé cette solution sur notre forum :

    Transfert vers MS Excel - caractères Unicode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Function StringToWideStringEx(const S: String; CodePage: Word): WideString;
          var
             L : Integer;
          begin
             L := MultiByteToWideChar(CodePage, 0, PChar(S), -1, nil, 0);
             SetLength(Result, L-1);
             MultiByteToWideChar(CodePage, 0, PChar(S), -1, PWideChar(Result), L - 1);
          end;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
       LaValeur := StringToWideStringEx(LeDetailBL.Fields[i-1].AsString, 1256);
       //Feuil.Range[s,s].Value[xlRangeValueDefault] := LeDetailBL.Fields[i-1].AsString;
       Feuil.Range[s,s].Value[xlRangeValueDefault] := LaValeur ;
    et ça a l'air de marcher bien .

  8. #8
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 086
    Par défaut
    Ah oui , c' était le sujet que je cherchais où j'avais déjà évoqué MultiByteToWideChar comme la solution, je te conseille tout de même une encapsulation plus complète comme celle de _WStrFromPCharLenCP pour gérer la chaine vide par exemple

    Pour info le code fourni plus haut de _WStrFromPCharLenCP et StringToOleStrCP est directement inspiré de _WStrFromPCharLenCP et StringToOleStr issu de System.pas
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Membre éclairé

    Inscrit en
    Mai 2010
    Messages
    407
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 407
    Par défaut
    Merci beaucoup ShaiLeTroll , pour les réponses et pour le suivi.
    Bonne et excellente journée.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Export de données vers excel avec Spreadsheet_Excel_Writer
    Par callo dans le forum Zend Framework
    Réponses: 3
    Dernier message: 22/05/2009, 16h26
  2. export de données vers excel avec bouton
    Par Kiefer_S dans le forum SAP
    Réponses: 4
    Dernier message: 30/07/2008, 14h20
  3. Problème d'exportation de données vers excel
    Par dubidon dans le forum VB.NET
    Réponses: 12
    Dernier message: 15/06/2007, 10h41
  4. Access, export de données vers Excel - avec Variable
    Par jackfred dans le forum VBA Access
    Réponses: 7
    Dernier message: 04/06/2007, 16h37
  5. exporter mon dbgrid vers excel
    Par nil dans le forum Bases de données
    Réponses: 4
    Dernier message: 29/04/2006, 10h44

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