[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SF.net SVN: ledger-smb: [1657] trunk



Revision: 1657
          http://ledger-smb.svn.sourceforge.net/ledger-smb/?rev=1657&view=rev
Author:   tetragon
Date:     2007-09-23 17:41:09 -0700 (Sun, 23 Sep 2007)

Log Message:
-----------
Adding Excel and OpenDocument spreadsheet options.  ODS needs more work.

Modified Paths:
--------------
    trunk/Makefile.PL
    trunk/bin/am.pl

Added Paths:
-----------
    trunk/LedgerSMB/Template/ODS.pm
    trunk/LedgerSMB/Template/XLS.pm
    trunk/UI/am-list-accounts.odst
    trunk/UI/am-list-accounts.xlst

Added: trunk/LedgerSMB/Template/ODS.pm
===================================================================
--- trunk/LedgerSMB/Template/ODS.pm	                        (rev 0)
+++ trunk/LedgerSMB/Template/ODS.pm	2007-09-24 00:41:09 UTC (rev 1657)
@@ -0,0 +1,167 @@
+
+=head1 NAME
+
+LedgerSMB::Template::ODS  Template support module for LedgerSMB
+
+=head1 SYNOPSIS
+
+OpenDocument Spreadsheet output.
+
+=head1 METHODS
+
+=over
+
+=item get_template ($name)
+
+Returns the appropriate template filename for this format.  '.xlst' is the
+extension that was chosen for the templates.
+
+=item preprocess ($vars)
+
+Returns $vars.
+
+=item process ($parent, $cleanvars)
+
+Processes the template for text.
+
+=item postprocess ($parent)
+
+Returns the output filename.
+
+=back
+
+=head1 Copyright (C) 2007, The LedgerSMB core team.
+
+This work contains copyrighted information from a number of sources all used
+with permission.  
+
+It is released under the GNU General Public License Version 2 or, at your 
+option, any later version.  See COPYRIGHT file for details.  For a full list 
+including contact information of contributors, maintainers, and copyright 
+holders, see the CONTRIBUTORS file.
+=cut
+
+package LedgerSMB::Template::ODS;
+
+use Error qw(:try);
+use CGI::Simple::Standard qw(:html);
+use Template;
+use XML::Twig;
+use OpenOffice::OODoc;
+use LedgerSMB::Template::TTI18N;
+
+sub get_template {
+	my $name = shift;
+	return "${name}.odst";
+}
+
+sub preprocess {
+    my $rawvars = shift;
+    my $vars;
+    my $type = ref $rawvars;
+
+    #XXX fix escaping function
+    return $rawvars if $type =~ /^LedgerSMB::Locale/;
+    if ( $type eq 'ARRAY' ) {
+        for (@{$rawvars}) {
+            push @{$vars}, preprocess( $_ );
+        }
+    } elsif (!$type) {
+        return escapeHTML($rawvars);
+    } else { # Hashes and objects
+        for ( keys %{$rawvars} ) {
+            $vars->{preprocess($_)} = preprocess( $rawvars->{$_} );
+        }
+    }
+    
+    return $vars;
+}
+
+sub _worksheet_handler {
+	if ($sheet) {
+		$rowcount = -1;
+		$currcol = 0;
+	}
+	$sheet = $ods->getTable(0, $_->{att}->{rows}, $_->{att}->{columns});
+	$ods->renameTable($sheet, $_->{att}->{name});
+}
+
+sub _row_handler {
+	$rowcount++;
+	$currcol = 0;
+}
+
+sub _cell_handler {
+	my $cell = $ods->getCell(-1, $rowcount, $currcol);
+	$ods->cellValue($cell, $_->{att}->{text});
+	$currcol++;
+}
+
+sub _ods_process {
+	my ($filename, $template, $user) = @_;
+
+	# the handlers need these vars in common
+	local $ods = ooDocument(file => $filename, create => 'spreadsheet');
+	local $sheet;
+	local $rowcount;
+	local $currcol;
+	my $parser = XML::Twig->new(
+		start_tag_handlers => {
+			worksheet => \&_worksheet_handler,
+			row => \&_row_handler,
+			},
+		twig_handlers => {
+			cell => \&_cell_handler,
+			}
+		);
+	$parser->parse($template);
+	$parser->flush;
+	#$ods->normalizeSheet($sheet, $rowcount, $colcount);
+	$ods->save;
+}
+
+sub process {
+	my $parent = shift;
+	my $cleanvars = shift;
+	my $template;
+	my $source;
+	my $tempdir = ${LedgerSMB::Sysconfig::tempdir};
+	my $output = '';
+	$parent->{outputfile} ||= "$tempdir/$parent->{template}-output-$$";
+
+	if (ref $parent->{template} eq 'SCALAR') {
+		$source = $parent->{template};
+	} elsif (ref $parent->{template} eq 'ARRAY') {
+		$source = join "\n", @{$parent->{template}};
+	} else {
+		$source = get_template($parent->{template});
+	}
+	$template = Template->new({
+		INCLUDE_PATH => $parent->{include_path},
+		START_TAG => quotemeta('<?lsmb'),
+		END_TAG => quotemeta('?>'),
+		DELIMITER => ';',
+		DEBUG => ($parent->{debug})? 'dirs': undef,
+		DEBUG_FORMAT => '',
+		}) || throw Error::Simple Template->error(); 
+
+	if (not $template->process(
+		$source, 
+		{%$cleanvars, %$LedgerSMB::Template::TTI18N::ttfuncs,
+			'escape' => \&preprocess},
+		\$output, binmode => ':utf8')) {
+		throw Error::Simple $template->error();
+	}
+	&_ods_process("$parent->{outputfile}.ods", $output, $parent->{myconfig});
+
+	parent->{mimetype} = 'application/vnd.oasis.opendocument.spreadsheet';
+}
+
+sub postprocess {
+	my $parent = shift;
+	$parent->{rendered} = "$parent->{outputfile}.ods";
+	return $parent->{rendered};
+}
+
+1;
+

Added: trunk/LedgerSMB/Template/XLS.pm
===================================================================
--- trunk/LedgerSMB/Template/XLS.pm	                        (rev 0)
+++ trunk/LedgerSMB/Template/XLS.pm	2007-09-24 00:41:09 UTC (rev 1657)
@@ -0,0 +1,123 @@
+
+=head1 NAME
+
+LedgerSMB::Template::XLS  Template support module for LedgerSMB
+
+=head1 SYNOPSIS
+
+Excel spreadsheet output.  For details about the XML template document
+elements, see Excel::Template.  For details about various parameters used, see
+Spreadsheet::WriteExcel.  As this module uses Excel::Template::Plus, flow
+control and variable substitution are handled with TT with the usual for LSMB
+tag formatting of <?lsmb foo ?> instead of the more HTML::Template-like forms
+of Excel::Template.
+
+=head1 METHODS
+
+=over
+
+=item get_template ($name)
+
+Returns the appropriate template filename for this format.  '.xlst' is the
+extension that was chosen for the templates.
+
+=item preprocess ($vars)
+
+Returns $vars.
+
+=item process ($parent, $cleanvars)
+
+Processes the template for text.
+
+=item postprocess ($parent)
+
+Returns the output filename.
+
+=back
+
+=head1 Copyright (C) 2007, The LedgerSMB core team.
+
+This work contains copyrighted information from a number of sources all used
+with permission.  
+
+It is released under the GNU General Public License Version 2 or, at your 
+option, any later version.  See COPYRIGHT file for details.  For a full list 
+including contact information of contributors, maintainers, and copyright 
+holders, see the CONTRIBUTORS file.
+=cut
+
+package LedgerSMB::Template::XLS;
+
+use Error qw(:try);
+use CGI::Simple::Standard qw(:html);
+use Excel::Template::Plus;
+use LedgerSMB::Template::TTI18N;
+
+sub get_template {
+	my $name = shift;
+	return "${name}.xlst";
+}
+
+sub preprocess {
+    my $rawvars = shift;
+    my $vars;
+    my $type = ref $rawvars;
+
+    #XXX fix escaping function
+    return $rawvars if $type =~ /^LedgerSMB::Locale/;
+    if ( $type eq 'ARRAY' ) {
+        for (@{$rawvars}) {
+            push @{$vars}, preprocess( $_ );
+        }
+    } elsif (!$type) {
+        return escapeHTML($rawvars);
+    } else { # Hashes and objects
+        for ( keys %{$rawvars} ) {
+            $vars->{preprocess($_)} = preprocess( $rawvars->{$_} );
+        }
+    }
+    
+    return $vars;
+}
+
+sub process {
+	my $parent = shift;
+	my $cleanvars = shift;
+	my $template;
+	my $source;
+	my $tempdir = ${LedgerSMB::Sysconfig::tempdir};
+	$parent->{outputfile} ||= "$tempdir/$parent->{template}-output-$$";
+
+	if (ref $parent->{template} eq 'SCALAR') {
+		$source = $parent->{template};
+	} elsif (ref $parent->{template} eq 'ARRAY') {
+		$source = join "\n", @{$parent->{template}};
+	} else {
+		$source = get_template($parent->{template});
+	}
+	$template = Excel::Template::Plus->new(
+		engine => 'TT',
+		template => $source,
+		params => {%$cleanvars, %$LedgerSMB::Template::TTI18N::ttfuncs,
+			'escape' => \&preprocess},
+		config => {
+			INCLUDE_PATH => $parent->{include_path},
+			START_TAG => quotemeta('<?lsmb'),
+			END_TAG => quotemeta('?>'),
+			DELIMITER => ';',
+			DEBUG => ($parent->{debug})? 'dirs': undef,
+			DEBUG_FORMAT => '',},
+	);
+	$template->write_file("$parent->{outputfile}.xls");
+
+	parent->{mimetype} = 'application/vnd.ms-excel';
+}
+
+sub postprocess {
+	my $parent = shift;
+	$parent->{rendered} = "$parent->{outputfile}.xls" if $parent->{outputfile};
+	return $parent->{rendered};
+}
+
+1;
+

Modified: trunk/Makefile.PL
===================================================================
--- trunk/Makefile.PL	2007-09-23 20:42:04 UTC (rev 1656)
+++ trunk/Makefile.PL	2007-09-24 00:41:09 UTC (rev 1657)
@@ -28,7 +28,6 @@
 requires 'Config::Std';
 requires 'MIME::Lite';
 requires 'Template' => '2.14';
-requires 'Template::Latex';
 requires 'Error';
 requires 'CGI::Simple';
 
@@ -49,14 +48,19 @@
     'Getopt::Long' => 0,
     'FileHandle' => 0;
 
-#feature 'Excel output',
-#    -default => 0,
-#    'Excel::Template::Plus' => 0;
-#
-#feature 'OpenOffice.org output',
-#    -default => 0,
-#    'XML::Twig' => 0,
-#    'OpenOffice::OODoc' => 0;
+# Rendering options
+feature 'PDF and Postscript output'
+    -default => 0,
+    'Template::Latex' => 0;
 
+feature 'OpenOffice.org output',
+    -default => 0,
+    'XML::Twig' => 0,
+    'OpenOffice::OODoc' => 0;
+
+feature 'Excel output',
+    -default => 0,
+    'Excel::Template::Plus' => 0;
+
 auto_install;
 WriteAll;

Added: trunk/UI/am-list-accounts.odst
===================================================================
--- trunk/UI/am-list-accounts.odst	                        (rev 0)
+++ trunk/UI/am-list-accounts.odst	2007-09-24 00:41:09 UTC (rev 1657)
@@ -0,0 +1,30 @@
+<workbook>
+	<worksheet name="test" rows="<?lsmb rows.size + 1 ?>" columns="<?lsmb columns.size ?>">
+		<format bottom="1"><row>
+	<?lsmb FOREACH column IN columns ?>
+	<?lsmb IF heading.$column.text ?>
+			<cell text="<?lsmb heading.$column.text ?>" />
+	<?lsmb ELSE ?>
+			<cell text="<?lsmb heading.$column ?>" />
+	<?lsmb END; END ?>
+		</row></format>
+	<?lsmb FOREACH row IN rows ?>
+		<row>
+		<?lsmb FOREACH column IN columns ?>
+			<?lsmb IF row.$column.href ?>
+			<cell text="<?lsmb row.$column.text ?>" />
+			<?lsmb ELSE ?>
+			<cell text="<?lsmb row.$column ?>" />
+			<?lsmb END ?>
+		<?lsmb END ?>
+		</row>
+	<?lsmb END ?>
+	<?lsmb IF totals; t = [] ?>
+	<row>
+		<?lsmb FOREACH column IN columns ?>
+		<cell text="<?lsmb totals.$column ?>" />
+		<?lsmb END ?>
+	</row>
+	<?lsmb END ?>
+	</worksheet>
+</workbook>

Added: trunk/UI/am-list-accounts.xlst
===================================================================
--- trunk/UI/am-list-accounts.xlst	                        (rev 0)
+++ trunk/UI/am-list-accounts.xlst	2007-09-24 00:41:09 UTC (rev 1657)
@@ -0,0 +1,30 @@
+<workbook>
+	<worksheet name="test">
+		<format bottom="1"><row>
+	<?lsmb FOREACH column IN columns ?>
+	<?lsmb IF heading.$column.text ?>
+			<cell text="<?lsmb heading.$column.text ?>" />
+	<?lsmb ELSE ?>
+			<cell text="<?lsmb heading.$column ?>" />
+	<?lsmb END; END ?>
+		</row></format>
+	<?lsmb FOREACH row IN rows ?>
+		<row>
+		<?lsmb FOREACH column IN columns ?>
+			<?lsmb IF row.$column.href ?>
+			<cell text="<?lsmb row.$column.text ?>" />
+			<?lsmb ELSE ?>
+			<cell text="<?lsmb row.$column ?>" />
+			<?lsmb END ?>
+		<?lsmb END ?>
+		</row>
+	<?lsmb END ?>
+	<?lsmb IF totals; t = [] ?>
+	<row>
+		<?lsmb FOREACH column IN columns ?>
+		<cell text="<?lsmb totals.$column ?>" />
+		<?lsmb END ?>
+	</row>
+	<?lsmb END ?>
+	</worksheet>
+</workbook>

Modified: trunk/bin/am.pl
===================================================================
--- trunk/bin/am.pl	2007-09-23 20:42:04 UTC (rev 1656)
+++ trunk/bin/am.pl	2007-09-24 00:41:09 UTC (rev 1657)
@@ -436,20 +436,23 @@
     }
 
     my @buttons;
-    push @buttons, {
-        name => 'action',
-        value => 'csv_list_account',
-        text => $locale->text('CSV Report'),
-        type => 'submit',
-        class => 'submit',
-    };
+    for my $type (qw(CSV XLS ODS)) {
+        push @buttons, {
+            name => 'action',
+            value => lc "${type}_list_account",
+            text => $locale->text("$type Report"),
+            type => 'submit',
+            class => 'submit',
+        };
+    }
 
+    my $format = uc substr($form->{action}, 0, 3);
     my $template = LedgerSMB::Template->new(
         user => \%myconfig, 
         locale => $locale,
         path => 'UI',
         template => 'am-list-accounts',
-        format => ($form->{action} =~ /^csv/)? 'CSV': 'HTML');
+        format => ($format ne 'LIS')? $format: 'HTML');
     $template->render({
         form => \%$form,
         buttons => ..hidden..,
@@ -460,6 +463,8 @@
 }
 
 sub csv_list_account { &list_account }
+sub xls_list_account { &list_account }
+sub ods_list_account { &list_account }
 
 sub delete_account {
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.