Menu Module Page Brique Table simple Table complexe Edition Mes ajouts
Obliquid ?
  est un C.M.S.P.G.C.

Vous trouverez un livre blanc sur les CMS sur le site :
www.cms-quebec.com
 
Menu
Module
Page
Brique
Table simple
Table complexe
Edition
Explication
Le source PHP
Le source TPL
getpdf.php
La classe edition.php
pdf_mysql_table
Mes ajouts
 
Version : 0.0.11
 
Explication
 
Les éditions sont dans le domaine informatique toujours problématiques.
Certains éditeurs pour se soulager de cette tâche utilise des logiciels d'info-centre (Business Object, Cristal Report, ...).
Pour ma part j' ai opté pour une autre solution, celle de générer des fichiers au format Acrobat Reader de chez Adobe. La version reader est gratuite, elle nous permet :
  • de faire des recherches,
  • d' avoir un zoom puissant sur les pages,
  • d' utiliser des marques pages,
  • de n' imprimer que la partie qui nous intéresse,
  • je vous laisse découvrir tout seul les autres avantages, ...
Pour cela j' ai choisi une classe libre, la classe FPDF dont le lien est en annexe, de plus elle existe en français.
Pour la création des fichiers pdf, je passe presque toujours par la génération du fichier, puis une visualisation dans une fenêtre séparée.
 
Le source PHP
 
Exemple de code nécessaire pour l' exploitation de cette édition.

<?php
/** Edition des Communes par ordre alphabétique.
 * @version 0.1
 * @date 2005/02/15
 * @author chautard patrick.chautard@cg94.fr
 * @package edition
 * @link edition::commune_alpha()
 */


/** Classe statistique */
require_once "local/classes/edition.php";

/** Edition des statisque sur les porteurs de carte Commutitre par Commune */
function edition_communealpha_()
{
  global $_obweb;

    $filename="commune_alpha.pdf";
    if ($_POST["action"]=="commune_alpha") {
        set_time_limit(600);

        $_edition = & new edition;
        $_edition->commune_alpha($filename);
               
        $url =& new url(); //creates an url object
        $url->dropVals("action"); //removes params from url
        $url->setVal("page", "edition_home", true);
        $url->reload_JS()//reloads the page
    }

    //form building
    $dbf =& new db_form();

    $frm["submit"]=$dbf->getHidden("action", "commune_alpha")
        .$dbf->getSubmit("submit", _l("Send"), array("class" => "textform"));

    $msg["ficname"]=$filename;
    $msg["printer"]=_l("Edition des communes par ordre alphabétique");

    $_obweb->addButtons(array("help"));
    $_obweb->smslot->assign(array("frm" => $frm, "msg" => $msg));
    $_obweb->smblock->assign(array("title" => _l("Edition des communes par ordre alphabétique")));
}
?>

Explications :

/** Classe statistique */
require_once "local/classes/edition.php";

set_time_limit(600);

$_edition = & new edition;
$_edition->commune_alpha($filename);

Comme vous pouvez le constater le source de l' édition est dans une classe séparée.
Si la brique est appelée avec une variable 'action' passée en mode POST qui contient la valeur 'commune_alpha' alors appel de la méthode 'commune_alpha($filename)' de la classe edition.

$url =& new url(); //creates an url object
$url->dropVals("action"); //removes params from url
$url->setVal("page", "edition_home", true);
$url->reload_JS()//reloads the page
 

La classe 'url' est appelée pour modifier l'url de la page en premier lieu le paramètre action est enlevé, puis le paramètre 'page' est initialisé avec la valeur 'edition_home'.
Il existe deux méthodes pour recharger la page :

  • $url->reload - Rechargement standard de la page, ne fonctionne pas si des données sont envoyées avant son appel.
  • $url->reload_JS - Écrit en javascript, fonctionne dans tous les cas.

//form building
$dbf =& new db_form();

$frm["submit"]=$dbf->getHidden("action", "commune_alpha")
        .$dbf->getSubmit("submit", _l("Send"), array("class" => "textform"));

$msg["ficname"]=$filename;
$msg["printer"]=_l("Edition des communes par ordre alphabétique");

