Categories > TinyButStrong general (FR) >

du CSV au lieu de l'HTML

The forum is closed. Please use Stack Overflow for submitting new questions. Use tags: tinybutstrong , opentbs
By: Lio
Date: 2005-12-09
Time: 14:28

du CSV au lieu de l'HTML

Bonjour,

Mes chers utilisateurs souhaitent obtenir une version "Excel" des rapports HTML que je génère avec bonheur grâce à TBS ( soit-il loué entre tous les saints, Amen ).

Voici donc le résultat actuel en HTML ( j'ai inclu la CSS mais normalement, elle est dans un fichier externe ). C'est un tableau croisé en fait.
<html>
<head>
<style>
a:link {
    font-family: "Trebuchet MS";
    font-size: 12px;
    color: #000080;
    text-decoration: none;
}
a:visited {
    font-family: "Trebuchet MS";
    font-size: 12px;
    color: #000080;
    text-decoration: none;
}
a:hover {
    font-family: "Trebuchet MS";
    font-size: 12px;
    color: #FF0000;
    text-decoration: underline;
}
p {
    font-family: "Trebuchet MS";
    font-size: 12px;
    color: #000080;
    list-style-type: none;
    line-height: 18px;
    text-decoration: none;
    font-weight: normal;
    text-align: justify;

}
.enonce {
    font-family: "Trebuchet MS";
    font-size: 12px;
    color: #008080;
    list-style-type: none;
    text-decoration: none;
    font-weight: normal;
    float: none;
    font-style: normal;
    clear: none;
    text-align: justify;
    background-color: #CCCCCC;
    padding-right: 5px;
    padding-left: 5px;
    border: none;
    padding-top: 2px;
    padding-bottom: 2px;
}
.liste0 {
    font-family: "Trebuchet MS";
    font-size: 12px;
    list-style-type: none;
    text-decoration: none;
    font-weight: normal;
    float: none;
    font-style: normal;
    clear: none;
    text-align: left;
    background-color: #DDDDFF;
    padding-right: 5px;
    padding-left: 5px;
    padding-top: 2px;
    padding-bottom: 2px;
    border-top: none;
    border-right: 1px solid #CCCCCC;
    border-bottom: none;
}
.liste1 {
    font-family: "Trebuchet MS";
    font-size: 12px;
    list-style-type: none;
    text-decoration: none;
    font-weight: normal;
    float: none;
    font-style: normal;
    clear: none;
    text-align: left;
    background-color: #CCCCFF;
    padding-right: 5px;
    padding-left: 5px;
    padding-top: 2px;
    padding-bottom: 2px;
    border-top: none;
    border-right: 1px solid #CCCCCC;
    border-bottom: none;
    border-left: none;
}
.bigtitre {
    font-family: "Trebuchet MS";
    font-size: 16px;
    font-weight: bold;
    text-transform: uppercase;
    color: #0000FF;
    text-align: left;
    letter-spacing: 1mm;
}
</style>
<title>Affichage du rapport</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link href="../physio_ant.css" rel="stylesheet" type="text/css">
</head>
<body>
<p>
<table border="0" cellpadding="0" cellspacing="0">
  <tr>
    <td class="bigtitre">Physioth&eacute;rapie :: Relev&eacute; des activit&eacute;s
      non-th&eacute;rapeutiques :: Back-office</td>

  </tr>
  <tr>
    <td> <p> <a href="liste_physio.php">Liste des physioth&eacute;rapeutes</a>
        - <a href="liste_activite.php">Liste des activit&eacute;s</a> - <a href="liste_rubrique.php">Liste
        des rubriques</a> - <a href="select_rapport.php">G&eacute;n&eacute;rer
        des rapports</a><br>

        <a href="../frontof/liste_physio_front.php">Allez au Front-Office</a></p></td>
  </tr>
  <tr>
    <td class="bigtitre">&nbsp;</td>
  </tr>
</table>
</p>
<p>P&eacute;riode du 01.01.2005 au 31.01.2005</p>
<table border="0" cellspacing="0" cellpadding="2">
  <tr>
    <td class='enonce' nowrap><strong>Rapport d'activité</strong></td>

    <td class='enonce' nowrap>Aichele A.</td><td class='enonce' nowrap>Broulis B.</td><td class='enonce' nowrap>De Bernardini J.L.</td>
    <td class='enonce' nowrap><strong>Total</strong></td>
  </tr>
  <tr>
    <td class='liste0' nowrap>Communications verbales et &eacute;crites au sujet d'un patient</td>
    <td class='liste0' nowrap><div align="right">10:20</div></td><td class='liste0' nowrap><div align="right">01:15</div></td><td class='liste0' nowrap><div align="right">05:10</div></td>

    <td class='liste0' nowrap><div align="right"><strong>16:45</strong></div></td>
  </tr><tr>
    <td class='liste1' nowrap>Colloques et discussions</td>
    <td class='liste1' nowrap><div align="right">00:00</div></td><td class='liste1' nowrap><div align="right">00:00</div></td><td class='liste1' nowrap><div align="right">00:00</div></td>
    <td class='liste1' nowrap><div align="right"><strong>00:00</strong></div></td>
  </tr><tr>
    <td class='liste0' nowrap>Facturation et statistiques</td>

    <td class='liste0' nowrap><div align="right">02:25</div></td><td class='liste0' nowrap><div align="right">01:40</div></td><td class='liste0' nowrap><div align="right">02:35</div></td>
    <td class='liste0' nowrap><div align="right"><strong>06:40</strong></div></td>
  </tr>
  <tr>
    <td  class="enonce" nowrap><strong>Total</strong></td>
    <td  class="enonce" nowrap><div align="right"><strong>12:45</strong></div></td><td  class="enonce" nowrap><div align="right"><strong>02:55</strong></div></td><td  class="enonce" nowrap><div align="right"><strong>07:45</strong></div></td>

    <td  class="enonce" nowrap>&nbsp;</td>
  </tr>
</table>

</body>
</html>

Pour cela, j'utilise le code php suivant:

<?
    /*
    Projet:    Etude sur les patients
    Document:    affichage du rapport
    Version:    0.1, 16 février 2005
    */
 
  function aff_duree($NomChamp,&$CurrVal){
      // transformation d'une durée en minutes au format hh:mm
      $CurrVal=sprintf("%02d:%02d",floor($CurrVal/60),$CurrVal%60);
  }
 
  function ismatch($variable,$minimum,$maximum,$defaut) {
      // cette fonction contrôle si la variable est incluses entre les limites minimum et maximum,
      // si ce n'est pas le cas, la valeur par défaut est retournée
      if ($minimum<=$variable and $variable<=$maximum){ return $variable; } else { return $defaut; }
  }
 
  include_once('tbs_class.php');
  include_once('../connectdb.inc.php');
  // récupérons les éléments arrivant par la méthode POST. Ces variables sont préfixées par "form_"
  if (isset($_POST)) {
        foreach ($_POST AS $key => $value) {
            ${'form_'.$key}=$value;
        }           
   }
  
   // Validation de la date de début et création du TimeStamp
    if (!ereg("([0-9]{1,2}).([0-9]{1,2}).([0-9]{4})",$form_date_début)) {$form_date_début="0.0.0";}
    $reg=explode(".",$form_date_début); 
    $date_début=mktime(0,0,0,ismatch($reg[1],1,12,1),ismatch($reg[0],1,31,1),ismatch($reg[2],1971,2037,1971));

   // Validation de la date de fin et création du TimeStamp
    if (!ereg("([0-9]{1,2}).([0-9]{1,2}).([0-9]{4})",$form_date_fin)) {$form_date_fin="0.0.0";}
    $reg=explode(".",$form_date_fin); 
    $date_fin=mktime(0,0,0,ismatch($reg[1],1,12,12),ismatch($reg[0],1,31,31),ismatch($reg[2],1971,2037,2037));

   // création de la requête pour la liste des physios
   $wherePhysio=implode(",", $form_physio);
   $queryListePhysio="SELECT id,référence,nom FROM physio WHERE référence IN ( $wherePhysio ) ORDER BY nom";
   
   // création de la requête pour la liste des activités
   $whereActivité=implode(",", $form_activité);
   $queryListeActivité="SELECT id,référence,nom FROM activité WHERE référence IN ( $whereActivité ) ORDER BY référence";   

   // durée totale par activité
   $queryDuréeAct="SELECT SUM( durée ) AS somme
                    FROM formulaire, physio, lien_formulaire_activité
                 WHERE    (formulaire.id_physio = physio.id) AND
                         (formulaire.id = lien_formulaire_activité.id_formulaire) AND
                        (physio.référence IN ( $wherePhysio ) ) AND
                        (formulaire.date_form BETWEEN $date_début AND $date_fin ) AND
                        (lien_formulaire_activité.id_activité=%p1%)";
   // durée totale par physio
   $queryDurée="SELECT SUM( durée ) AS somme
                    FROM formulaire, physio, lien_formulaire_activité
                 WHERE    (formulaire.id_physio = physio.id) AND
                         (formulaire.id = lien_formulaire_activité.id_formulaire) AND
                        (formulaire.date_form BETWEEN $date_début AND $date_fin ) AND
                        (physio.id=%p1%) AND
                        (lien_formulaire_activité.id_activité=%p2%)";

   // durée totale par activité et par physio
   $queryDuréePhy="SELECT SUM( durée ) AS somme
                    FROM    formulaire, physio, lien_formulaire_activité, activité
                 WHERE    (formulaire.id_physio = physio.id) AND
                         (formulaire.id = lien_formulaire_activité.id_formulaire) AND
                        (activité.id = lien_formulaire_activité.id_activité) AND
                        (formulaire.date_form BETWEEN $date_début AND $date_fin ) AND
                        (physio.id=%p1%) AND
                        (activité.référence IN ( $whereActivité ))";
  
  // on prépare la fusion TBS
  $TBS=new clsTinyButStrong;
  $TBS->LoadTemplate('affiche_rapport.htm');
 
  // on récupère la date de début et de fin
  $aff_début=date("d.m.Y",$date_début);
  $aff_fin=date("d.m.Y",$date_fin);
 
  // liste des physios
  $TBS->MergeBlock('blk1,blk1b,blk1c,blk1d','mysql',$queryListePhysio);
  // liste des activités
  $TBS->MergeBlock('blk2','mysql',$queryListeActivité);
  // durée totale par activité et par physio
  $TBS->MergeBlock('blk3','mysql',$queryDurée);
  // durée totale par activité
  $TBS->MergeBlock('blk4','mysql',$queryDuréeAct);
  // durée totale par activité
  $TBS->MergeBlock('blk5','mysql',$queryDuréePhy);

  // et on envoie
  $TBS->Show();

?>

et le modèle html:

<html>
<head>
<title>affichage du rapport</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link href="../physio_ant.css" rel="stylesheet" type="text/css">
</head>
<body>
<p>[onload;file='back_header.htm']</p>
<p>P&eacute;riode du [var.aff_début] au [var.aff_fin]</p>
<table border="0" cellspacing="0" cellpadding="2">
  <tr>
    <td class='enonce' nowrap><strong>Rapport d'activité</strong></td>
    <td class='enonce' nowrap>[blk1.nom;block=td]</td>
    <td class='enonce' nowrap><strong>Total</strong></td>
  </tr>
  <tr>
    <td class='liste0' nowrap>[blk2.nom;block=tr]</td>
    <td class='liste0' nowrap><div align="right">[blk3.somme;block=td;p1=[blk1b.id;block=td];p2=[blk2.id];onformat=aff_duree]</div></td>
    <td class='liste0' nowrap><div align="right"><strong>[blk4.somme;block=td;p1=[blk2.id];onformat=aff_duree]</strong></div></td>
  </tr>
  <tr>
    <td class='liste1' nowrap>[blk2.nom;block=tr]</td>
    <td class='liste1' nowrap><div align="right">[blk3.somme;block=td;p1=[blk1c.id;block=td];p2=[blk2.id];onformat=aff_duree]</div></td>
    <td class='liste1' nowrap><div align="right"><strong>[blk4.somme;block=td;p1=[blk2.id];onformat=aff_duree]</strong></div></td>
  </tr>
  <tr>
    <td  class="enonce" nowrap><strong>Total</strong></td>
    <td  class="enonce" nowrap><div align="right"><strong>[blk5.somme;block=td;p1=[blk1d.id;block=td];onformat=aff_duree]</strong></div></td>
    <td  class="enonce" nowrap>&nbsp;</td>
  </tr>
</table>

</body>
</html>

Et cela fonctionne bien. Alors, pour le modèle permettant de sortir du CSV, je me suis dit qu'il suffisait d'utiliser la syntaxe [NomBloc;block=begin] et [NomBloc;block=end] comme délimiteur ce qui m'a amené à ceci:

<?
    header("Content-type: application/vnd.ms-excel");
    echo "Période du [var.aff_début] au [var.aff_fin]\r\n";
    echo "Rapport d'activité;";
    [blk1;block=begin]
        echo"[blk1.nom;htmlconv=no];";
    [blk1;block=end]
    echo "Total\r\n";
    [blk2;block=begin]
        echo "[blk2.nom;htmlconv=no];";
        [blk3;block=begin]
            [blk1b;block=begin]
                echo"[blk3.somme;p1=[blk1b.id];p2=[blk2.id];onformat=aff_duree];";
            [blk1b;block=end]
        [blk3;block=end]
        [blk4;block=begin]
            echo "[blk4.somme;p1=[blk2.id];onformat=aff_duree]\r\n";
        [blk4;block=end]
    [blk2;block=end]
    echo "Total;";
    [blk5;block=begin]
        [blk1d;block=begin]
            echo "[blk5.somme;p1=[blk1c.id];onformat=aff_duree];";
        [blk1d;block=end]
    [blk5;block=end]
    echo "\r\n";
?>

et là, je reçois des erreurs de TBS ( ou plutôt MySql ) m'annonçant:

TinyButStrong Error (MergeBlock [blk3]): MySql error message when opening the query: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '%p1%) AND (lien_formulaire_activité.id_activité=%p2%)' a

TinyButStrong Error (MergeBlock [blk4]): MySql error message when opening the query: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '%p1%)' at line 7

TinyButStrong Error (MergeBlock [blk5]): MySql error message when opening the query: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near '%p1%) AND (activité.référence IN ( 10,11,12 ))' at line

donc les p1 et p2 ne passent plus et j'ignore pourquoi ... Y a-t-il un ordre spécifique à donner pour les [NomBloc;block=begin] [NomBloc;block=end] ?

Merci d'avance pour vos réponses,

Lionel
By: Lio
Date: 2005-12-09
Time: 14:34

Re: du CSV au lieu de l'HTML

ah, et si je demande le code source de la page m'affichant les erreurs, j'ai ceci:
<?
    header("Content-type: application/vnd.ms-excel");
    echo "Période du 01.01.2005 au 31.01.2005\r\n";
    echo "Rapport d'activité;";
   
        echo"Aichele A.;";
   
        echo"Broulis B.;";
   
        echo"De Bernardini J.L.;";
   
    echo "Total\r\n";
   
        echo "Communications verbales et écrites au sujet d'un patient;";
        [blk3;block=begin]
            
                echo"[blk3.somme;p1=1;p2=2;onformat=aff_duree];";
            
                echo"[blk3.somme;p1=21;p2=2;onformat=aff_duree];";
            
                echo"[blk3.somme;p1=2;p2=2;onformat=aff_duree];";
           
        [blk3;block=end]
        [blk4;block=begin]
            echo "[blk4.somme;p1=2;onformat=aff_duree]\r\n";
        [blk4;block=end]
   
        echo "Colloques et discussions;";
        [blk3;block=begin]
            
                echo"[blk3.somme;p1=1;p2=3;onformat=aff_duree];";
            
                echo"[blk3.somme;p1=21;p2=3;onformat=aff_duree];";
            
                echo"[blk3.somme;p1=2;p2=3;onformat=aff_duree];";
           
        [blk3;block=end]
        [blk4;block=begin]
            echo "[blk4.somme;p1=3;onformat=aff_duree]\r\n";
        [blk4;block=end]
   
        echo "Facturation et statistiques;";
        [blk3;block=begin]
            
                echo"[blk3.somme;p1=1;p2=4;onformat=aff_duree];";
            
                echo"[blk3.somme;p1=21;p2=4;onformat=aff_duree];";
            
                echo"[blk3.somme;p1=2;p2=4;onformat=aff_duree];";
           
        [blk3;block=end]
        [blk4;block=begin]
            echo "[blk4.somme;p1=4;onformat=aff_duree]\r\n";
        [blk4;block=end]
   
    echo "Total;";
    [blk5;block=begin]
       
            echo "[blk5.somme;p1=1;onformat=aff_duree];";
       
            echo "[blk5.somme;p1=1;onformat=aff_duree];";
       
            echo "[blk5.somme;p1=1;onformat=aff_duree];";
       
    [blk5;block=end]
    echo "\r\n";
?>

On voit que tout se passe bien jusqu'au moment ou je commence à imbriquer des [NomBloc;block=begin]

Version  TBS: 2.01 for PHP >= 4.0.6
By: Lio
Date: 2005-12-09
Time: 14:41

Re: du CSV au lieu de l'HTML

et même problème avec TBS 2.05.3. Je viens de l'essayer.
By: Skrol29
Date: 2005-12-09
Time: 15:08

Re: du CSV au lieu de l'HTML

Bonjour,

Il y a deux erreurs dans votre export CSV.

1/
Vous avez placé des <? ?>, un commande header()  et des commandes echo() dans le modèle. Mais ça n'a pas de sens car PHP ne vas pas interpréter ce script. Ce fichier va simplement être chargé par TBS comme une simple chaîne de caractère.
Votre modèle CSV doit être de la forme :
Période du [var.aff_début] au [var.aff_fin]
Rapport d'activité;
[blk1;block=begin][blk1.nom;htmlconv=no];[blk1;block=end]
Total
...

Pour spécifier que le source envoyé est du CSV, vous devez donc arranger votre script comme ceci:
  // et on envoie
  header("Content-type: application/vnd.ms-excel");
  $TBS->Show();

2/
Les paramètres de bloc doivent être placés dans la balise de définition de bloc (celle qui contient "block=").
Par exemple pour le bloc "blk3", il devrait être codé :
  [blk3;block=begin;p1=[blk1b.id];p2=[blk2.id]]
   [blk1b;block=begin]
    [blk3.somme;onformat=aff_duree]
   [blk1b;block=end]
  [blk3;block=end]

"p1" et "p2" sont des paramètres de bloc, donc on les mets dans la balise qui contient "block=".
"onformat" est un paramètre de champ, donc il reste avec la balise [blk3.somme]

Derniers conseils :
--------------------
a)
Votre modèle CSV ne doit pas être fusionné avec des conversions Html.
Je vous conseille donc de charger le modèle CSV en spécifiant aucun charset.
$TBS->LoadTemplate('affiche_rapport.csv',false);

