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

JavaScript Discussion :

Exporter une <table> vers fichier CSV


Sujet :

JavaScript

  1. #1
    Membre éprouvé Avatar de sebhm
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    1 090
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 090
    Points : 1 241
    Points
    1 241
    Par défaut Exporter une <table> vers fichier CSV
    Bonjour,

    je souhaite réaliser (trouver ? ) une fonction javascript/Ajax qui me permettrait d'enregistrer un fichier CSV contenant les données de ma table HTML.

    a priori :
    (à partir d'un ID d'une table HTML)
    - parse la table
    - ecrit dans un textarea caché ou une variable le contenu du CSV
    - uploade le CSV via AJAX (parce qu'on va avoir du mal à créer un fichier depuis le client)
    - crée le fichier (PHP)
    - le propose au téléchargement (re AJAX)

    j'ai vu quelques trucs intéressants en cherchant, comme la table éditable de bigboomshakala, mais la table est créée en javascript, ce qui n'est pas mon cas.

    D'autres ont deja posé la question, et on leur a répondu (à juste titre)
    "crée ton fichier en PHP !! "

    mes arguments :
    - j'ai toute une application pleine de tableaux à rendre exportables (donc soit je me les tape tous en PHP, soit une superbe fonction javascript prend juste un id en entrée et ca roule)
    - ca me permet de ne pas stocker les pages CSV inutiles (oui c'est vrai, je peux les supprimer la nuit si ca m'embete...) (il me fallait au moins un second argument à part la flemmingite)

    merci de ne pas taper trop fort !

  2. #2
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 637
    Points : 66 656
    Points
    66 656
    Billets dans le blog
    1
    Par défaut
    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
    <script type='text/javascript'>
    function  createCSV(obj){
    var tab=document.getElementById(obj)
    var Tablignes =tab.getElementsByTagName('tr')
     
    var CSVText=""
    var x=0;
     
    while(Tablignes[x]){
    	TabCol=Tablignes[x].getElementsByTagName('td')
    	var ArrLine=new Array()
    	var y=0;
    	while (TabCol[y]){
    		ArrLine.push(TabCol[y].innerHTML);
    		y++
    		}
    		CSVText+='"'+ArrLine.join('";"')+'"\n'
    		x++
    	}
    alert	(CSVText)
    }
     
    </script>
    </head>
     
    <body onload="createCSV('tableau')">
     
    <table id="tableau" border="1" width="100%">
      <tr>
        <td width="20%">un </td>
        <td width="20%">deux</td>
        <td width="20%">trois</td>
        <td width="20%">quatre</td>
        <td width="20%">cinq</td>
      </tr>
      <tr>
        <td width="20%">1</td>
        <td width="20%">2</td>
        <td width="20%">3</td>
        <td width="20%">4</td>
        <td width="20%">5</td>
      </tr>
      <tr>
        <td width="20%">un </td>
        <td width="20%">deux</td>
        <td width="20%">trois</td>
        <td width="20%">quatre</td>
        <td width="20%">cinq</td>
      </tr>
      <tr>
        <td width="20%">1</td>
        <td width="20%">2</td>
        <td width="20%">3</td>
        <td width="20%">4</td>
        <td width="20%">5</td>
      </tr>
    </table>
     
    </body>
    suffit e,suite de faire le send ajax qui pointe sur une page php qui retourne un header de fichier csv et qui fait un echo de ce qu'il reçoit ...
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  3. #3
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 637
    Points : 66 656
    Points
    66 656
    Billets dans le blog
    1
    Par défaut
    le fichier qui envoie les données:
    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
    <html>
     
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>un</title>
    <script type='text/javascript'>
    function  createCSV(obj){
    var tab=document.getElementById(obj)
    var Tablignes =tab.getElementsByTagName('tr')
     
    var CSVText=""
    var x=0;
     
    while(Tablignes[x]){
    	TabCol=Tablignes[x].getElementsByTagName('td')
    	var ArrLine=new Array()
    	var y=0;
    	while (TabCol[y]){
    		ArrLine.push(TabCol[y].innerHTML);
    		y++
    		}
    		CSVText+=ArrLine.join('\t')+'\n'
    		x++
    	}
    document.getElementById("csvText").value=CSVText
    document.forms[0].submit();
    }
     
    </script>
    </head>
     
    <body onload="createCSV('tableau')">
     
    <table id="tableau" border="1" width="100%">
      <tr>
        <td width="20%">un </td>
        <td width="20%">deux</td>
        <td width="20%">trois</td>
        <td width="20%">quatre</td>
        <td width="20%">cinq</td>
      </tr>
      <tr>
        <td width="20%">1</td>
        <td width="20%">2</td>
        <td width="20%">3</td>
        <td width="20%">4</td>
        <td width="20%">5</td>
      </tr>
      <tr>
        <td width="20%">un </td>
        <td width="20%">deux</td>
        <td width="20%">trois</td>
        <td width="20%">quatre</td>
        <td width="20%">cinq</td>
      </tr>
      <tr>
        <td width="20%">1</td>
        <td width="20%">2</td>
        <td width="20%">3</td>
        <td width="20%">4</td>
        <td width="20%">5</td>
      </tr>
    </table>
    <form action="csvexport.php" method="post">
    <input type="hidden" name="csvText" id="csvText"/>
    </form>
     
    </body>
     
    </html>
    le php qui retourne le csv:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <?php
    header ("Content-Type: application/vnd.ms-excel");
    header("Content-disposition: attachement; filename=\"fichier.csv\""); 
    echo ($_POST['csvText']);
    ?>
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  4. #4
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 637
    Points : 66 656
    Points
    66 656
    Billets dans le blog
    1
    Par défaut
    en fait il faut doubler les " dans les cellules
    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
    <script type='text/javascript'>
    function  createCSV(obj){
    var tab=document.getElementById(obj)
    var Tablignes =tab.getElementsByTagName('tr')
     
    var CSVText=""
    var x=0;
     
    while(Tablignes[x]){
    	TabCol=Tablignes[x].getElementsByTagName('td')
    	var ArrLine=new Array()
    	var y=0;
    	while (TabCol[y]){
    		ArrLine.push(TabCol[y].innerHTML.replace(/"/g,'""'));
    		y++
    		}
    		CSVText+='"'+ArrLine.join('","')+'"\r\n'
    		x++
    	}
    document.getElementById("csvText").value=CSVText
     
    document.forms[0].submit();
    }
     
    </script>
    ensuite en fonction des versions d'excel le séparateur peut être , ; voire \t
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  5. #5
    Membre éprouvé Avatar de sebhm
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    1 090
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 090
    Points : 1 241
    Points
    1 241
    Par défaut
    merci docteur, combien je vous dois ?



    c'est quasi parfait.
    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
    <html>
     
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>un</title>
    <script type='text/javascript'>
    function  createCSV(obj){
    var tab=document.getElementById(obj);
    var Tablignes =tab.getElementsByTagName('tr');
     
    var CSVText="";
    var x=0;
     
    while(Tablignes[x]){
    	TabCol=Tablignes[x].getElementsByTagName('td');
    	var ArrLine=new Array();
    	var y=0;
    	while (TabCol[y]){
    		ArrLine.push(TabCol[y].innerHTML+';');
    		y++;
    		}
    		CSVText+=ArrLine.join('\t')+'\n';
    		x++;
    	}
    document.getElementById("csvText").value=CSVText;
    document.forms[0].submit();
    }
     
    </script>
    </head>
     
    <body>
     
    <table id="tableau" border="1" width="100%">
      <tr>
        <td width="20%">un </td>
        <td width="20%">deux</td>
        <td width="20%">trois</td>
        <td width="20%">quatre</td>
        <td width="20%">cinq</td>
      </tr>
      <tr>
        <td width="20%">1</td>
        <td width="20%">2</td>
        <td width="20%">3</td>
        <td width="20%">4</td>
        <td width="20%">5</td>
      </tr>
      <tr>
        <td width="20%">un </td>
        <td width="20%">deux</td>
        <td width="20%">trois</td>
        <td width="20%">quatre</td>
        <td width="20%">cinq</td>
      </tr>
      <tr>
        <td width="20%">1</td>
        <td width="20%">2</td>
        <td width="20%">3</td>
        <td width="20%">4</td>
        <td width="20%">5</td>
      </tr>
    </table>
     
    <p>
    <button onclick="createCSV('tableau')">EXPORTER en CSV</button>
    </p>
     
    <form action="csvexport.php" method="post">
    <input type="hidden" name="csvText" id="csvText"/>
    </form>
     
    </body>
     
    </html>
    j'ai juste mis un bouton pour lancer la génération du fichier (ca c'est mon niveau )
    Je mets le séparateur ';' entre chaque cellule.

    ben c'est super !!

    PS : marrant cette habitude que tu sembles avoir de ne pas mettre les ';' apres les instructions javascript

    Merci encore

  6. #6
    Membre éprouvé Avatar de sebhm
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    1 090
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 090
    Points : 1 241
    Points
    1 241
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TabCol=Tablignes[x].getElementsByTagName('td');
    on peut trouver des <td> ou des <th>, comment gérer cela quand on ne sait pas dans quel ordre ca peut arriver ??

    eventuellement gérer les cellules fusionnées ?

    et existe-t-il une fonction DOM pour tester si c'est un noeud texte à l'interieur de la cellule ?
    (y'a parfois des images dans les cellules, qui n'ont rien à faire dans le CSV)

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 313
    Points : 330
    Points
    330
    Par défaut
    Pour connaitre le type, il faut tester nodeType.
    La fusion des colonnes et lignes, il faut tester colSpan et rowSpan.

    Une petite démonstration sans prétention :
    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
    <html>
    <head>
    <script>
    function tell (oid) {
    	var trs = document.getElementById(oid).getElementsByTagName('TR');
    	for (var i=0, n=trs.length; i<n; i++) {
    		for (var j=0, m=trs[i].childNodes.length; j<m; j++) {
    			alert('c: ' + trs[i].childNodes[j].colSpan + ', r: ' + trs[i].childNodes[j].rowSpan);
    			for (var k=0, l=trs[i].childNodes[j].childNodes.length; k<l; k++) {
    				if (trs[i].childNodes[j].childNodes[k].nodeType == 3) alert(trs[i].childNodes[j].childNodes[k].data);
    			}
    		}
    	} 
    }
    </script>
    </head>
    <body onload="tell('tintin')">
    <table border=1 id="tintin">
    <tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5<br />6</td></tr>
    <tr><td>10</td><td>12</td><td>13</td><td>14</td><td>15<div>16</div></td></tr>
    <tr><td>21</td><th colspan=2>22/23</th><td>24</td><td>25</td></tr>
    </table>
    </body>
    </html>
    Je récupère les items 'TR' ;
    Je parcoure tous les enfants de chaque 'TR', scannant les colS et rowS ;
    Pour chacun de ses enfants, je scan tous les noeuds de type texte.

    A noter :
    - Ligne 1 : 5<br />6. '5' et '6' seront affichés ;
    - Ligne 2 : '16' est pris dans un enfant DIV. Il ne sera pas affiché ;
    - Ligne 3 : un TH en colspan=2. Inexploité, mais parcouru .

    Puisse ceci te donner des pistes

  8. #8
    Rédacteur
    Avatar de Arnaud F.
    Homme Profil pro
    Développeur COBOL
    Inscrit en
    Août 2005
    Messages
    5 183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur COBOL
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 5 183
    Points : 8 873
    Points
    8 873
    Par défaut
    Dans ce cas, je procéderais de la sorte :

    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
     
    function toCSV(id) {
        var table = document.getElementById(id);
        if( ! table) return false;
     
        var row, cell;
        var content = new Array();
        var CSV = '';
     
        for (var i = 0, rows = table.rows.length; i < rows; i++) {
            row = table.rows[i];
            for (var j = 0, cells = row.cells.length; j < cells; j++) {
                cell = row.cells[j];
     
                if(cell.hasChildNodes()) {
                    var element = cell.firstChild; // Recherche d'une balise interne s'il y a
                    while (element && element.nodeType != 1) {
                        element = element.nextSibling;
                    }
     
                    if( ! element || element.tagName.toLowerCase() !== 'img') { // S'il y a une balise interne, on verifie si ca n'est pas une image
                        content.push(cell.innerHTML);
                    }
                }
            }
            CSV += '"' + content.join(';').replace(/"/g, '""') + '"\r\n';
            content.length = 0;
        }
     
        return CSV;
    }
    C'est par l'adresse que vaut le bûcheron, bien plus que par la force. Homère

    Installation de Code::Blocks sous Debian à partir de Nightly Builds

  9. #9
    Membre éprouvé Avatar de sebhm
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    1 090
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 090
    Points : 1 241
    Points
    1 241
    Par défaut
    merci vraiment pour votre aide à tous.

    j'en suis là :
    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
    function createCSV(id) {
      var table = document.getElementById(id);
      if( ! table) return false;
     
      var row, cell;
      var content = new Array();
      var CSV = '';
      var cellContent=new Array();
      var cell_parsed=0;
     
      for (var i = 0, rows = table.rows.length; i < rows; i++) {
        row = table.rows[i];
        for (var j = 0, cells = row.cells.length; j < cells; j++) {
          cell = row.cells[j];
          if(cell.hasChildNodes()) {
            for (k=0;k<cell.childNodes.length;k++) {
              if (cell.childNodes[k].nodeType==3) {
                cellContent.push(cell.childNodes[k].nodeValue);
                cell_parsed++;
              }
            }
            if (cell_parsed==0)
              content.push('');
            else
              content.push(cellContent.join(' '));
            cellContent.length = 0;
            cell_parsed=0;
          }
        }
     
        CSV += content.join(';') + "[[RC]]";
        content.length = 0;
      }
     
      //return CSV;
      document.getElementById("csvText").value=CSV;
      document.getElementById("form_export_csv").submit();
    }
    je m'explique :
    je parcours le tableau avec table.rows et rows[i].cells, ce qui me permet de ne pas me soucier des <td> ou des <th>.
    je teste le type des noeuds afin de ne trouver que les noeuds Texte.
    Ainsi, un contenu '13 <br /> 14' donnera dans le CSV '13 14'.
    De plus, nodeValue va m'écrire des caracteres 'normaux' à la place des entités HTML (&nbsp; &eacute; ...)
    Et si je n'ai aucun noeud fils Texte (on n'a qu'une image), je le detecte et j'ecris un champ vide pour garder ma mise en forme dans mon CSV.
    Le retour à la ligne ne fonctionne pas dans mon fichier CSV (il veut pas comprendre '\n' ou '\r\n' une fois passé la main à PHP). J'ai donc feinté en insérant une chaine particuliere ([[RC]]) que je transforme en PHP.

    ce qu'il me reste à gérer :
    - detecter les colspan rowspan
    - aller lire dans les balises contenues dans les cellules si il y a des champs texte
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <td>toto<br />tata</td>
    donne bien 'toto tata'
    mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <td>toto<span>tata</span></td>
    ne donne que 'toto'
    - et p'etre d'autres trucs ...

  10. #10
    Membre éprouvé Avatar de sebhm
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    1 090
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 090
    Points : 1 241
    Points
    1 241
    Par défaut
    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
    function createCSV(id) {
        var table = document.getElementById(id);
        if( ! table) return false;
     
        var row, cell;
        var content = new Array();
        var CSV = '';
        var cellContent=new Array();
     
        for (var i = 0, rows = table.rows.length; i < rows; i++) {	//parcours lignes
            row = table.rows[i];
            for (var j = 0, cells = row.cells.length; j < cells; j++) {	//parcours cellules
    	    cell = row.cells[j];
                if(cell.hasChildNodes()) {	//si y'a du monde dans la cellule
    				//noeuds fils
    				noeuds_texte_fils(cell, cellContent);
     
    				//contenu de la cellule vers CSV
    				if (cellContent.length==0)	//si rien (<td><img ... /></td>dans la cellule : case vide CSV
    					content.push('');
    				else	//contenu ok
    					content.push(cellContent.join(' '));
     
    				cellContent.length = 0;
                }
    			else	//si rien (<td></td>) dans la cellule : case vide CSV
    				content.push('');
    			//gestion colspan	
    			if (cell.colSpan > 1)
    				for(var c=1;c<cell.colSpan;c++)
    					content.push('');
     
            }
    		//retour chariot apres une ligne
            CSV += content.join(';') + "[[RC]]";
            content.length = 0;
        }
     
    	//on envoie
    	document.getElementById("csvText").value=CSV;
    	document.getElementById("form_export_csv").submit();
    }
     
    /*recherche des noeuds texte fils pour former une chaine de caractere*/
    function noeuds_texte_fils(node, tabtxt) {
    	for (var k=0;k<node.childNodes.length;k++) {	//on cherche les noeuds textes
    		if (node.childNodes[k].nodeType==3) {
    			tabtxt.push(node.childNodes[k].nodeValue);
    		}
    		else
    			if (node.childNodes[k].hasChildNodes())
    				noeuds_texte_fils(node.childNodes[k], tabtxt);
    	}
    }
    - ajout d'une fonction "noeuds_texte_fils" qui va aller chercher tous les noeuds texte fils de maniere recursive
    ainsi une cellule
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <td>TOTO <div>TATA<span> titi</span></div></td>
    donnera la chaine "TOTO TATA titi" en CSV

    - gestion des colspan : on crée des cellules vides derrieres pour conserver la mise en forme du tableau

    Reste à gérer le rowspan : plus compliqué car il faut conserver la valeur pour les lignes suivantes de facon à créer des cellules vides. Et gerer un rowspan+colspan bien sur.

    Mais deja c'est cool !

    merci

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 313
    Points : 330
    Points
    330
    Par défaut
    Une des limites de DOM focalisé d'avantage sur le contenant que le contenu.

    Il est bien plus facile de récupérer une collection de tagName que de #text

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 313
    Points : 330
    Points
    330
    Par défaut
    Une petite solution (FF,Safari. Pas testée sur les autres) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Element.prototype.getElementsByNodeName = function (nodeName) {
    	var list = new Array();
    	list.item = function(i) { return this[i] }; // NodeList
     
    	for (var children=this.childNodes, i=0, n=children.length; i<n; i++) {
    		var item = children.item(i);
    		if (item.nodeName == nodeName) list.push(item);
    		if (item.hasChildNodes()) list = list.concat(item.getElementsByNodeName(nodeName));
    	}
     
    	return list;
    };
    Que tu peux utiliser comme ça, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    var tds = tr.getElementsByNodeName('TD'); //ou ByTagName, sans doute plus rapide car 'natif'
    {pour chaque td de tds :}
        var txts = td.item(i).getElementsByNodeName('#text');
        var str = '';
        for (var i=0, n=txts.length; i<n; i++) str += txts[i].data;

  13. #13
    Membre éprouvé Avatar de sebhm
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    1 090
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 090
    Points : 1 241
    Points
    1 241
    Par défaut
    j'ai pas testé mais ca a l'air beau !

    pourquoi préférer nodeName à nodeType ?

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 313
    Points : 330
    Points
    330
    Par défaut
    Sans doute parce qu'en tant qu'être humain, je retiens mieux '#text' que '3' ou '#document' que '9' et qu'il y a 12 types à connaitre

    On peut aussi créer sur cette base une méthode ByNodeType
    Mais, soyons humain, passons une de ces valeurs qui sera immédiatement lisible par tout le monde :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Node.ELEMENT_NODE
    Node.ATTRIBUTE_NODE
    Node.TEXT_NODE
    Node.CDATA_SECTION_NODE
    Node.ENTITY_REFERENCE_NODE
    Node.ENTITY_NODE
    Node.PROCESSING_INSTRUCTION_NODE
    Node.COMMENT_NODE
    Node.DOCUMENT_NODE
    Node.DOCUMENT_TYPE_NODE
    Node.DOCUMENT_FRAGMENT_NODE
    Node.NOTATION_NODE
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Element.prototype.getElementsByNodeType = function (nodeType) {
    	var list = new Array();
    	list.item = function(i) { return this[i] }; // NodeList
     
    	for (var children=this.childNodes, i=0, n=children.length; i<n; i++) {
    		var item = children.item(i);
    		if (item.nodeType == nodeType) list.push(item);
    		if (item.hasChildNodes()) list = list.concat(item.getElementsByNodeType(nodeType));
    	}
     
    	return list;
    };

  15. #15
    Membre éprouvé Avatar de sebhm
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    1 090
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 090
    Points : 1 241
    Points
    1 241
    Par défaut
    Sans doute parce qu'en tant qu'être humain, je retiens mieux '#text' que '3' ou '#document' que '9' et qu'il y a 12 types à connaitre
    oui, mais tu n'es pas réellement un etre humain, tu es un informaticien

    et à ce titre, tu te dois de préférer les codes numériques, moins sujets à erreur

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 313
    Points : 330
    Points
    330
    Par défaut
    Je reviens là-dessus pour te signaler que le prototypage de Element sous IE7 ne fonctionne pas.
    Il est nécessaire, de plus, de wrapper les couches DOM de base.

    A priori, cela devrait fonctionner sous IE8. En théorie, il intègre le modèle DOM du W3C (dixit Microsoft).

    Woili voilou.

  17. #17
    Membre éprouvé Avatar de sebhm
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    1 090
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 090
    Points : 1 241
    Points
    1 241
    Par défaut
    de wrapper les couches DOM de base
    c'est à dire ?

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 313
    Points : 330
    Points
    330
    Par défaut
    Je n'ai pas fini d'en faire le tour, mais globalement, il s'agit de ré-écrire document.createElement.
    Certains utilisent HTC, d'autres non.

    Le but est de faire retourner un objet Element à la fonction CreateElement.

    Mais il faut voir aussi les document.getElement(s)... et bien sur les Element.getElement(s)...

    Pas mal de boulot pour IE7 en sommes.

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    313
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 313
    Points : 330
    Points
    330
    Par défaut
    Finallement, j'ai trouvé une méthode moins compliquée mais tout de même bien tordue.
    Le hack consiste à utiliser CSS pour aller décorer les éléments.
    (reste plus qu'à bien isoler IE7...)

    Il y a un bémol, j'en parlerais à la fin, j'espère que quelqu'un me proposera une solution.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (function(){
    if (!window.Element) { //IE7 hack...
    	Element = function(){};
    	document.createStyleSheet().addRule('*', 'behavior: expression( void(this.getElementsByNodeName = function(){return Element.prototype.getElementsByNodeName.apply(this, arguments)}) || void(this.getElementsByNodeType = function(){return Element.prototype.getElementsByNodeType.apply(this, arguments)}) || void(this.hasChildNodes = function(){return this.childNodes.length > 0}) )');
    }
    })()
    Comme tu peux le constater, j'ai du aussi ajouter la méthode hasChildNodes, qui bizarrement, ne se trouvait pas implémentée sur certaines balises sans que je puisse déterminer le pourquoi du comment

    Ensuite, on prototype Element comme dans les posts ci-dessus.

    Ok, avec cette méthode, le script est compatible FF, Opera, Safari, Chrome et IE7 MAIS, pour ce dernier, j'ai des résultats aléatoires : Il fonctionne au petit bonheur la chance des rafraichissements.
    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
    ...
    <script type="text/javascript" src="Element.prototype.js"></script>
    <script defer="defer">
    function extrude() {
    var mbody = document.getElementsByTagName('BODY')[0];
    var txt = mbody.getElementsByNodeName('#text');
    var str = '';
    for (var i=0, n=txt.length; i<n; i++) str += txt[i].data;
    alert(str.replace(/[\s]+/g,' '));
    alert(mbody.getElementsByTagName('TD').length);
    }
    </script>
    </head>
    <body onload="extrude()">
    ...
    J'ai tenté de retarder par tous les moyens que je connaissais l'exécution du script, il semble que ce ne soit pas suffisant. Par change, defer est pris en compte sous IE

    Si quelqu'un a une idée, quelque chose que j'aurais loupé, merci de me le dire.

    Une idée pour optimiser la cible du CSS ? ('*' est utilisé. Comment faire pour ne pas prendre les classes ni les IDs par exemple. Ne taper que sur les balises ?)

    (Je vais sortir le hasChilNodes du CSS et adapter mes méthods, pour voir si ça ne l'optimise pas un peu)

    Quelques autres propositions ?

  20. #20
    Membre éprouvé Avatar de sebhm
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2004
    Messages
    1 090
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Landes (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 090
    Points : 1 241
    Points
    1 241
    Par défaut
    t'es foufou non ??

    mal à la tete rien qu'en voyant cette ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    document.createStyleSheet().addRule('*', 'behavior: expression( void(this.getElementsByNodeName = function(){return Element.prototype.getElementsByNodeName.apply(this, arguments)}) || void(this.getElementsByNodeType = function(){return Element.prototype.getElementsByNodeType.apply(this, arguments)}) || void(this.hasChildNodes = function(){return this.childNodes.length > 0}) )');
    j'essaierai de la comprendre un peu plus tard...
    bon courage

Discussions similaires

  1. Exporter une table access en fichier CSV
    Par TheTcha dans le forum Access
    Réponses: 2
    Dernier message: 03/07/2013, 11h05
  2. [PHP 4] Exporter une table dans un fichier .csv
    Par silbano85 dans le forum Langage
    Réponses: 7
    Dernier message: 20/07/2011, 11h27
  3. exporter une table accesse vers fichier
    Par sanfour_walhan dans le forum VB.NET
    Réponses: 7
    Dernier message: 14/06/2011, 16h01
  4. Export Table Acces vers fichier Texte
    Par ston dans le forum Access
    Réponses: 2
    Dernier message: 04/04/2006, 17h21
  5. Mise à jour d'une table avec un fichier csv
    Par blackangel dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 26/05/2005, 14h46

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