TinyButStrong - the PHP Template Engine
Categories > OpenTBS with PPTX >

Supressing and/or adding slides to a pptx

The forum is closed. Please use Stack Overflow for submitting new questions. Use tags: tinybutstrong , opentbs

By: Alejandro
Date: 2012-12-18
Time: 22:10

Supressing and/or adding slides to a pptx

Hi everybody again,  first of all, Merry Christmas!!

Well, I'm generating a Powerpoint that consist on several slides that follows the same template, but the number and content of the slides depends on the results of a db query.

Right now, I've solved my problem generating a template with more slides than the maximun I need and, once the ppt is generated, I open it manually and delete the spare slides.

I've tried deleting the slides, (with $TBS->Plugin(OPENTBS_DELETEFILE) ) but when I open the ppt it says that is corrupted.

Is there any way to delete slides and/or duplicate a Slide in powerpoint presentation to be able to generate the pptx rigth away??

Thx for your help
Regards
Alejandro
By: Skrol29
Date: 2012-12-20
Time: 01:26

Re: Supressing and/or adding slides to a pptx

Hi Alejandro,

In a PPTX, slides are references in several extra sub-files such as "ppt/_rels/viewProps.xml.rels", "ppt/_rels/presentation.xml.rels", "ppt/viewProps.xml".
So it's a punctilious technical task to delete a slide.
There is not such a feature for now in OpenTBS, but someone has submitted a script in french for this purpose, but it is not tested yet.

By: Alejandro
Date: 2012-12-20
Time: 18:12

Re: Supressing and/or adding slides to a pptx

That's what I thought.

Can you point me where is that script. I'll be glad to test it and try to fix it if it doesn't work.
By: Skrol29
Date: 2012-12-21
Time: 00:15

Re: Supressing and/or adding slides to a pptx

Here it is, submitted by David L.:

