sfTinyDocPlugin - 1.0.2

symfony sfTinyDoc plugin

You are currently browsing
the website for symfony 1

Visit the Symfony2 website


« Back to the Plugins Home

Signin


Forgot your password?
Create an account

Tools

Stats

advanced search
Information Readme Releases Changelog Contribute
Show source

sfTinyDocPlugin

Overview

The sfTinyDocPlugin allows to generate OpenOffice (OpenDocument) and Word 2007 documents with TinyButStrong template engine.

  • Prerequisite :

    • PHP 5.2
    • symfony framework 1.0, 1.1 and 1.2 (for the plugin)
  • History :

    The previous class was named tbsOOo. I rewrite the class to have a clean code with new methods and add some new functionnality like :

    • works with the last version of TinyButStrong
    • better support of specials characters like carriage return, new line and tab
    • can generate Word 2007 documents
    • can add images (only OpenDocument)
    • can merge data with native format in OpenOffice spreadsheet
    • two methods to zip and unzip the office files (zip with command line and the pecl ZipArchive)
    • and a plugin for symfony framework : sfTinyDocPlugin
  • The office formats supported :

    • OpenOffice 1.0 or OpenDocument 1.0
    • OpenOffice 2.0 or OpenDocument 1.1
    • Word 2007
  • It's useful :

    • To create word processing and spreadsheet documents.
    • To create reports, bill, orders.
    • To create mailing.
    • To create multi pages documents.
    • To use the power of the TinyButStrong template engine syntax :
      • Merge fields
      • Merge blocks (repetitive fields)
      • and more...
  • It's not :

    • To create an Office document from scratch.
    • To convert a document from OpenOffice to Word or to PDF or else. See the project PyODConverter to do that.
  • Avantages :

    • No installation of OpenOffice on the server side.
    • Works on *nix, win and other systems.
    • Templates can be created and modified easyly by designer.
    • Templates layouts and styles are made with OpenOffice or Word2007 application.
    • For the symfony framework
      • Works with sf1.0, sf1.1 and sf1.2
      • No dependance with ORM
      • Template have the same location as the symfony templates.
      • Template name have the same name as the symfony templates. moduleName/templates/actionNameSuccess.odt
      • Get the config from app.yml.
  • Only for OpenDocument (OpenOffice) :

    • Merge pictures dynamicaly with the new parameter named 'image'.
    • Data in spreadsheet are converted to native OpenOffice format with the new parameter named 'type'.
      • Useful to work with spreadsheet formulas
      • Useful to work the spreadsheet formats
    • Transform data to a linkable text with the new parameter named 'link'.
  • Limitations :

    • Can't merge collection of objects (iterator not supported in TinyButStrong, soon in next version), you have to transform to an array before.

      • For Propel write your own method like asArray() in the Jobeet tutorial, see day 16.
      • For Doctrine use the magic method : $result->toArray (false | true) to transform the result to an array, see : doctrine api
    • Can't change a style of the Office document by code, the styles are fix when you editing your Office document.

    • Can't merge global vars [var.xxx], use method mergeXmlField() in place of use globals vars
    • Can't merge sub-block because TinyButStrong need global vars, see headergrp syntax

Installation

  • Install sfTinyDocPlugin :

    $ pear channel-discover pear.symfony-project.com
    $ symfony plugin-install http://plugins.symfony-project.com/sfTinyDocPlugin
    

    Or from the SVN repository

    $ svn co http://svn.symfony-project.com/plugins/sfTinyDocPlugin/trunk/
    
  • Optionally add the following config to app.yml :

    all:
      sf_tiny_doc_plugin:
        zip_method:    shell             # the method to zip/unzip : shell | ziparchive
        zip_bin:       zip               # the binary to zip   for 'shell' method
        unzip_bin:     unzip             # the binary to unzip for 'shell' method
        process_dir:   %SF_WEB_DIR%/tmp  # the process directory
  • Clear your cache :

    $ ./symfony cc
    
  • Configure the method to zip/unzip office documents :

    • Method 1 : shell (by default)

      To install Zip on Red Hat Enterprise Linux or CentOS

        $ yum install zip
      
    • Method 2 : ziparchive

      To install Pecl ZipArchive on Red Hat Enterprise Linux or CentOS

        $ yum install httpd-devel   # if necessary
        $ pecl install zip
      
  • Create a directory where to process temporary files, by example on web root :

    $ mkdir web/tmp
    $ chmod 777 web/tmp
    

