Revision 84ba8214
Von Moritz Bunkus vor mehr als 16 Jahren hinzugefügt
SL/ReportGenerator.pm | ||
---|---|---|
189 | 189 |
}; |
190 | 190 |
} |
191 | 191 |
|
192 |
sub set_custom_headers { |
|
193 |
my $self = shift; |
|
194 |
|
|
195 |
if (@_) { |
|
196 |
$self->{custom_headers} = [ @_ ]; |
|
197 |
} else { |
|
198 |
delete $self->{custom_headers}; |
|
199 |
} |
|
200 |
} |
|
201 |
|
|
192 | 202 |
sub get_attachment_basename { |
193 | 203 |
my $self = shift; |
194 | 204 |
my $filename = $self->{options}->{attachment_basename} || 'report'; |
... | ... | |
269 | 279 |
push @column_headers, $header; |
270 | 280 |
} |
271 | 281 |
|
282 |
my $header_rows; |
|
283 |
if ($self->{custom_headers}) { |
|
284 |
$header_rows = $self->{custom_headers}; |
|
285 |
} else { |
|
286 |
$header_rows = [ \@column_headers ]; |
|
287 |
} |
|
288 |
|
|
272 | 289 |
my ($outer_idx, $inner_idx) = (0, 0); |
273 | 290 |
my $next_border_top; |
274 | 291 |
my @rows; |
... | ... | |
354 | 371 |
'ALLOW_PDF_EXPORT' => $allow_pdf_export, |
355 | 372 |
'ALLOW_CSV_EXPORT' => $opts->{allow_csv_export}, |
356 | 373 |
'SHOW_EXPORT_BUTTONS' => ($allow_pdf_export || $opts->{allow_csv_export}) && $self->{data_present}, |
357 |
'COLUMN_HEADERS' => \@column_headers,
|
|
374 |
'HEADER_ROWS' => $header_rows,
|
|
358 | 375 |
'NUM_COLUMNS' => scalar @column_headers, |
359 | 376 |
'ROWS' => \@rows, |
360 | 377 |
'EXPORT_VARIABLES' => \@export_variables, |
... | ... | |
390 | 407 |
|
391 | 408 |
my (@data, @column_props, @cell_props); |
392 | 409 |
|
393 |
my $data_row = []; |
|
394 |
my $cell_props_row = []; |
|
410 |
my ($data_row, $cell_props_row); |
|
395 | 411 |
my @visible_columns = $self->get_visible_columns('HTML'); |
412 |
my $num_columns = scalar @visible_columns; |
|
413 |
my $num_header_rows = 1; |
|
396 | 414 |
|
397 | 415 |
foreach $name (@visible_columns) { |
398 |
$column = $self->{columns}->{$name}; |
|
399 |
|
|
400 |
push @{ $data_row }, $column->{text}; |
|
401 |
push @{ $cell_props_row }, {}; |
|
402 |
push @column_props, { 'justify' => $column->{align} eq 'right' ? 'right' : 'left' }; |
|
416 |
push @column_props, { 'justify' => $self->{columns}->{$name}->{align} eq 'right' ? 'right' : 'left' }; |
|
403 | 417 |
} |
404 | 418 |
|
405 |
push @data, $data_row; |
|
406 |
push @cell_props, $cell_props_row; |
|
419 |
if (!$self->{custom_headers}) { |
|
420 |
$data_row = []; |
|
421 |
$cell_props_row = []; |
|
422 |
push @data, $data_row; |
|
423 |
push @cell_props, $cell_props_row; |
|
424 |
|
|
425 |
foreach $name (@visible_columns) { |
|
426 |
$column = $self->{columns}->{$name}; |
|
427 |
|
|
428 |
push @{ $data_row }, $column->{text}; |
|
429 |
push @{ $cell_props_row }, {}; |
|
430 |
} |
|
407 | 431 |
|
408 |
my $num_columns = scalar @column_props; |
|
432 |
} else { |
|
433 |
$num_header_rows = scalar @{ $self->{custom_headers} }; |
|
434 |
|
|
435 |
foreach my $custom_header_row (@{ $self->{custom_headers} }) { |
|
436 |
$data_row = []; |
|
437 |
$cell_props_row = []; |
|
438 |
push @data, $data_row; |
|
439 |
push @cell_props, $cell_props_row; |
|
440 |
|
|
441 |
foreach my $custom_header_col (@{ $custom_header_row }) { |
|
442 |
push @{ $data_row }, $custom_header_col->{text}; |
|
443 |
push @{ $cell_props_row }, {}; |
|
444 |
} |
|
445 |
} |
|
446 |
} |
|
409 | 447 |
|
410 | 448 |
foreach my $row_set (@{ $self->{data} }) { |
411 | 449 |
if ('HASH' eq ref $row_set) { |
... | ... | |
534 | 572 |
'font' => $font, |
535 | 573 |
'font_size' => $font_size, |
536 | 574 |
'font_color' => '#000000', |
575 |
'num_header_rows' => $num_header_rows, |
|
537 | 576 |
'header_props' => { |
538 | 577 |
'bg_color' => '#ffffff', |
539 | 578 |
'repeat' => 1, |
... | ... | |
656 | 695 |
my @visible_columns = $self->get_visible_columns('CSV'); |
657 | 696 |
|
658 | 697 |
if ($opts->{headers}) { |
659 |
$csv->print($stdout, [ map { $self->unescape_string($self->{columns}->{$_}->{text}) } @visible_columns ]); |
|
698 |
if (!$self->{custom_headers}) { |
|
699 |
$csv->print($stdout, [ map { $self->unescape_string($self->{columns}->{$_}->{text}) } @visible_columns ]); |
|
700 |
|
|
701 |
} else { |
|
702 |
foreach my $custom_header_row (@{ $self->{custom_headers} }) { |
|
703 |
$csv->print($stdout, [ map { $self->unescape_string($_->{text}) } @{ $custom_header_row } ]); |
|
704 |
} |
|
705 |
} |
|
660 | 706 |
} |
661 | 707 |
|
662 | 708 |
foreach my $row_set (@{ $self->{data} }) { |
modules/override/PDF/Table.pm | ||
---|---|---|
238 | 238 |
# Table Header Section |
239 | 239 |
#===================================== |
240 | 240 |
# Disable header row into the table |
241 |
my $header_props = 0; |
|
241 |
my $header_props; |
|
242 |
my $num_header_rows = 0; |
|
243 |
my @header_rows; |
|
242 | 244 |
# Check if the user enabled it ? |
243 | 245 |
if (defined $arg{'header_props'} and ref( $arg{'header_props'}) eq 'HASH') { |
244 | 246 |
# Transfer the reference to local variable |
... | ... | |
249 | 251 |
$header_props->{'font_color'} = $header_props->{'font_color'} || '#000066'; |
250 | 252 |
$header_props->{'font_size'} = $header_props->{'font_size'} || $fnt_size + 2; |
251 | 253 |
$header_props->{'bg_color'} = $header_props->{'bg_color'} || '#FFFFAA'; |
254 |
|
|
255 |
$num_header_rows = $arg{'num_header_rows'} || 1; |
|
252 | 256 |
} |
253 |
my $header_row = undef; |
|
254 | 257 |
#===================================== |
255 | 258 |
# Other Parameters check |
256 | 259 |
#===================================== |
... | ... | |
276 | 279 |
my $pg_cnt = 1; |
277 | 280 |
my $cur_y = $ybase; |
278 | 281 |
my $cell_props = $arg{cell_props} || []; # per cell properties |
279 |
my $row_cnt = ( ref $header_props and $header_props->{'repeat'} ) ? 1 : 0; # current row in user data
|
|
282 |
my $row_cnt = $num_header_rows;
|
|
280 | 283 |
|
281 | 284 |
#If there is valid data array reference use it! |
282 | 285 |
if (ref $data eq 'ARRAY') { |
283 | 286 |
# Copy the header row if header is enabled |
284 |
@$header_row = $$data[0] if defined $header_props; |
|
287 |
if (defined $header_props) { |
|
288 |
map { push @header_rows, $$data[$_] } (0..$num_header_rows - 1); |
|
289 |
} |
|
285 | 290 |
# Determine column widths based on content |
286 | 291 |
|
287 | 292 |
# an arrayref whose values are a hashref holding |
... | ... | |
292 | 297 |
# the actual widths of the column/row intersection |
293 | 298 |
my $row_props = []; |
294 | 299 |
# An array ref with the widths of the header row |
295 |
my $header_row_props = [];
|
|
300 |
my @header_row_props;
|
|
296 | 301 |
|
297 | 302 |
# Scalars that hold sum of the maximum and minimum widths of all columns |
298 | 303 |
my ( $max_col_w, $min_col_w ) = ( 0,0 ); |
... | ... | |
301 | 306 |
# Hash that will hold the width of every word from input text |
302 | 307 |
my $word_w = {}; |
303 | 308 |
my $rows_counter = 0; |
304 |
my $first_row = 1; |
|
305 | 309 |
|
306 | 310 |
foreach $row ( @{$data} ) { |
311 |
push(@header_row_props, []) if ($rows_counter < $num_header_rows); |
|
312 |
|
|
307 | 313 |
my $column_widths = []; #holds the width of each column |
308 | 314 |
for( my $j = 0; $j < scalar(@$row) ; $j++ ) { |
309 | 315 |
# look for font information for this column |
... | ... | |
360 | 366 |
}#End of for(my $j.... |
361 | 367 |
$row_props->[$rows_counter] = $column_widths; |
362 | 368 |
# Copy the calculated row properties of header row. |
363 |
@$header_row_props = @$column_widths if (!$rows_counter and ref $header_props); |
|
369 |
if (($rows_counter < $num_header_rows) && $header_props) { |
|
370 |
push(@header_row_props, [ @{ $column_widths } ]); |
|
371 |
} |
|
364 | 372 |
$rows_counter++; |
365 | 373 |
} |
374 |
$main::lxdebug->dump(0, "hrp", \@header_row_props); |
|
366 | 375 |
# Calc real column widths and expand table width if needed. |
367 | 376 |
my $calc_column_widths; |
368 | 377 |
($calc_column_widths, $width) = $self->CalcColumnWidths( $col_props, $width ); |
... | ... | |
373 | 382 |
my ( $gfx , $gfx_bg , $background_color , $font_color, ); |
374 | 383 |
my ( $bot_marg, $table_top_y, $text_start , $record, $record_widths ); |
375 | 384 |
|
385 |
my $remaining_header_rows = $header_props ? $num_header_rows : 0; |
|
386 |
|
|
376 | 387 |
# Each iteration adds a new page as neccessary |
377 | 388 |
while(scalar(@{$data})) { |
378 | 389 |
my $page_header; |
... | ... | |
392 | 403 |
$bot_marg = $table_top_y - $next_h; |
393 | 404 |
|
394 | 405 |
if ( ref $header_props and $header_props->{'repeat'}) { |
395 |
# Copy Header Data |
|
396 |
@$page_header = @$header_row; |
|
397 |
my $hrp ; |
|
398 |
@$hrp = @$header_row_props ; |
|
399 |
# Then prepend it to master data array |
|
400 |
unshift @$data ,@$page_header ; |
|
401 |
unshift @$row_props ,$hrp ; |
|
402 |
$first_row = 1; # Means YES |
|
406 |
foreach my $idx (0 .. $num_header_rows - 1) { |
|
407 |
unshift @$data, [ @{ $header_rows[$idx] } ]; |
|
408 |
unshift @$row_props, [ @{ $header_row_props[$idx] } ]; |
|
409 |
} |
|
410 |
$remaining_header_rows = $num_header_rows; |
|
403 | 411 |
} |
404 | 412 |
} |
405 | 413 |
|
... | ... | |
438 | 446 |
$background_color = $rows_counter % 2 ? $background_color_even : $background_color_odd; |
439 | 447 |
$font_color = $rows_counter % 2 ? $font_color_even : $font_color_odd; |
440 | 448 |
|
441 |
if ($first_row and ref $header_props) {
|
|
449 |
if ($remaining_header_rows and ref $header_props) {
|
|
442 | 450 |
$background_color = $header_props->{'bg_color'} |
443 | 451 |
} |
444 | 452 |
$text_start = $cur_y - $fnt_size - $pad_top; |
... | ... | |
455 | 463 |
$leftovers->[$j] = undef; |
456 | 464 |
|
457 | 465 |
# Choose font color |
458 |
if ( $first_row and ref $header_props ) {
|
|
466 |
if ( $remaining_header_rows and ref $header_props ) {
|
|
459 | 467 |
$txt->fillcolor( $header_props->{'font_color'} ); |
460 | 468 |
|
461 | 469 |
} elsif ( $cell_props->[$row_cnt][$j]{font_color} ) { |
... | ... | |
469 | 477 |
} |
470 | 478 |
|
471 | 479 |
# Choose font size |
472 |
if ( $first_row and ref $header_props ) {
|
|
480 |
if ( $remaining_header_rows and ref $header_props ) {
|
|
473 | 481 |
$col_fnt_size = $header_props->{'font_size'}; |
474 | 482 |
|
475 | 483 |
} elsif ( $col_props->[$j]->{'font_size'} ) { |
... | ... | |
480 | 488 |
} |
481 | 489 |
|
482 | 490 |
# Choose font family |
483 |
if ( $first_row and ref $header_props ) {
|
|
491 |
if ( $remaining_header_rows and ref $header_props ) {
|
|
484 | 492 |
$txt->font( $header_props->{'font'}, $header_props->{'font_size'}); |
485 | 493 |
|
486 | 494 |
} elsif ( $col_props->[$j]->{'font'} ) { |
... | ... | |
493 | 501 |
$col_props->[$j]->{justify} = $col_props->[$j]->{justify} || 'left'; |
494 | 502 |
|
495 | 503 |
my $this_width; |
496 |
if (!$first_row && $cell_props->[$row_cnt]->[$j]->{colspan}) {
|
|
504 |
if (!$remaining_header_rows && $cell_props->[$row_cnt]->[$j]->{colspan}) {
|
|
497 | 505 |
$colspan = -1 == $cell_props->[$row_cnt]->[$j]->{colspan} ? $num_cols - $j : $cell_props->[$row_cnt]->[$j]->{colspan}; |
498 | 506 |
my $last_idx = $j + $colspan - 1; |
499 | 507 |
$this_width = sum @{ $calc_column_widths }[$j..$last_idx]; |
... | ... | |
550 | 558 |
$col_props->[$j]->{'background_color'} || |
551 | 559 |
$background_color ) { |
552 | 560 |
$gfx_bg->rect( $cur_x, $cur_y-$row_h, $calc_column_widths->[$j], $row_h); |
553 |
if ( $cell_props->[$row_cnt][$j]->{'background_color'} && !$first_row ) {
|
|
561 |
if ( $cell_props->[$row_cnt][$j]->{'background_color'} && !$remaining_header_rows ) {
|
|
554 | 562 |
$gfx_bg->fillcolor($cell_props->[$row_cnt][$j]->{'background_color'}); |
555 | 563 |
|
556 |
} elsif ( $col_props->[$j]->{'background_color'} && !$first_row ) {
|
|
564 |
} elsif ( $col_props->[$j]->{'background_color'} && !$remaining_header_rows ) {
|
|
557 | 565 |
$gfx_bg->fillcolor($col_props->[$j]->{'background_color'}); |
558 | 566 |
|
559 | 567 |
} else { |
... | ... | |
576 | 584 |
$gfx->move( $xbase , $cur_y ); |
577 | 585 |
$gfx->hline( $xbase + $width ); |
578 | 586 |
$rows_counter++; |
579 |
$row_cnt++ unless ( $first_row ); |
|
580 |
$first_row = 0; |
|
587 |
if ($remaining_header_rows) { |
|
588 |
$remaining_header_rows--; |
|
589 |
} else { |
|
590 |
$row_cnt++; |
|
591 |
} |
|
581 | 592 |
}# End of while(scalar(@{$data}) and $cur_y-$row_h > $bot_marg) |
582 | 593 |
|
583 | 594 |
# Draw vertical lines |
templates/webpages/report_generator/html_report_de.html | ||
---|---|---|
38 | 38 |
[% IF DATA_PRESENT %] |
39 | 39 |
<p> |
40 | 40 |
<table width="100%"> |
41 |
[%- FOREACH row = HEADER_ROWS %] |
|
41 | 42 |
<tr> |
42 |
[% FOREACH col = COLUMN_HEADERS %]
|
|
43 |
[% FOREACH col = row %]
|
|
43 | 44 |
<th class="listheading">[% IF col.link %]<a href="[% col.link %]">[% END %][% col.text %][% IF col.link %][% IF col.show_sort_indicator %]<img border="0" src="image/[% IF col.sort_indicator_direction %]down[% ELSE %]up[% END %].png">[% END %]</a>[% ELSE %][% IF col.show_sort_indicator %]<img src="image/[% IF col.sort_indicator_direction %]down[% ELSE %]up[% END %].png">[% END %][% END %]</th> |
44 | 45 |
[% END %] |
45 | 46 |
</tr> |
47 |
[%- END %] |
|
46 | 48 |
|
47 | 49 |
[% FOREACH row = ROWS %] |
48 | 50 |
[% IF row.IS_CONTROL %] |
templates/webpages/report_generator/html_report_master.html | ||
---|---|---|
38 | 38 |
[% IF DATA_PRESENT %] |
39 | 39 |
<p> |
40 | 40 |
<table width="100%"> |
41 |
[%- FOREACH row = HEADER_ROWS %] |
|
41 | 42 |
<tr> |
42 |
[% FOREACH col = COLUMN_HEADERS %]
|
|
43 |
[% FOREACH col = row %]
|
|
43 | 44 |
<th class="listheading">[% IF col.link %]<a href="[% col.link %]">[% END %][% col.text %][% IF col.link %][% IF col.show_sort_indicator %]<img border="0" src="image/[% IF col.sort_indicator_direction %]down[% ELSE %]up[% END %].png">[% END %]</a>[% ELSE %][% IF col.show_sort_indicator %]<img src="image/[% IF col.sort_indicator_direction %]down[% ELSE %]up[% END %].png">[% END %][% END %]</th> |
44 | 45 |
[% END %] |
45 | 46 |
</tr> |
47 |
[%- END %] |
|
46 | 48 |
|
47 | 49 |
[% FOREACH row = ROWS %] |
48 | 50 |
[% IF row.IS_CONTROL %] |
Auch abrufbar als: Unified diff
ReportGenerator: Unterstützung für mehrzeilige und individuell festgelegte Tabellenköpfe/Spaltenüberschriften implementiert.