The sales people always misconfigure text documents. It's a law. They can't just fill the fields and print it, they have to change something, move the margin a little to the left, change that font, whatever...

As I really love a well-formatted document (sometimes a designer does that), I started to think how to prevent the sales people from misformatting it, then I ended providing a CGI at my machine, which list all relevant document models available, then ask the user to change the values of the fields, gives the possibility to remove some paragraphs (the template documents are always as complete as possible) that doesn't apply to that case, and then promptly offer to the user a already-filled-no-reason-to-touch document, which can simply be printed.

The script lists the file from the $templates_dir variable, which is setted up in the beginning of the script. For the sake of simplicity, I built the html using the CGI module. Please read the use's to know the dependancies... And, remember it's a CGI, so, unless you're really good in reading HTML, run it in a web serveer...

BTW, there are few output strings in the code, they're in portuguese 'cause I didn't have the courage to translate them... So, if your lost just use a web translator...

#!/usr/bin/perl use strict; use Symbol; use CGI; use CGI::Untaint; use OpenOffice::OODoc::Document; use File::Temp qw(tempfile tempdir); use utf8; my $cgi = CGI->new(); my $handler = CGI::Untaint->new($cgi->Vars()); my $templates_dir = '/dir/to/templates/'; my $tmpdir = tempdir(); chdir $tmpdir; if ($cgi->param('fill')) { do_fill(); } elsif ($cgi->param('template')) { do_form(); } else { do_first_form(); } exit 0; sub do_first_form { print ( $cgi->header(), $cgi->start_html('Selecione o modelo'), $cgi->h1('Selecione o modelo de documento'), $cgi->start_form(-method => 'GET') ); # Obter os modelos disponiveis... my $dir_handle = gensym(); opendir $dir_handle, $templates_dir; my @files = grep { /.odt$/ } readdir($dir_handle); print $cgi->radio_group ( -name => 'template', -values => \@files, -linebreak => 'true' ); print ( $cgi->submit(), $cgi->end_form(), $cgi->hr(), $cgi->end_html() ); } sub do_form { my $template = $handler->extract( -as_printable => 'template'); my $document = OpenOffice::OODoc::Document->new(file => $templates +_dir.$template); print ( $cgi->header(), $cgi->start_html('Preencha o documento'), $cgi->h1("Preenchendo o documento $template"), $cgi->start_form(-method => 'GET'), $cgi->hidden('template',$template), $cgi->hidden('fill','1') ); my %fields = obter_user_fields($document); if (%fields) { print $cgi->h2('Campos'); print "<TABLE WIDTH=100%>"; } foreach my $field (sort { $fields{$a}{order} <=> $fields{$b}{order +} } keys %fields) { print ( "<TR><TD>$field</TD><TD width=100%>", $cgi->textfield ( -name => 'field_'.$field, -default => $fields{$field}{value}, -style => 'width: 100%' ), "</TD></TR>".$/ ); } if (%fields) { print "</TABLE>"; } print $cgi->h2('Selecione para remover parágrafos do Documento'); my @paragraphs = $document->getParagraphList(); my $count = 0; foreach my $para (@paragraphs) { my $text = $document->getText($para); $text =~ s/\</\&lt;/g; $text =~ s/\>/\&gt;/g; print "<P><INPUT TYPE=CHECKBOX NAME=para_$count>".$text."</P>" +; $count++; } print $cgi->submit(), $cgi->end_form(), $cgi->end_html(); } sub obter_user_fields { my $document = shift; my @elems = $document->selectElements('//text:user-field-decl'); my %list; my $order = 0; foreach my $elem (@elems) { my $name = $document->getAttribute($elem,'text:name'); $list{$name}{value} = $document->getAttribute($elem, 'office:s +tring-value'); $list{$name}{order} = $order++; } return %list; } sub do_fill { my $template = $handler->extract( -as_printable => 'template'); my $document = OpenOffice::OODoc::Document->new(file => $templates +_dir.$template); my @params = $cgi->param(); my (%fields, @paragraphs); foreach my $param (@params) { if ($param =~ /^field_/) { my $field = $param; $field =~ s/field_//; $fields{$field} = $cgi->param($param); } elsif ($param =~ /^para_/) { my $para = $param; $para =~ s/para_//; push @paragraphs, $para; } } my @elems = ( $document->selectElements('//text:user-field-decl'), $document->selectElements('//text:user-field-get') ); foreach my $elem (@elems) { my $name = $document->getAttribute($elem,'text:name'); my $value = $fields{$name}; unless (defined $value) { next; } my $field = $elem->name; if ($field =~ /user-field-decl/) { $document->setAttributes($elem, 'office:string-value' => $ +value); } elsif ($field =~ /user-field-get/) { $document->setText($elem,$value); } } foreach my $para_num (reverse sort @paragraphs) { my $para = $document->getParagraph($para_num); $document->removeElement($para); } # Cuspir o conteúdo do arquivo para STDOUT... my ($fh,$filename) = tempfile(); $document->save($filename); close $fh; my ($buf,$tempfile); open $tempfile, $filename || die $!; print $cgi->header ( -type => 'application/octet-stream', -attachment => 'preenchido.odt' ); while (read($tempfile,$buf,10)) { print $buf; } }
daniel