From ffb40290f88380418635a951dbb0788bf7b7e3ce Mon Sep 17 00:00:00 2001 From: Fridolin Somers Date: Mon, 18 Feb 2019 17:33:37 +0100 Subject: [PATCH] Bug 21560: create Koha::Util::OpenDocument with subroutine for ODS generation There is nearly the same code in misc/cronjobs/gather_print_notices.pl and reports/guided_reports.pl. This patch creates a new module with subroutine called by both scripts. If file path or content is undefined, subroutine will just return undef. If content is an empty arrayref, empty ods file is still generated. Unicode encoding is kept outisde because it may not be necessary. Note that for print notices the first line of message is always the column names so it is extracted only from first message. Test plan : Run previous patches test plans and check ODS files are the same. Signed-off-by: Martin Renvoize Signed-off-by: Nick Clemens --- Koha/Util/OpenDocument.pm | 95 +++++++++++++++++++++++++++ misc/cronjobs/gather_print_notices.pl | 66 +++++++------------ reports/guided_reports.pl | 53 +++++---------- 3 files changed, 135 insertions(+), 79 deletions(-) create mode 100644 Koha/Util/OpenDocument.pm diff --git a/Koha/Util/OpenDocument.pm b/Koha/Util/OpenDocument.pm new file mode 100644 index 0000000000..0fc807236a --- /dev/null +++ b/Koha/Util/OpenDocument.pm @@ -0,0 +1,95 @@ +package Koha::Util::OpenDocument; + +# Copyright 2019 Biblibre +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use Encode qw( decode ); +use File::Temp; +use File::Basename qw( dirname ); +use OpenOffice::OODoc; + +use parent qw( Exporter ); + +our @EXPORT = qw( + generate_ods +); + +=head1 NAME + +Koha::Util::OpenDocument - utility class to manage filed in Open Document Format aka OpenDocument + +=head1 METHODS + +=head2 generate_ods + +Generate an Open Document Sheet + +Arguments are file path and content as an arrayref of lines containing arrayrefs of cells. + +=cut + + +sub generate_ods { + my ( $filepath, $content ) = @_; + + unless ( $filepath && $content ) { + return; + } + my @input_rows = @$content; + my $nb_rows = scalar @input_rows; + my $nb_cols; + if ($nb_rows) { + $nb_cols= scalar @{ $input_rows[0] }; + } + + # Create document + my $wdir = dirname($filepath); + odfWorkingDirectory($wdir); + my $odf_doc = odfDocument( file => $filepath, create => 'spreadsheet' ); + + if ($nb_rows) { + # Prepare sheet + my $odf_sheet = $odf_doc->expandTable( 0, $nb_rows + 1, $nb_cols ); + my @odf_rows = $odf_doc->getTableRows($odf_sheet); + + # Writing + for ( my $i = 0 ; $i < $nb_rows ; $i++ ) { + for ( my $j = 0 ; $j < $nb_cols ; $j++ ) { + my $cellval = $input_rows[$i][$j]; + $odf_doc->cellValue( $odf_rows[$i], $j, $cellval ); + } + } + } + + # Done + $odf_doc->save(); + + return $odf_doc; +} + +1; +__END__ + +=head1 AUTHOR + +Koha Development Team + +Fridolin Somers + +=cut diff --git a/misc/cronjobs/gather_print_notices.pl b/misc/cronjobs/gather_print_notices.pl index ebd3dd86f5..edbe689997 100755 --- a/misc/cronjobs/gather_print_notices.pl +++ b/misc/cronjobs/gather_print_notices.pl @@ -19,7 +19,6 @@ use Pod::Usage; use Getopt::Long; use C4::Log; -use File::Basename qw( dirname ); use Koha::DateUtils; use MIME::Lite; @@ -181,7 +180,7 @@ sub print_notices { filepath => $filepath, }); } elsif ( $format eq 'ods' ) { - generate_ods ({ + _generate_ods ({ messages => $branch_messages, filepath => $filepath, }); @@ -249,57 +248,36 @@ sub generate_csv { } } -sub generate_ods { +sub _generate_ods { my ( $params ) = @_; my $messages = $params->{messages}; - my $filepath = $params->{filepath}; - - # Create document - use OpenOffice::OODoc; - my $tmpdir = dirname $filepath; - odfWorkingDirectory( $tmpdir ); - my $doc = odfDocument( file => $filepath, create => 'spreadsheet' ); + my $ods_filepath = $params->{filepath}; # Prepare sheet - my @headers; - my @rows; - my $i = 0; + my $ods_content; + my $has_headers; foreach my $message ( @$messages ) { - my @lines = split /\n/, $message->{content}; - chomp for @lines; - - # We don't have headers, get them - unless ( @headers ) { - @headers = split $delimiter, $lines[0]; - my $nb_cols = scalar @headers; - my $nb_rows = scalar @$messages; - my $sheet = $doc->expandTable( 0, $nb_rows + 1, $nb_cols ); - @rows = $doc->getTableRows($sheet); - - # Write headers row - my $row = $rows[0]; - my $j = 0; - for my $header ( @headers ) { - $doc->cellValue( $row, $j, Encode::encode( 'UTF8', $header ) ); - $j++; - } - $i = 1; + my @message_lines = split /\n/, $message->{content}; + chomp for @message_lines; + # Get headers from first message + if ($has_headers) { + shift @message_lines; + } else { + $has_headers = 1; } - - # Write all rows - shift @lines; # remove headers - for my $line ( @lines ) { - my @row_data = split $delimiter, $line; - my $row = $rows[$i]; - # Note scalar(@$row_data) should be equal to $nb_cols - for ( my $j = 0 ; $j < scalar(@row_data) ; $j++ ) { - my $value = Encode::encode( 'UTF8', $row_data[$j] ); - $doc->cellValue( $row, $j, $value ); + foreach my $message_line ( @message_lines ) { + my @content_row; + my @message_cells = split $delimiter, $message_line; + foreach ( @message_cells ) { + push @content_row, Encode::encode( 'UTF8', $_ ); } - $i++; + push @$ods_content, \@content_row; } } - $doc->save(); + + # Process + use Koha::Util::OpenDocument; + generate_ods($ods_filepath, $ods_content); } sub send_files { diff --git a/reports/guided_reports.pl b/reports/guided_reports.pl index 4a6ace361d..00e0805a6e 100755 --- a/reports/guided_reports.pl +++ b/reports/guided_reports.pl @@ -23,7 +23,6 @@ use Text::CSV::Encoded; use Encode qw( decode ); use URI::Escape; use File::Temp; -use File::Basename qw( dirname ); use C4::Reports::Guided; use Koha::Reports; use C4::Auth qw/:DEFAULT get_session/; @@ -922,43 +921,27 @@ elsif ($phase eq 'Export'){ $type = 'application/vnd.oasis.opendocument.spreadsheet'; my $ods_fh = File::Temp->new( UNLINK => 0 ); my $ods_filepath = $ods_fh->filename; - - # Create document - use OpenOffice::OODoc; - my $tmpdir = dirname $ods_filepath; - odfWorkingDirectory( $tmpdir ); - my $doc = odfDocument( file => $ods_filepath, create => 'spreadsheet' ); - - # Prepare sheet - my @headers = header_cell_values( $sth ); - my $rows = $sth->fetchall_arrayref(); - my ( $nb_rows, $nb_cols ) = ( 0, 0 ); - $nb_rows = @$rows; - $nb_cols = @headers; - my $sheet = $doc->expandTable( 0, $nb_rows + 1, $nb_cols ); - my @rows = $doc->getTableRows($sheet); - - # Write headers row - my $row = $rows[0]; - my $j = 0; - for my $header ( @headers ) { - $doc->cellValue( $row, $j, $header ); - $j++; - } - - # Write all rows - my $i = 1; - for ( @$rows ) { - $row = $rows[$i]; - for ( my $j = 0 ; $j < $nb_cols ; $j++ ) { - my $value = Encode::encode( 'UTF8', $rows->[$i - 1][$j] ); - $doc->cellValue( $row, $j, $value ); + my $ods_content; + + # First line is headers + my @headers = header_cell_values($sth); + push @$ods_content, \@headers; + + # Other line in Unicode + my $sql_rows = $sth->fetchall_arrayref(); + foreach my $sql_row ( @$sql_rows ) { + my @content_row; + foreach my $sql_cell ( @$sql_row ) { + push @content_row, Encode::encode( 'UTF8', $sql_cell ); } - $i++; + push @$ods_content, \@content_row; } - # Done - $doc->save(); + # Process + use Koha::Util::OpenDocument; + generate_ods($ods_filepath, $ods_content); + + # Output binmode(STDOUT); open $ods_fh, '<', $ods_filepath; $content .= $_ while <$ods_fh>; -- 2.39.5