$_obweb->addButtons(array("help"));
$_obweb->smslot->assign(array("frm" => $frm, "msg" => $msg));
$_obweb->smblock->assign(array("title" => _l("Edition des communes par ordre alphabétique")));

Création d' un formulaire avec un champ caché 'action' et un bouton submit 'Send'.
Initialisation des messages affichés sur la brique.

 
Le source TPL
 
<br/>
<table class="tablemain" width="100%">
  <tr>
    <td>
      <form method="post">
      Pr&eacute;paration : {{$frm.submit}}
      </form>
    </td>
    <td>
      <a href="obfiles/pdf/getpdf.php?f={{$msg.ficname}}" target="_blank" {{popup text="`$msg.printer`"}}>
      <img src="local/images/edition/printer.gif" border="0"></a>
    </td>
</tr>
</table>
<span class="textmini"><br/></span>

Explications :

Création d'un formulaire qui génére le fichier d'édition.
Un lien vers le programme getpdf.pdp permet de charger celle-ci dans une fenêtre séparée, lors de la validation sur l'image de l'imprimante.

 
getpdf.php
 
<?php
$f=$_SERVER["DOCUMENT_ROOT"]."/electromenager/obfiles/pdf/".$_GET['f'];
//Traitement de la requête spéciale IE au cas où
if($HTTP_SERVER_VARS['HTTP_USER_AGENT']=='contype')
{
    Header('Content-Type: application/pdf');
    exit;
}
//Envoi du PDF
Header('Content-Type: application/pdf');
Header('Content-Length: '.filesize($f));
readfile($f);
exit;
?>
 

Explications :

Tous les fichiers chargés dans obliquid se trouvent dans le répertoire obfiles.
Pour rester dans la même logique créer un sous-répertoire pdf qui contiendra l' ensemble des fichiers pdf générés.
Dans ce répertoire copier le fichier getpdf.php, sans oublier de mettre à jour la variable $f qui contient le chemin d'accés vers le fichier passé en paramètre. Les autres lignes restent inchangées.

 
La classe edition.php
 
<?php

/**  Editions
 * Les éditions.
 * @version 0.1
 * @date 2005/01/18
 * @author chautard patrick.chautard@cg94.fr
 * @package edition
 * @access public
 */


/** Classe pdf_mysql_table */
require_once('local/classes/fpdf/pdf_mysql_table.php');

/** Edition des communes par ordre alphabétique.
 * Surchage de la classe PDF_MySQL_Table pour la personnalisation de l'état.
 * @access private
 * @package edition
 */

class PDFCA extends PDF_MySQL_Table
{
 //En-tête
 function Header()
 {
    $this->Ln(10);
    $this->SetFont('Arial','B',24);
    $this->Cell(0,0,"Edition alphabétique des communes",0,0,"C");
    $this->Ln(10);
       
        //Imprime l'en-tête du tableau si nécessaire
    parent::Header();
 }

 //Pied de page
 function Footer()
 {
    //Police Arial italique 8
    $this->SetFont('Arial','',7);
    //Numéro de page
    $this->SetXY(180,-10);
    $this->Cell(0,0,"Page ".$this->PageNo(),0,0,'R');
 }
}

/**  Classe pour la génération de diverses editions.
 *  @package         edition
 */

class edition
{
    /** Statistique des communes par ordre alphatétique
        * @link edition_communealpha_()
     * @access public
         * @param string - Nom du fichier pdf à générer.
        * @param boolean = [false] - Affichage des informations de debug.
        */

        function commune_alpha($fname, $debug=false) {
                // Recherche de tous les établissements
                $sql="SELECT * FROM ".$_obweb->tprefix."ville ORDER BY nom";

                $pdf=new PDFCA();
                $pdf->Open();

                $pdf->AddPage('P');
                $pdf->AddCol( 0,30,"CODE INSEE",'C');
                $pdf->AddCol( 1,30,"CODE POSTAL",'C');
                $pdf->AddCol( 2,60,"NOM",'L');
                $prop=array('HeaderColor'=>array(255,150,100),
                                        'color1'=>array(210,245,255),
                                        'color2'=>array(255,255,210),
                                        'padding'=>2);
                $pdf->Table( $sql, $prop, true);
               
                $pdf->Output("obfiles/pdf/".$fname);
        }
       
