@@ -, +, @@ --- ...bug_27510_download_report_html_format.perl | 8 ++ installer/data/mysql/mandatory/sysprefs.sql | 3 +- .../prog/en/includes/reports-toolbar.inc | 1 + .../admin/preferences/staff_interface.pref | 7 +- reports/guided_reports.pl | 94 +++++++++++++++++++ 5 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_27510_download_report_html_format.perl --- a/installer/data/mysql/atomicupdate/bug_27510_download_report_html_format.perl +++ a/installer/data/mysql/atomicupdate/bug_27510_download_report_html_format.perl @@ -0,0 +1,8 @@ +$DBversion = 'XXX'; # will be replaced by the RM +if( CheckVersion( $DBversion ) ) { + # you can use $dbh here like: + $dbh->do(q{INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) VALUES ('ReportUserCSS','',NULL,'','free')}); + + # Always end with this (adjust the bug info) + NewVersion( $DBversion, 27510, "Download the report in HTML format"); +} --- a/installer/data/mysql/mandatory/sysprefs.sql +++ a/installer/data/mysql/mandatory/sysprefs.sql @@ -791,5 +791,6 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('XSLTListsDisplay','default','','Enable XSLT stylesheet control over lists pages display on intranet','Free'), ('XSLTResultsDisplay','default','','Enable XSL stylesheet control over results page display on intranet','Free'), ('z3950AuthorAuthFields','701,702,700',NULL,'Define the MARC biblio fields for Personal Name Authorities to fill biblio.author','free'), -('z3950NormalizeAuthor','0','','If ON, Personal Name Authorities will replace authors in biblio.author','YesNo') +('z3950NormalizeAuthor','0','','If ON, Personal Name Authorities will replace authors in biblio.author','YesNo'), +('ReportUserCSS','',NULL,'Add CSS to be included on the report in HTML format.','free') ; --- a/koha-tmpl/intranet-tmpl/prog/en/includes/reports-toolbar.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/reports-toolbar.inc @@ -117,6 +117,7 @@
  • [% PROCESS 'delimiter_text.inc' %]
  • Tab separated text
  • Open Document Spreadsheet
  • +
  • Document HTML
  • [% IF (results.json) %]
  • Chart (.svg)
  • [% END %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_interface.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/staff_interface.pref @@ -199,7 +199,6 @@ Staff interface: 1: Show 0: "Don't show" - a search field pulldown for 'Search the catalog' boxes. - Authentication: - - pref: staffShibOnly choices: @@ -213,3 +212,9 @@ Staff interface: "enabled": Enable "disabled": "Don't enable" - two-factor authentication (2FA) for staff members. + - + - "Include the following CSS on the report in HTML format:" + - pref: ReportUserCSS + type: textarea + syntax: css + class: code --- a/reports/guided_reports.pl +++ a/reports/guided_reports.pl @@ -38,6 +38,8 @@ use Koha::Patron::Categories; use Koha::SharedContent; use Koha::Util::OpenDocument qw( generate_ods ); use C4::ClassSource qw( GetClassSources ); +use HTML::Table; +use utf8; =head1 NAME @@ -958,6 +960,10 @@ elsif ($phase eq 'Export'){ $content .= $_ while <$ods_fh>; unlink $ods_filepath; } + elsif ( $format eq 'html' ) { + $type = 'text/html'; + $content = _to_html($sth, $input); + } } print $input->header( -type => $type, @@ -1094,3 +1100,91 @@ sub create_non_existing_group_and_subgroup { } } +# pass $sth and sql_params, get back an executable query +sub get_prepped_report { + my ($sql, $param_names, $sql_params ) = @_; + + # First we split out the placeholders + # This part of the code supports using [[ table.field | alias ]] in the + # query and replaces it by table.field AS alias. Not sure why we would + # need it if we can type the latter (which is simpler)? + my @split = split /\[\[|\]\]/,$sql; + my $headers; + for(my $i=0;$i<$#split/2;$i++){ #The placeholders are always the odd elements of the array + my ($type,$name) = split /\|/,$split[$i*2+1]; # We split them on '|' + $headers->{$name} = $type; # Store as a lookup for the template + $headers->{$name} =~ s/^\w*\.//; # strip the table name just as in $sth->{NAME} array + $split[$i*2+1] =~ s/(\||\?|\.|\*|\(|\)|\%)/\\$1/g; #Quote any special characters so we can replace the placeholders + $name = C4::Context->dbh->quote($name); + $sql =~ s/\[\[$split[$i*2+1]\]\]/$type AS $name/; # Remove placeholders from SQL + } + + my %lookup; + @lookup{@$param_names} = @$sql_params; + @split = split /<<|>>/,$sql; + my @tmpl_parameters; + for(my $i=0;$i<$#split/2;$i++) { + my $quoted = @$param_names ? $lookup{ $split[$i*2+1] } : @$sql_params[$i]; + # if there are special regexp chars, we must \ them + $split[$i*2+1] =~ s/(\||\?|\.|\*|\(|\)|\%)/\\$1/g; + if ($split[$i*2+1] =~ /\|\s*date\s*$/) { + $quoted = output_pref({ dt => dt_from_string($quoted), dateformat => 'iso', dateonly => 1 }) if $quoted; + } + $quoted = C4::Context->dbh->quote($quoted); + $sql =~ s/<<$split[$i*2+1]>>/$quoted/; + } + return $sql,$headers; +} + +sub _to_html { + my ($sth, $input) = @_; + my $header_type = "application/x-download"; + my $rep_name = Encode::encode_utf8($input->param('reportname')); + my $file = $rep_name . ".html"; + my $html_start = + " + + + + + $rep_name - Koha"; + my $html_end = + "\n + \n"; + my $h1 = "\n

    " . $rep_name . "

    "; + my @head = header_cell_values($sth); + my $con = join(" ", @head); + my $cols = scalar @head; + + my $css = C4::Context->preference('ReportUserCSS'); + if ($css eq ''){ + $css = + "\ntable, th, td { + border: 1px solid black; + } + table { + border-collapse: collapse; + }"; + } + my $content = $html_start; + $content .= + "\n" . + "\n + \n"; + my $table = HTML::Table->new( + -cols => $cols, + ); + $table->addSectionRow('thead', 0, @head); + $table->setSectionRCellsHead('thead', 0, 1); + my ($tmp_str, @tmp_arr); + while (my $row = $sth->fetchrow_arrayref()) { + $tmp_str = join ('*replace*', @$row); + $tmp_str = Encode::encode_utf8($tmp_str); + @tmp_arr = split (/\*replace\*/, $tmp_str); + $table->addSectionRow( 'tbody', 0, @tmp_arr); + } + $content .= $h1 . $table . $html_end; + return $content; +} --