Articles on how to create OpenDocument invoices already exist but almost always they require you to start and use OpenOffice manually each time. Here, instead, I’ll show how to have your computer to do all your OpenDocument work for you.
The script explained below takes an ODF template like the one of the left and generates an ODF text file like the one you see on the right, which is ready to be printed or sent via email (follow the links to download the template or the resulting ODF invoice)
The advantages of creating the invoice with a script rather than with macros are explained in detail in the “Why and how ODF can save you a lot of time” page: in a nutshell, once you have created and saved with any ODF compliant word processor the initial template, the whole process is completely automatic, so it could run unattended and be integrated with other backend systems even where OpenOffice isn’t installed.
The script takes two arguments, the template name and an invoice data file:
odf_invoice_generator.sh odf_scripting_sample_invoice.odt my_data.sh
then opens the template, replaces placeholder data or strings like e.g. __Customer_name with the proper values from the invoice data file and finally saves everything as a separate OpenDocument text file. The data file has an extremely simple format, since it’s only variable assignments in shell script syntax:
marco => cat my_data.sh INVOICE_DATE='2010/05/15' VENDOR_CODE='007' PO_NUMBER='Purchase Order #1' TOTAL=10 ISSUE=150 DESCRIPTION='Here is your invoice'
and can be automatically generated on the spot by querying a database, by a Web server or in many other ways.
Here is the complete script, followed by an explanation:
0 #!/bin/bash 1 WORK_DIR=odt_invoice_generator_temp_dir 2 3 rm -rf $WORK_DIR 4 mkdir $WORK_DIR 5 FILENAME=`basename $1 .odt` 6 7 cp $1 $WORK_DIR/my_template.odt 8 cp $2 $WORK_DIR/my_data.sh 9 10 ## preparation 11 cd $WORK_DIR 12 mkdir work 13 mv my_template.odt work 14 cd work 15 source ../my_data.sh 16 unzip my_template.odt > /dev/null 17 rm my_template.odt 18 19 ## replace text strings 20 sed "s|__INVOICE_DATE|$INVOICE_DATE|" content.xml \ 21 | sed "s|__VENDOR_CODE|$VENDOR_CODE|" \ 22 | sed "s|__PO_NUMBER|$PO_NUMBER|" \ 23 | sed "s|__TOTAL|$TOTAL|g" \ 24 | sed "s|__ISSUE_NUMBER|$ISSUE|" \ 25 | sed "s|__DESCRIPTION|$DESCRIPTION|" \ 26 | sed "s|__Customer_name|$Customer_name|" \ 27 > custom_content.xml 28 mv custom_content.xml content.xml 29 30 ## zip everything, rename it as .odt file and clean up 31 find . -type f -print0 | xargs -0 zip ../$FILENAME > /dev/null 32 cd .. 33 mv $FILENAME.zip ../new_$FILENAME.odt 34 cd .. 35 rm -rf $WORK_DIR
The lines from 1 to 17 don’t do anything difficult: create a temporary working directory (WORK_DIR) copy the template inside it, unzip the template, and load from the data file (line 15) the values that must fill the template.
The (relatively) tricky part are lines 19 to 26: this is where a series of sed commands replaces each placeholder string in the content.xml file which contains the template text with its value loaded from my_data.sh.
If you change the template you must add here one sed command for each string you want to substitute; the order is not important. Just remember that if a string occurs multiple times, as is the case with the __TOTAL price, you must add the `g` (global) option to sed (cfr line 23), otherwise the script will only replace the first occurrence of that string.
If you have any question or suggestion about this script, please email me or (even better, add it in the comments.