    /** Affichage d'un message à l'écran
     * @access private
        * @param string - le message à afficher
        */

        function e($input) {
                echo str_pad($input, 255, " ", STR_PAD_RIGHT)."<br>";
                fflush();
        }
}

Explications :

/** Classe pdf_mysql_table */
require_once('local/classes/fpdf/pdf_mysql_table.php');

Chargement de la classe 'pdf_mysql_table.php'.

La classe PDFCA :

/** Edition des communes par ordre alphabétique.
 * Surchage de la classe PDF_MySQL_Table pour la personnalisation de l'état.
 * @access private
 * @package edition
 */

class PDFCA extends PDF_MySQL_Table
{
 //En-tête
 function Header()
 {
    $this->Ln(10);
    $this->SetFont('Arial','B',24);
    $this->Cell(0,0,"Edition alphabétique des communes",0,0,"C");
    $this->Ln(10);
       
        //Imprime l'en-tête du tableau si nécessaire
    parent::Header();
 }

 //Pied de page
 function Footer()
 {
    //Police Arial italique 8
    $this->SetFont('Arial','',7);
    //Numéro de page
    $this->SetXY(180,-10);
    $this->Cell(0,0,"Page ".$this->PageNo(),0,0,'R');
 }
}

Surcharge de la classe pdf_mysql_table pour la personnalisation de l' en-tête et du pied de page.

  • L' entête contient un titre écrit en police Arial Bold de 24.
  • Le pied de page contient le numéro de la page.

La classe edition :

class edition
{
    /** Statistique des communes par ordre alphatétique
        * @link edition_communealpha_()
     * @access public
         * @param string - Nom du fichier pdf à générer.
        * @param boolean = [false] - Affichage des informations de debug.
        */

        function commune_alpha($fname, $debug=false)
       
        ...
}

Elle contient la méthode 'commune_alpha' qui est appelée pour la création du fichier pdf.

La méthode edition::commune_alpha :

// Recherche de tous les établissements
$sql="SELECT * FROM ".$_obweb->tprefix."ville ORDER BY nom";

$pdf=new PDFCA();
$pdf->Open();

$pdf->AddPage('P');
$pdf->AddCol( 0,30,"CODE INSEE",'C');
$pdf->AddCol( 1,30,"CODE POSTAL",'C');
$pdf->AddCol( 2,60,"NOM",'L');
$prop=array('HeaderColor'=>array(255,150,100),
                        'color1'=>array(210,245,255),
                        'color2'=>array(255,255,210),
                        'padding'=>2);
$pdf->Table( $sql, $prop, true);

$pdf->Output("obfiles/pdf/".$fname);

Elle se compose en :

  • Génération de l' ordre sql d'interogation de la base.
  • Création d' un nouvel objet PDFCA.
  • Ouverture du nouveau fichier.
  • Déclaration des colonnes de l' état.
  • Définition des couleur pour l' entête et les colonnes changement de couleur une ligne sur deux.
  • Appel de la méthode Table de la classe de base.
  • Génération du fichier.
Vous

trouverez toutes les explications sur les classes fpdf et pdf_mysql_table sur le site de fpdf, voir la rubrique Annexe.
 
pdf_mysql_table
 

Cette classe est à installer dans le répertoire /local/classes/fpdf,

sous le nom pdf_mysql_table.php.

<?php
define('FPDF_FONTPATH','font/');
require_once('local/classes/fpdf/fpdf.php');