<?php
 
  function cleanPptx($file) {
 
    // Récupère l'archive pptx à nettoyer (suppression des slides superflus).
    $zip = $file -> TbsZip;
   
    // Initialise un compteur utile pour connaître le numéro du slide courant dans notre boucle.
    $cpt_slide = 1;
   
    // Initialise l'id du slide courant dans notre boucle.
    $id_slide = '';
   
    // Initialise l'id de la vue affiliée au slide courant dans notre boucle.
    $id_view = '';
   
    // Récupère le fichier récapitulant les différents éléments que contient le document de présentation.
    $content = $zip -> FileRead('[Content_Types].xml');
   
    // Récupère le contenu de fichier qui recense les relations entre identifiants et slides.
    $presentation_rels = $zip -> FileRead('ppt/_rels/presentation.xml.rels');
   
    // Vérifie si le fichier viewProps.xml est présent dans l'archive.
    if ($zip -> FileExists('ppt/_rels/viewProps.xml.rels')) {
   
      $view_rels_exists = true;
   
      // Récupère le contenu du fichier viewProps.xml.rels susceptible de renseigner l'identifiant d'une vue pour un slide.
      $view_rels = $zip -> FileRead('ppt/_rels/viewProps.xml.rels');
     
      // Récupère le contenu du fichier viewProps.xml présente les vues.
      $view = $zip -> FileRead('ppt/viewProps.xml');
    } else {
      $view_rels_exists = false;
    }
   
    // Récupère le contenu du fichier de presentation.
    $presentation = $zip -> FileRead('ppt/presentation.xml');
   
    // Récupère le contenu du fichier qui récapitule les propriétés du document (nombre de slides, titre des slides, etc).
    $app = $zip -> FileRead('docProps/app.xml');
   
    // Initialise le tableau comprenant les numéros des slides supprimés.
    $slides_supprimes = array();
   
    // Boucle autant de fois qu'il y a de slides (en vérifiant que le fichier xml représentant le slide existe dans l'archive).
    while ($zip -> FileExists('ppt/slides/slide' . $cpt_slide . '.xml')) {
   
      // Récupère le contenu du fichier.
      $slide = $zip -> FileRead('ppt/slides/slide' . $cpt_slide . '.xml');
     
      // Vérifie si le slide courant contient des balises non remplies.
      if (strstr($slide, '%%optional%%')) {
     
        // Supprime le slide courant et le fichier de relation associé.
        $zip -> FileReplace('ppt/slides/slide' . $cpt_slide . '.xml', false);
        $zip -> FileReplace('ppt/slides/_rels/slide' . $cpt_slide . '.xml.rels', false);
       
        $slides_supprimes[] = $cpt_slide;
       
       
        //////////////////////////////////////////////////////////
        //                                                      //
        //  Début préparation mise à jour [Content_Types].xml   //
        //                                                      //
        //////////////////////////////////////////////////////////
       
        $offset = 0;
        $fin_boucle = false;
       
        // Boucle sur l'ensemble des éléments que contient le document de présentation jusqu'à ce qu'on trouve celui que l'on souhaite supprimer.
        while (! $fin_boucle) {
       
          $debut_chaine = strpos($content, "<Override ", $offset);
          $fin_chaine = strpos($content, "/>", $debut_chaine);
         
          // Récupère l'élément courant.
          $chaine_temp = substr($content, $debut_chaine, $fin_chaine - $debut_chaine);
         
          // Vérifie si l'élement courant est celui que l'on souhaite supprimer.
          if (strstr($chaine_temp, 'slide' . $cpt_slide . '.xml') != false) {
         
            // Définit le contenu à jour du fichier .
            $content = substr($content, 0, $debut_chaine) . substr($content, $fin_chaine + 2, strlen($content) - $fin_chaine + 1);
           
            $fin_boucle = true;
          }
         
          $offset = $fin_chaine + 2;
        }
       
        //////////////////////////////////////////////////////////
        //                                                      //
        //  Fin préparation mise à jour [Content_Types].xml     //
        //                                                      //
        //////////////////////////////////////////////////////////
       
       
        //////////////////////////////////////////////////////////
        //                                                      //
        //  Début préparation mise à jour presentation.xml.rels //
        //                                                      //
        //////////////////////////////////////////////////////////
       
        $offset = 0;
        $fin_boucle = false;
       
        // Boucle sur l'ensemble des relations entre identifiants et slides définies dans le fichier jusqu'à ce qu'on trouve celle que l'on souhaite supprimer.
        while (! $fin_boucle) {
       
          $debut_chaine = strpos($presentation_rels, "<Relationship ", $offset);
          $fin_chaine = strpos($presentation_rels, "/>", $debut_chaine);
         
          // Récupère la relation courante.
          $chaine_temp = substr($presentation_rels, $debut_chaine, $fin_chaine - $debut_chaine);
         
          // Vérifie si la relation courante est celle que l'on souhaite supprimer.
          if (strstr($chaine_temp, 'slide' . $cpt_slide . '.xml') != false) {
         
            // Définit le contenu à jour du fichier qui recense les relations entre identifiants et slides (suppression de la relation courante).
            $presentation_rels = substr($presentation_rels, 0, $debut_chaine) . substr($presentation_rels, $fin_chaine + 2, strlen($presentation_rels) - $fin_chaine + 1);
           
           
            $debut_chaine = strpos($chaine_temp, "Id=\"");
            $fin_chaine = strpos($chaine_temp, "\" Type");
           
            // Récupère de l'id de la relation courante. Utile pour supprimer par la suite une ligne dans la fichier de presentation.
            $id_slide = substr($chaine_temp, $debut_chaine + 4, $fin_chaine - $debut_chaine - 4);
           
            $fin_boucle = true;
          }
         
          $offset = $fin_chaine + 2;
        }
       
        //////////////////////////////////////////////////////////
        //                                                      //
        //  Fin préparation mise à jour presentation.xml.rels   //
        //                                                      //
        //////////////////////////////////////////////////////////
       
       
        //////////////////////////////////////////////////////////
        //                                                      //
        //  Début préparation mise à jour viewProps.xml.rels    //
        //                & viewProps.xml         //
        //                                                      //
        //////////////////////////////////////////////////////////
       
        if ($view_rels_exists) {
          // Vérifie si viewProps.xml.rels contient des vues relatives au slide courant à supprimer.
          if (strstr($view_rels, 'slide' . $cpt_slide . '.xml') != false) {
            $offset = 0;
            $fin_boucle = false;
           
            // Boucle sur l'ensemble des relations entre vues et slides définies dans le fichier jusqu'à ce qu'on trouve celle que l'on souhaite supprimer.
            while (! $fin_boucle) {
              $debut_chaine = strpos($view_rels, "<Relationship ", $offset);
              $fin_chaine = strpos($view_rels, "/>", $debut_chaine);
             
              // Récupère la relation courante.
              $chaine_temp = substr($view_rels, $debut_chaine, $fin_chaine - $debut_chaine);
             
              // Vérifie si la relation courante est celle que l'on souhaite supprimer.
              if (strstr($chaine_temp, 'slide' . $cpt_slide . '.xml') != false) {
                // Définit le contenu à jour du fichier viewProps.xml.rels en supprimant la relation obsolète.
                $view_rels = substr($view_rels, 0, $debut_chaine) . substr($view_rels, $fin_chaine + 2, strlen($view_rels) - $fin_chaine - 2);
               
                $debut_chaine = strpos($chaine_temp, "Id=\"");
                $fin_chaine = strpos($chaine_temp, "\" Type");
             
                // Récupère de l'id de la relation courante. Utile pour supprimer par la suite une ligne dans la fichier de présentation des vues.
                $id_view = substr($chaine_temp, $debut_chaine + 4, $fin_chaine - $debut_chaine - 4);
               
                $fin_boucle = true;
              }
             
              $offset = $fin_chaine + 2;
            }
           
            $offset = 0;
            $fin_boucle = false;
           
            // Boucle sur l'ensemble des identifiants listés dans le fichier viewProps.xml présentant les vues.
            while (! $fin_boucle) {
              $debut_chaine = strpos($view, "<p:sld r:id", $offset);
              $fin_chaine = strpos($view, "/>", $debut_chaine);
             
              // Récupère l'id courant.
              $chaine_temp = substr($view, $debut_chaine, $fin_chaine - $debut_chaine);
             
              // Vérifie si l'id courant est celui que l'on souhaite supprimer.
              if (strstr($chaine_temp, $id_view) != false) {
             
                // Définit le contenu à jour du fichier de présentation des vues (suppression de l'id courant).
                $view = substr($view, 0, $debut_chaine) . substr($view, $fin_chaine + 2, strlen($view) - $fin_chaine - 2);
               
                $fin_boucle = true;
              }
             
              $offset = $fin_chaine + 2;
            }
          }
        }
       
        //////////////////////////////////////////////////////////
        //                                                      //
        //  Fin préparation mise à jour viewProps.xml.rels      //
        //                & viewProps.xml           //
        //                                                      //
        //////////////////////////////////////////////////////////
       
       
        //////////////////////////////////////////////////////////
        //                                                      //
        //  Début préparation mise à jour presentation.xml      //
        //                                                      //
        //////////////////////////////////////////////////////////
       
        $offset = 0;
        $fin_boucle = false;
       
        // Boucle sur l'ensemble des définitions d'identifiant dans le fichier de présentation jusqu'à ce qu'on trouve celle que l'on souhaite supprimer.
        while (! $fin_boucle) {
          $debut_chaine = strpos($presentation, "<p:sldId ", $offset);
          $fin_chaine = strpos($presentation, "/>", $debut_chaine);
         
          // Récupère l'id courant.
          $chaine_temp = substr($presentation, $debut_chaine, $fin_chaine - $debut_chaine);
         
          // Vérifie si l'id courant est celui que l'on souhaite supprimer.
          if (strstr($chaine_temp, $id_slide) != false) {
         
            // Définit le contenu à jour du fichier de présentation (suppression de l'id courant).
            $presentation = substr($presentation, 0, $debut_chaine) . substr($presentation, $fin_chaine + 2, strlen($presentation) - $fin_chaine + 1);
           
            $fin_boucle = true;
          }
         
          $offset = $fin_chaine + 2;
        }
       
        //////////////////////////////////////////////////////////
        //                                                      //
        //  Fin préparation mise à jour presentation.xml        //
        //                                                      //
        //////////////////////////////////////////////////////////
      }
     
      // Remplace les différents fichiers xml utiles du document de présentation par les mises à jour construites dans le tratitement ci-dessus.
      $zip -> FileReplace('[Content_Types].xml', $content, TBSZIP_STRING);
      $zip -> FileReplace('ppt/_rels/presentation.xml.rels', $presentation_rels, TBSZIP_STRING);
     
      if ($view_rels_exists) {
        $zip -> FileReplace('ppt/_rels/viewProps.xml.rels', $view_rels, TBSZIP_STRING);
        $zip -> FileReplace('ppt/viewProps.xml', $view, TBSZIP_STRING);
      }
     
      $zip -> FileReplace('ppt/presentation.xml', $presentation, TBSZIP_STRING);
     
     
      ++ $cpt_slide;
    }
   
    //////////////////////////////////////////////////////////
    //                                                      //
    //  Début préparation mise à jour app.xml               //
    //                                                      //
    //////////////////////////////////////////////////////////
   
    if (count($slides_supprimes) > 0) {
      $debut_chaine = strpos($app, "<Slides>");
      $fin_chaine = strpos($app, "</Slides>");
     
      // Récupère le nombre de slides total du document de présentation mis à jour.
      $nb_slides = substr($app, $debut_chaine + 8, $fin_chaine - $debut_chaine - 8) - count($slides_supprimes);;
     
      // Définit le contenu à jour du fichier app.xml qui récapitule les propriétés du document.
      $app = substr($app, 0, $debut_chaine + 8) . $nb_slides . substr($app, $fin_chaine, strlen($app) - $fin_chaine);
     
      $fin_boucle = false;
      $offset = 0;
      $nb_polices = 0;
      $nb_themes = 0;
     
      // Boucle sur les balises i4 afin de déterminer le nom de polices et thèmes (utile pour la suite) et mettre à jour le nombre de slides.
      while (! $fin_boucle) {
        $debut_chaine = strpos($app, "<vt:i4>", $offset);
        $fin_chaine = strpos($app, "</vt:i4>", $debut_chaine);
       
        $debut_chaine_bis = strpos($app, "<vt:lpstr>", $offset);
        $fin_chaine_bis = strpos($app, "</vt:lpstr>", $debut_chaine_bis);
       
        $propriete = substr($app, $debut_chaine_bis + 10, $fin_chaine_bis - $debut_chaine_bis - 10);
       
        if ($propriete == "Polices utilisées") {
          // Récupère le nombre de polices utilisées au sein du document de présentation.
          $nb_polices = substr($app, $debut_chaine + 7, $fin_chaine - $debut_chaine - 7);
        } else if ($propriete == "Thème") {
          // Récupère le nombre de thèmes utilisés au sein du document de présentation.
          $nb_themes = substr($app, $debut_chaine + 7, $fin_chaine - $debut_chaine - 7);
        } else if ($propriete == "Titres des diapositives") {
          // Définit le contenu à jour du fichier app.xml qui récapitule les propriétés du document.
          $app = substr($app, 0, $debut_chaine + 7) . $nb_slides . substr($app, $fin_chaine, strlen($app) - $fin_chaine);
         
          $fin_boucle = true;
        }
       
        $offset = $fin_chaine;
      }
     
      $debut_chaine = strrpos($app, "<vt:vector size=\"");
      $fin_chaine = strpos($app, "\" baseType=\"lpstr\">", $debut_chaine);
     
      // Récupère le nombre de balises lpstr mis à jour.
      $lpstr = substr($app, $debut_chaine + 17, $fin_chaine - $debut_chaine - 17) - count($slides_supprimes);
     
      // Définit le contenu à jour du fichier app.xml qui récapitule les propriétés du document.
      $app = substr($app, 0, $debut_chaine + 17) . $lpstr . substr($app, $fin_chaine, strlen($app) - $fin_chaine);
     
      // Définit la balise lpstr à supprimer (balise contenant le titre du slide courant à supprimer).
      $lpstr_delete = $nb_polices + $nb_themes + $cpt_slide;
     
      $offset = $fin_chaine;
     
      // Boucle sur les balises lpstr jusqu'à celle à supprimer puis on met à jour le fichier app.xml qui récapitule les propriétés du document.
      for ($i = 1 - $nb_polices - $nb_themes ; $i <= $lpstr_delete ; ++ $i) {
     
        $debut_chaine = strpos($app, "<vt:lpstr>", $offset);
        $fin_chaine = strpos($app, "</vt:lpstr>", $debut_chaine);
       
        if (in_array($i, $slides_supprimes)) {
          // Définit le contenu à jour du fichier app.xml qui récapitule les propriétés du document.
          $app = substr($app, 0, $debut_chaine) . substr($app, $fin_chaine + 11, strlen($app) - $fin_chaine - 11);
        } else {
          $offset = $fin_chaine;
        }
      }
     
      // Met à jour le fichier app.xml qui récapitule les propriétés du document.
      $zip -> FileReplace('docProps/app.xml', $app, TBSZIP_STRING);
    }
   
    //////////////////////////////////////////////////////////
    //                                                      //
    //  Fin préparation mise à jour app.xml                 //
    //                                                      //
    //////////////////////////////////////////////////////////
  }
 
?>
By: Alejandro
Date: 2012-12-21
Time: 18:07

Re: Supressing and/or adding slides to a pptx

Thx, I'll report my progress with this. (Gice me some time :))

Regards
Alejandro
By: Skrol29
Date: 2013-01-22
Time: 01:30

Re: Supressing and/or adding slides to a pptx

OpenTBS 1.8.0 beta has a new command for deleting slides in PPTX.
Any testing report is welcome.

http://www.tinybutstrong.com/dl.php?f=tbs_plugin_opentbs_beta.zip&s=2
By: Anonymous
Date: 2013-01-22
Time: 08:57

Re: Supressing and/or adding slides to a pptx

Great!! I haven't have time to work on this script, but I'll try the new version

Thx!