CakePHP-Fr.Org

Forum francophone du Framework CakePHP

Vous n'êtes pas identifié.

  • Forums
  •  » Vos annonces
  •  » Integrer jasperReport à cakePhp pour la réalisation d'états complexes

#1 10-07-2013 11:56:54

dev66
Crêpe Suzette
Date d'inscription: 07-01-2010
Messages: 7

Integrer jasperReport à cakePhp pour la réalisation d'états complexes

1) La philosophie
Utilisation du mvc de cake, les données proviennent des modéles, la vue est le rapport jasper qui met en forme ces données.

2) Comment ça fonctionne.

Sous forme de composant cake « JasperComponent » que l'on utilise dans les actions.

Exemple :

Code: php

  1.   function statistique_mandats_mois() {
  2.     if (!empty($this->request->data)) {
  3.       $mandats = $this->Mandat->getByPeriodeTypeAide($this->request->data['Mandat']['periode']);
  4.           $this->Jasper->set(compact('mandats'));
  5.           $this->Jasper->render();
  6.     } else {
  7.       $this->set('title_for_layout','Statistiques mandats par mois');
  8.       $periodes = $this->Mandat->getPeriodes();
  9.       $this->set('periodes', $periodes);
  10.     }
  11.   }

La vue « statistique_mandats_mois.ct »p propose un formulaire de sélection du mois.

Dans un premier temps, après choix du mois, l'action générera un fichier xml (statistique_mandats_mois.xml) qui pourra être utilisé comme source de donnée xml au moyen du logiciel libre iReport pour construire un état (report, graphiques, ...) statistique_mandats_mois.jasper.

Le fichier statistique_mandats_mois.jasper sera copié dans le répertoire vue du contrôleur.

Toute nouvelle utilisation de l'action générera un état pdf construit à partir des données du modèle et du report jasper pour la mise en forme.

3) Le code du composant

Code: php

  1. <?php
  2. class JasperComponent extends Component {
  3.     public $Controller = null;
  4.     private $keys = array();
  5.  
  6.     public function startup(Controller $controller) {
  7.         parent::startup($controller);
  8.         $this->Controller = $controller;
  9.     }
  10.  
  11.     public function set($vars = array()) {
  12.       if (!($this->Controller->viewClass == 'Xml')) {
  13.         $this->Controller->viewClass = 'Xml';
  14.       }
  15.       $this->Controller->set($vars);
  16.       $this->keys = array_merge(array_keys($vars),$this->keys);
  17.     }
  18.    
  19.     public function render($view = null) {
  20.       if ($view == null) {
  21.         $view = $this->Controller->view;
  22.       };
  23.       $this->Controller->set('_rootNode', 'Jasper');
  24.       $this->Controller->set('_serialize', $this->keys);
  25.       foreach(App::path('View') as $view_path) {
  26.         $expected_view = $view_path. DS . $this->Controller->name . DS . $view . '.jasper';
  27.         if (file_exists($expected_view)) {
  28.           $path_ok = $expected_view;
  29.         }
  30.       }
  31.       if (isset ($path_ok)) {
  32.         $monXml = $this->Controller->render()->body(null);
  33.         define('JAVA_HOSTS', '127.0.0.1:8087');
  34.         define('JAVA_SERVLET', "JavaBridge");
  35.         require_once(APP . 'Vendor' . DS.'javaBridge'.DS.'Java.inc');
  36.         $Jasper = new java("org.Jasper");
  37.         $response =  $Jasper->runJasper(array($path_ok,$monXml));
  38.         header('Content-type: application/pdf');
  39.         header('Content-Disposition: attachment; filename="'.$view.'.pdf"');
  40.         echo $response;
  41.         exit;
  42.       } else {
  43.         return $this->Controller->render();
  44.       }
  45.     }
  46. }

L’exécutable jasper étant un bout de code java, j'utilise le pont php/java http://php-java-bridge.sourceforge.net.

Le code java :

Code: php

  1. package org;
  2. import java.io.ByteArrayInputStream;
  3. import java.io.InputStream;
  4. import java.util.HashMap;
  5. import java.util.Locale;
  6. import java.util.Map;
  7. import net.sf.jasperreports.engine.JRParameter;
  8. import net.sf.jasperreports.engine.JasperRunManager;
  9. import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory;
  10. import net.sf.jasperreports.engine.util.JRXmlUtils;
  11. import org.w3c.dom.Document;
  12.  
  13. public class Jasper {
  14.     public static final String JAVABRIDGE_PORT="8087";
  15.     static final php.java.bridge.JavaBridgeRunner runner =
  16.       php.java.bridge.JavaBridgeRunner.getInstance(JAVABRIDGE_PORT);
  17.   /**
  18.    * @param args
  19.    */
  20.   public static void main(String[] args) throws Exception {
  21.     runner.waitFor();
  22.       System.exit(0);
  23.   }
  24.  
  25.   public byte[] runJasper(String args[]) throws Exception {
  26.     String view_path = args[0];
  27.     Map<String, Object> params = new HashMap<String, Object>();
  28.     InputStream in = new ByteArrayInputStream(args[1].getBytes("UTF-8"));
  29.     Document document = JRXmlUtils.parse(in);
  30.     params.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, document);
  31.     params.put(JRXPathQueryExecuterFactory.XML_DATE_PATTERN, "yyyy-MM-dd");
  32.     params.put(JRXPathQueryExecuterFactory.XML_NUMBER_PATTERN, "#,##0.##");
  33.     params.put(JRXPathQueryExecuterFactory.XML_LOCALE, Locale.ENGLISH);
  34.     params.put(JRParameter.REPORT_LOCALE, Locale.FRANCE);
  35.     byte[] bytes = JasperRunManager.runReportToPdf(view_path, params);
  36.     return bytes;
  37.   }
  38.  
  39. }

Bien entendu, ce code utilise la librairie javaBridge et toutes les librairies de jasperReport.

Le code cake fonctionne sous réserve que soit lancé l’exécutable Java sur le serveur.

Code: php

  1. Java -jar jasper.jar

Une fois le code lancé on récupére le fichier java.inc

Code: php

  1. wget http://127.0.0.1:8087/JavaBridge/java/Java.inc

et on le copie dans Vendor/javaBridge

Le code php est alors fonctionnel.

4) précaution

Il s'agit d'un premier jet qui doit être amélioré du point de vue de la gestion des erreurs.

Le serveur HTTP simple intégré à la librairieJavaBridge.jar n'est pas recommandé dans un environnement de production.
Des tests de charges sont à prévoir, en cas de problèmes, il faudra intégrer le code java dans tomcat.

Dernière modification par dev66 (17-07-2013 14:34:37)

Hors ligne

 
  • Forums
  •  » Vos annonces
  •  » Integrer jasperReport à cakePhp pour la réalisation d'états complexes

Pied de page des forums

Propuls� par FluxBB
Traduction par FluxBB.fr