class PDF_MySQL_Table extends FPDF
{
var $ProcessingTable=false;
var $aCols=array();
var $TableX;
var $HeaderColor;
var $RowColors;
var $ColorIndex;
var $Ligne;
var $Verbose;

function Header()
{
    //Imprime l'en-tête du tableau si nécessaire
    if($this->ProcessingTable)
        $this->TableHeader();
}

function CheckPageBreak($h)
{
    //Si la hauteur h provoque un débordement, saut de page manuel
    if($this->GetY()+$h>$this->PageBreakTrigger)
        $this->AddPage($this->CurOrientation);
}

function NbLines($w,$txt)
{
    //Calcule le nombre de lignes qu'occupe un MultiCell de largeur w
    $cw=&$this->CurrentFont['cw'];
    if($w==0)
        $w=$this->w-$this->rMargin-$this->x;
    $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
    $s=str_replace("\r",'',$txt);
    $nb=strlen($s);
    if($nb>0 and $s[$nb-1]=="\n")
        $nb--;
    $sep=-1;
    $i=0;
    $j=0;
    $l=0;
    $nl=1;
    while($i<$nb)
    {
        $c=$s[$i];
        if($c=="\n")
        {
            $i++;
            $sep=-1;
            $j=$i;
            $l=0;
            $nl++;
            continue;
        }
        if($c==' ')
            $sep=$i;
        $l+=$cw[$c];
        if($l>$wmax)
        {
            if($sep==-1)
            {
                if($i==$j)
                    $i++;
            }
            else
                $i=$sep+1;
            $sep=-1;
            $j=$i;
            $l=0;
            $nl++;
        }
        else
            $i++;
    }
    return $nl;
}

function TableHeader()
{
    $this->SetFont('Arial','B',12);
    $this->SetX($this->TableX);
    $fill=!empty($this->HeaderColor);
    if($fill)
        $this->SetFillColor($this->HeaderColor[0],$this->HeaderColor[1],$this->HeaderColor[2]);
    foreach($this->aCols as $col)
        $this->Cell($col['w'],6,$col['c'],1,0,'C',$fill);
    $this->Ln();
}

function Row($data)
{
    //Calcule la hauteur de la ligne
    $nb=0;
    foreach($this->aCols as $col) {
        $nb=max($nb,$this->NbLines($col['w'],$data[$col['f']]));
    }
    $h=5*$nb;

    //Effectue un saut de page si nécessaire
    $this->CheckPageBreak($h);

    // Recherche de la couleur
    $ci=$this->ColorIndex;
    $fill=!empty($this->RowColors[$ci]);
    if($fill)
        $this->SetFillColor($this->RowColors[$ci][0],$this->RowColors[$ci][1],$this->RowColors[$ci][2]);

    $this->SetX($this->TableX);

    //Dessine les cellules
    foreach($this->aCols as $col)
          {
             // Largeur de la colonne
       $w=$col['w'];
       //Sauve la position courante
       $x=$this->GetX();
       $y=$this->GetY();

       //Dessine le cadre
       $this->Rect($x,$y,$w,$h,"DF");

       //Imprime le texte
           if ($data[$col['f']]=="X")
                $this->MultiCell($w,5,$this->Ligne,0,$col['a']);
           else
                $this->MultiCell($w,5,$this->utf8($data[$col['f']]),0,$col['a']);
               
       //Repositionne à droite
       $this->SetXY($x+$w,$y);
          }
    //Va à la ligne
    $this->Ln($h);
    $this->ColorIndex=1-$ci;
}

function CalcWidths($width,$align)
{
    //Calcule les largeurs des colonnes
    $TableWidth=0;
    foreach($this->aCols as $i=>$col)
    {
        $w=$col['w'];
        if($w==-1)
            $w=$width/count($this->aCols);
        elseif(substr($w,-1)=='%')
            $w=$w/100*$width;
        $this->aCols[$i]['w']=$w;
        $TableWidth+=$w;
    }
    //Calcule l'abscisse du tableau
    if($align=='C')
        $this->TableX=max(($this->w-$TableWidth)/2,0);
    elseif($align=='R')
        $this->TableX=max($this->w-$this->rMargin-$TableWidth,0);
    else
        $this->TableX=$this->lMargin;
}

function AddCol($field=-1,$width=-1,$caption='',$align='L')
{
    //Ajoute une colonne au tableau
    if($field==-1)
        $field=count($this->aCols);
    $this->aCols[]=array('f'=>$field,'c'=>$caption,'w'=>$width,'a'=>$align);
}

function Table($query, $prop=array(), $verbose=false)
{
        global $_obweb;
       
    if ($verbose) echo "Interrogation de la base :<br>";
       
        //Exécute la requête
        $_obweb->mb->QueryAll($query, $Col);

    //Ajoute toutes les colonnes si aucune n'a été définie
    if(count($this->aCols)==0)
    {
        $nb=mysql_num_fields($res);
        for($i=0;$i<$nb;$i++)
            $this->AddCol();
    }
    //Détermine les noms des colonnes si non spécifiés
    foreach($this->aCols as $i=>$col)
    {
        if($col['c']=='')
        {
            if(is_string($col['f']))
                $this->aCols[$i]['c']=ucfirst($col['f']);
            else
                $this->aCols[$i]['c']=ucfirst(mysql_field_name($res,$col['f']));
        }
    }
    //Traite les propriétés
    if(!isset($prop['width']))
        $prop['width']=0;
    if($prop['width']==0)
        $prop['width']=$this->w-$this->lMargin-$this->rMargin;
    if(!isset($prop['align']))
        $prop['align']='C';
    if(!isset($prop['padding']))
        $prop['padding']=$this->cMargin;
    $cMargin=$this->cMargin;
    $this->cMargin=$prop['padding'];
    if(!isset($prop['HeaderColor']))
        $prop['HeaderColor']=array();
    $this->HeaderColor=$prop['HeaderColor'];
    if(!isset($prop['color1']))
        $prop['color1']=array();
    if(!isset($prop['color2']))
        $prop['color2']=array();
    $this->RowColors=array($prop['color1'],$prop['color2']);
    //Calcule les largeurs des colonnes
    $this->CalcWidths($prop['width'],$prop['align']);
    //Imprime l'en-tête
    $this->TableHeader();
    //Imprime les lignes
    $this->SetFont('Arial','',11);
    $this->ColorIndex=0;
    $this->ProcessingTable=true;
        $this->Ligne = 1;
    for($i=0; $i<count($Col); $i++) {
                if ($verbose) echo "Traitement de la ligne : ".$this->Ligne."<br>";
            $this->Row($Col[$i]);
                $this->Ligne++;
          }
    $this->ProcessingTable=false;
    $this->cMargin=$cMargin;
    $this->aCols=array();
}

function TableArray($query,$prop=array())
{
    // Toutes les colonnes doivent être définies avant
    // Traite les propriétés
    if(!isset($prop['width']))
        $prop['width']=0;
    if($prop['width']==0)
        $prop['width']=$this->w-$this->lMargin-$this->rMargin;
    if(!isset($prop['align']))
        $prop['align']='C';
    if(!isset($prop['padding']))
        $prop['padding']=$this->cMargin;
    $cMargin=$this->cMargin;
    $this->cMargin=$prop['padding'];
    if(!isset($prop['HeaderColor']))
        $prop['HeaderColor']=array();
    $this->HeaderColor=$prop['HeaderColor'];
    if(!isset($prop['color1']))
        $prop['color1']=array();
    if(!isset($prop['color2']))
        $prop['color2']=array();
    $this->RowColors=array($prop['color1'],$prop['color2']);
    //Calcule les largeurs des colonnes
    $this->CalcWidths($prop['width'],$prop['align']);
    //Imprime l'en-tête
    $this->TableHeader();
    //Imprime les lignes
    $this->SetFont('Arial','',11);
    $this->ColorIndex=0;
    $this->ProcessingTable=true;
          $this->Ligne = 1;
    for($row=0; $row<count($query); $row++) {
      $this->Row(array_values($query[$row]));
                  $this->Ligne++;

      if ( $this->Verbose && (($row % 100)==0)) {
          echo "- $row / ".count($query).str_repeat(" ",240)."<br>";
          flush();
      }
        }
    $this->ProcessingTable=false;
    $this->cMargin=$cMargin;
    $this->aCols=array();
}
}

Attention !

Cette classe a été modifiée pour prendre en compte le fait que dans Obliquid on utilise une métabase, de plus la méthode 'TableArray' a été ajouté.

PARTIE ANNEXE  
Quelques sites utiles et utilisés : Quelques documentations sommaires extraites de www.programmez.com

Je ne suis pas un gourou PHP, TPL ou Obliquid, mais si des informations vous manquent sur ce CMS n'exitez pas à m'envoyer un mail.