I am wrinting some code which will benefit from a good templating system on Excel.

What I was expecting was the ability to insert TT [% ucfirst user.name %] in a binary .xls file and then run it through some "TT::Excel" and get a nice binary .xls with my data in it.

To my surprise "TT::Excel" does not exist. That is Excel::Template::TT and Excel::Template::Plus::TT (the two that come the closest to my dirty desires) use an xml template instead of a binary .xls.

My thing with the binary .xls template is it can be a really nice "user config file" for really basic users, it is really straight forward when it comes to formating WYSIWYG-ishly.

In trying to getting starter on a new module that merges TT with binary .xls templates (.xlsx would be nice too, should be covered by another nice Spreadsheet::xxxx) I have read TT docs and the Badger book to no avail (yes, "Extending the Template Toolkit" too). Seems that nobody tackles into reading a non-text based template; thus, no one goes past XML templates. I have skimmed through the code of Template::Service and Template::Provider (which seems like nice candidates) but it seems that from then on everything should be text or a really big rewrite (which is far from my abilities as was reading to full understanding the code itself).

Then comes request for thoughts on implementing this...
Maybe suggestions on an approach. My to three has: 1-Contacting someone who has this module already working by this means, failing that... 2-Reading the original .xls outputting to XML then Excel::Template::Plus::TT which will work but seems sloppy and some limitations arise from the commands being "in" the cells (specially for loops), 3-Finding some magic hook in TT where each line is read and extending that to Excel cells, 4-Using the grammar, stash and other modules from Template::Toolkit to create a new front end and never getting it done (again my limitations arise).

Comments welcome!

Replies are listed 'Best First'.
Re: Binary Excel Templates
by Corion (Patriarch) on Sep 14, 2010 at 06:54 UTC

    A "non-text based" template is usually quite hard, because usually, binary file formats tend to encode the length of fields somewhere. Your best approach is to read an Excel file using Spreadsheet::ParseExcel, replace all the values/loops within cells, and then write it out again using Spreadsheet::WriteExcel.

Re: Binary Excel Templates
by jmcnamara (Monsignor) on Sep 14, 2010 at 09:59 UTC
    An Excel file is a collection of binary files within a binary file. It contains several interlinked checksums and changing even one byte can cause it to become corrupted.

    As such it isn't possible to template a binary Excel file in the same way that you would template a text file.

    Hence the route that Excel::Template and Spreadsheet::WriteExcel::FromXML take where the tempate file is text or XML based and the backend uses Spreadsheet::WriteExcel to create the Excel binary file.

    The newer xlsx Excel files from Excel 2007 onwards are XML files contained in a zip file and are more suitable for TT style templating.

    As an aside I am working on an xlsx writer module that will eventually read and rewrite files as well so that it will be possible to use an existing file as a template (although not in the TT sense). However, that work is still at an early stage.

    --
    John.

Re: Binary Excel Templates
by locked_user sundialsvc4 (Abbot) on Sep 16, 2010 at 18:56 UTC

    Since the Excel XML format is a well-behaved, full featured (and thoroughly documented) format that Excel can both read and write, I strongly suggest that you use this approach.   If you are generating “stock” outputs (e.g. reports) in Excel format, templates are a reliable way to do it.   (I did this recently for Excel 2003 and impressed a lot of my client’s folks.)   If you need to do more advanced things, any XML-oriented package would be suitable and efficient.

    It seemed to me that MS has done their homework on this one.   It’s a good, clean design that can handle formulas, formatting, you name it.   And I think that there’s a formal DTD for it, as well.

    The final result is “exactly as the user expects.”   They do not have to do anything special, afaik, to handle the file.   Excel sees what the file contains and, “it just works.™”   In fact, I believe that their new .xslx format is XML-based behind the scenes.

Re: Binary Excel Templates
by Anonymous Monk on Sep 15, 2010 at 00:10 UTC

    Every Excel version since (I think...) 2003 has defined a very well thought-out XML format, which is easy to build using a template.

    AFAIK, if a file with the extension “.XLS” actually turns out to contain XML content ... “it just works.”

    I have used a similar strategy to populate a (live!) Excel spreadsheet within a generated web-page.   As long as the MIME-type is correct, it works.

Re: Binary Excel Templates
by psini (Deacon) on Sep 15, 2010 at 10:07 UTC

    I don't know what you need it for, so I've to ask: would your code equally benefit from a templating system on openoffice spreadsheet?

    Rule One: "Do not act incautiously when confronting a little bald wrinkly smiling man."

Re: Binary Excel Templates
by Anonymous Monk on Sep 14, 2010 at 06:41 UTC
    Maybe microsoft can help?
Re: Binary Excel Templates
by gbarco (Novice) on Sep 28, 2010 at 13:55 UTC

    First and foremost, thanks to everybody for you comments!

    I believe a little clarification regarding the "binary" format would be of use. My idea was to be able to have a binary excel template, read it using Spreadsheet::ParseExcel and feed text and variables to TT for processing and then Spreadsheet::WriteExcel to a new binary file. My idea was to plugin where TT reads and writes a text file and convert "read next line" to "read next row" and "write line" to "write row".

    Although the idea of marking and escaping the binary file directly seems like a nice candidate for the Obfuscation forum... my idea is to have a template that resembles the processed file for ease of template creation.

    My final solution will be to convert Excel to text including a little markup that identifies columns ends and rows ends. Since a way to have markup "outside" rows and columns will arise I will use TT markup in comments that will be converted to text putting it "before" the column marker. Then run TT on it and read through the text converting the original marks to "next column" and "next row"

    Thanks again to everybody.

      gbarco:

      Given your proposed usage, then I'd use XML, as mentioned in earlier posts. That way, you'd be able to:

      1. produce your template easily (generate it manually, or create a spreadsheet in Excel, save as .xlsx and edit it into shape),
      2. fill it out without jumping through flaming hoops (text files are *much* easier to munge, and XML files may be even easier with the various XML packages available on CPAN),
      3. and be able to have widespread usage. (Since XML is easy enough to read and manipulate, people using tools other than Excel may be able to use your files.

      Of course, that's just my $local_currency/50...

      ...roboticus