My first OpenOffice text document in action (.odt)

  • Create a new module doc in your application

  • Create an action basic in doc/actions/actions.class.php

    <?php
    public function executeBasic(sfWebRequest $request)
    {
      // create the document
      $doc = new sfTinyDoc();
      $doc->createFrom();
      $doc->loadXml('content.xml');
      $doc->mergeXmlField('field1', 'variable');
      $doc->mergeXmlField('field2', array('id' => 55, 'name' => 'bob'));
      $doc->mergeXmlField('field3', $doc);
      $doc->mergeXmlBlock('block1',
        array(
          array('firstname' => 'John'   , 'lastname' => 'Doe'),
          array('firstname' => 'Douglas', 'lastname' => 'Adams'),
          array('firstname' => 'Roger'  , 'lastname' => 'Waters'),
        )
      );
      $doc->saveXml();
      $doc->close();
     
      // send and remove the document
      $doc->sendResponse();
      $doc->remove();
     
      throw new sfStopException;
    }
  • Create an OpenOffice text document (.odt) and paste this.

    $doc->mergeXmlField() with a string
    
    [field1]
    
    $doc->mergeXmlField() with an array
    
    [field2.id] [field2.name]
    
    $doc->mergeXmlField() with an object
    
    [field3.getZipMethod]
    [field3.getZipBinary]
    [field3.getUnzipBinary]
    
    $doc->mergeXmlBlock() with an array
    
    [block1;block=begin][block1.$] [block1.firstname] [block1.lastname]
    [block1;block=end]
    Num rows : [block1.#]
    
  • Save the document as basicSuccess.odt in template directory doc/templates/

  • You can now test my first doc in a browser the result : doc/basic

    The result is something like this :

    $doc->mergeXmlField() with a string
    
    variable
    
    $doc->mergeXmlField() with an array
    
    55 bob
    
    $doc->mergeXmlField() with an object
    
    shell
    zip
    unzip
    
    $doc->mergeXmlBlock() with an array
    
    0 John Doe
    1 Douglas Adams
    2 Roger Waters
    
    Num rows : 3
    

and for OpenOffice calc document (.ods)

  • Change in your action

    <?php
    $doc->createFrom();

    By

    <?php
    $doc->createFrom(array('extension' => 'ods'));
  • Create an OpenOffice spreadsheed document (.ods) and paste the same as before.

    $doc->mergeXmlField() with a string
    
    [field1]
    
    $doc->mergeXmlField() with an array
    
    [field2.id] [field2.name]
    
    $doc->mergeXmlField() with an object
    
    [field3.getZipMethod]
    [field3.getZipBinary]
    [field3.getUnzipBinary]
    
    $doc->mergeXmlBlock() with an array
    
    [block1;block=begin][block1.$] [block1.firstname] [block1.lastname]
    [block1;block=end]
    Num rows : [block1.#]
    
  • Save the document as basicSuccess.ods in template directory doc/templates/

  • You can now test my OpenOffice calc document in a browser the result : doc/basicCalc

and for Word2007 document (.docx)

  • Change in your action

    <?php
    $doc->createFrom();
    $doc->loadXml('content.xml');

    By

    <?php
    $doc->createFrom(array('extension' => 'docx'));
    $doc->loadXml('word/document.xml');
  • Create an Word2007 document (.docx) and paste the same as before.

    $doc->mergeXmlField() with a string
    
    [field1]
    
    $doc->mergeXmlField() with an array
    
    [field2.id] [field2.name]
    
    $doc->mergeXmlField() with an object
    
    [field3.getZipMethod]
    [field3.getZipBinary]
    [field3.getUnzipBinary]
    
    $doc->mergeXmlBlock() with an array
    
    [block1;block=begin][block1.$] [block1.firstname] [block1.lastname]
    [block1;block=end]
    Num rows : [block1.#]
    
  • Save the document as basicSuccess.docx in template directory doc/templates/

  • You can now test the Word2007 document in a browser the result : doc/basicWord

    Tips

    <?php
    $doc->createFrom();  // the defaut extension is 'odt'
    $doc->loadXml();     // the defaut XML filename is 'content.xml'

The basic structure of OpenDocument (OpenOffice) and Word 2007 files

  • The documents are a zip archive format with these main files :

                      OpenDocument      Word2007
    
    content           content.xml       word/document.xml
    meta              meta.xml          ? 
    settings          settings.xml      word/settings.xml
    styles            styles.xml        word/styles.xml     
    header            styles.xml        word/header1.xml     
    footer            styles.xml        word/footer1.xml     
    

    content.xml is the main file to merge in OpenOffice documents.

    word/document.xml is the main file to merge in Word 2007 documents.

    content.xml is the defaut file in loadXml() method.

    See more on :

  • The XML tags you have to know :

                HTML tags     OpenDocument XML tags     Word2007 XML tags
    
    table       <table>       <table:table>             <w:tbl>
    row         <tr>          <table:table-row>         <w:tr>
    cell        <td>          <table:table-cell>        <w:tc>
    paragraph   <p>           <text:p>                  <w:p>
    

The method to merge data

  • Before merging data, you have to load the XML file with the loadXml() method.
  • After merging data, you have to save the result of merging in the XML file with the saveXml() method.

    Each time you have to merge data with an another file you have to

    <?php
    $doc->loadXml('content.xml');
    // ...
    $doc->mergeXml(...);
    $doc->mergeXmlField(...);
    $doc->mergeXmlBlock(...);
    $doc->mergeXml(...);
    // ...
    $doc->saveXml();
     
     
    $doc->loadXml('styles.xml');
    // ...
    $doc->mergeXml(...);
    $doc->mergeXmlField(...);
    $doc->mergeXmlBlock(...);
    $doc->mergeXml(...);
    // ...
    $doc->saveXml();
  • There two different methods to merge data, field and block

    • method : mergeXmlField($name, $data)

      MergeField it's for fields (one time)

    • method : mergeXmlBlock($name, $data)

      MergeBlock it's for repetive fields to merge all items from an array.

TIPS

If you don't define the begin block and the end of the block, the fields are merged one time.

  • The two methods call the generic method : mergeXml($options, $data)

    With this method, you can pass some parameters in the $options array like :

    • name: The tag name in the template ('block' by default)
    • type: The tag type in the template ('field' | 'block' - 'block' by default)
    • data_type: The data type - only for type = 'block' ('array' by default)
    • charset: The data charset ('UTF-8' by default)
    • is_escape: If data are escaped (true by default)
    • callback: The callback to encode data ('=~encodeData' by default)

    Example :

      [php]
      <?php
      $doc->mergeXml(
        array(
          'name'      => 'b1',
          'type'      => 'block',
          'data_type' => 'array',
          'charset'   => 'UTF-8',
          'is_escape' => true,
        ),
        $data
      );
    

TinyButStrong templates syntax (TBS tags)

For all parameters of TinyButStrong, have a look to the TinyButStrong manual

The TBS field parameters

  • ifempty
  • if expr1=expr2;then val1;else val2
  • frm=format1|format2|format3|format4
  • magnet
  • mtype
  • ope=action

The TBS block parameters

  • block
  • $
  • #
  • nodata
  • bmagnet
  • headergrp
  • footergrp
  • splittergrp
  • parentgrp
  • serial
  • p1=val1 (for subquery, this param don't work inside a class, like for sfTinyDoc)
  • when expr1=expr2
  • default
  • several

New parameters for OpenOffice

  • image : This parameter is to merge image automaticaly

    • image or image=100% are equivalent
    • image=[ratio] fix the ratio of the merged image
    • image=fit the merged image is reduced or increased to fit on template's image size with the best ratio
    • image=max the merged image is limited to the maximum template's image size

      Examples :

      [field.src;image]
      [block.src;image]
      [block.src;image=50%]
      [block.src;image=max]
      [block.src;image=fit]

NOTES

Note #1 : The TBS tag is set in the image name. Use OpenOffice dialog box image property to edit.

Note #2 : The file image is added into the document and you don't have to use the addFile() method.

Note #3 : If the image is empty or not found, the image is removed.

  • link : This parameter to transform to a linkable text

    • link
    • link=click here to render a different text, "click here" in this example
  • type : This parameter fixes the type of the cell, not the format (only for spreadsheet).

    • type=currency or the shorten way type=c. Input data is float.
    • type=date or type=d. Input data is string like 'Y-m-d' or 'Y-m-d H:i:s'.
    • type=number or type=n. Input data is float or integer.
    • type=percent or type=p. Input data is float.
    • type=time or type=t. Input data is string like 'H:i:s'.

      Examples :

      [field;type=n]
      [field.data;type=date]
      [block.data;type=percentage]
      [block.data;type=time]

NOTES

Note #1 : Only one TBS field can be merge in a cell when the parameter type is set.

Note #2 : To fix the format the cell, use OpenOffice dialog box format for that. Don't use frm parameter.

Examples

As in French we can said, "Un dessin vaut mieux qu'un long discours", here some examples for sfTinyDocPlugin

Releases

  • Release 1.0.2

    • ADDED : support differents units for picture (cm, mm, in, px)
    • ADDED : the tinyDoc version in a constant, tinyDoc::VERSION
    • FIXED : news parameters [link, image and type] can merge with data type var and array
  • Release 1.0.1

    • ADDED : parameter [image] to merge pictures for OpenDocument
    • ADDED : parameter [link] to merge linkable text for OpenDocument
  • Release 1.0.0

    • Initial

Bugs / Features

  • add formula support in spreadsheet

    <?php
    <table:table-cell table:formula="of:=IF([.B2]&gt;0;&quot;true&quot;;&quot;false&quot;)" office:value-type="string" office:string-value="true">
      <text:p>true</text:p>
    </table:table-cell>
  • add optionals parameters in method sendResponse()

  • support native format (float, percentage, currency, date, time) in word processing tables (* not easy)

  • support merge images with a block in spreadsheet (* not easy)

  • next TinyButStrong version (3.5 ?) to support iterators and a new parameter to merge sub-block.

Todo

  • More documentation
  • More examples on specials TBS parameters

Support

Mailing-list : http://groups.google.fr/group/tinydoc

Please email to the mailing-list tinydoc@googlegroups.com for support (register only).

Bug tracker : http://trac.symfony-project.org/browser/plugins/sfTinyDocPlugin

The tbsOOo class is no longer supported, and I strongly discourage his use.

Contribution

If you have feature suggestions, bug reports, patches, usage examples for the documentation or want to become an active contributor, send me an email to: olivierloynet [at] gmail [dot] com

Any help is welcome!

Acknowledgements

Special thanks to Vincent who write TinyButStrong.

To Romain, Pierre and Cecile.