b)
Du fait que votre modèle est texte plutôt que Html (CSV est texte), les sauts de lignes seront répercutés tels quels. Il n'y a pas de <br> en CSV. Vous aurez donc probablement à arranger votre modèle pour supprimer les sauts de ligne. ca va donner un modèle assez tassé à lire mais qui marche.

c) pour le fun :
J'ai vu que votre modèle Html contient des majuscules accentuée, mais affichées comme des minuscules (é au lieu de É). Bien que votre clavier ne contienne pas de majuscule, l'ordinateur les gère parfaitement. Vous pouvez insérer un É en tapant [Alt]+0201.
È -> [Alt]+0200
Ê -> [Alt]+0202
À -> [Alt]+0192
;)
By: Lio
Date: 2005-12-12
Time: 13:53

Re: du CSV au lieu de l'HTML

Super ! Problème réglé avec ta rapidité habituelle. Un grand MERCI !

J'ai juste du modifier ton exemple comme ceci pour que ca fonctionne:
[blk1b;block=begin]
  [blk3;block=begin;p1=[blk1b.id];p2=[blk2.id]]
    [blk3.somme;onformat=aff_duree]
  [blk3;block=end]
[blk1b;block=end]

Le bloc "blk1b" doit être défini hors de la boucle qui l'utilise en paramètre.

encore merci !