in reply to Re^7: Making PDF Tables
in thread Making PDF Tables

Hi there if you are still around.
I used your example here to build what I have, it has been a great help. I am having an issue where I need to have two tables side by side and I can not figured it out how to align them, seeing that all the data on this PDF page is dynamic, it can be a few rows of data or it can be several rows o data.
If you run this code I am posting, you can see where the issue is on the tables labeled "TABLE A" and "TABLE B". Everything else works how it should work for me, unless there are better ways to doing what I am trying to do.
It would be relay appreciated if you could look at this code and tell me how I could align tables side by side and dynamic have them still aligned if the data grows or shrink.
Here is the code:

#!/usr/bin/perl use strict; use warnings; use PDF::API2; use PDF::Table; use Data::Dumper; # #A4 Landscape my $width = 842; my $height = 595; my $pdftable = new PDF::Table; my $pdf = new PDF::API2(-file => "tables_side_by_side_test.pdf"); $pdf->mediabox($width, $height); my $font_HB = $pdf->corefont('Helvetica-Bold'); my $font_H = $pdf->corefont("Helvetica"); my $page_num; # Font settings my %font = ( Helvetica => { Bold => $pdf->corefont( 'Helvetica-Bold' +, -encoding => 'utf8' ), Roman => $pdf->corefont( 'Helvetica', + -encoding => 'utf8' ), Italic => $pdf->corefont( 'Helvetica-Obliq +ue', -encoding => 'utf8' ), }, ); my ($principal, $principal_a ,$principal_b) = _get_data(); main_table( $pdf ); $pdf->saveas(); sub main_table { my $got_pdf = shift; my $left_edge_of_table = 50; # 50 my $page = _page(); my ($x,$y) = ($left_edge_of_table,490); my $page_height = 500; # create new page if caption too low if ($y < 100){ $page = _page(); $y = 500; } # add caption for table 1 my $caption = $page->text(); $caption->font($font_HB, 10); $caption->translate($x,$y); #$caption->text("Caption for table 1 \$t"); $caption->text("The First Table"); # create table my $col_numbers_tb1 = 4; my ($nextpage,$new_y) = _table( $pdf, $page, $y, _ob_disc(), $left_ed +ge_of_table, $col_numbers_tb1 ); $page = $nextpage; # gap to next table $y = $new_y - 20; # add caption for table 2 $caption = $page->text(); $caption->font($font_HB, 10); $caption->translate($x,$y); $caption->text("The Second Table"); my $col_numbers_tb2 = 11; my ($nextpage2,$new_y2) = _table( $pdf, $page, $y, _excluded(), $left +_edge_of_table, $col_numbers_tb2 ); $page = $nextpage2; # gap to next table $y = $new_y2 - 20; # add caption for table 3 $caption = $page->text(); $caption->font($font_HB, 10); $caption->translate($x,$y); $caption->text("Block Tables Start"); while (@$principal) { my ($data_princ_acc, $data_princ_a, $data_princ_b) = _send_data_to_p +df(); my $col_numbers_tb3 = 4; my ($nextpage3,$new_y3) = _table( $pdf, $page, $y, $data_princ_acc, +$left_edge_of_table, $col_numbers_tb3 ); $page = $nextpage3; # gap to next table $y = $new_y3 - 20; # I tried setting up here a new value here for this table #my $xy = $y - 19; # add caption for table 4 $caption = $page->text(); $caption->font($font_HB, 10); $caption->translate($x,$y); $caption->text("Table A: + Table B:"); my $col_numbers_tb4 = 3; my ($nextpage4,$new_y4) = _table_a( $pdf, $page, $y, $data_princ_a, +$left_edge_of_table, $col_numbers_tb4 ); $page = $nextpage4; # gap to next table $y = $new_y4 - 20; my $col_numbers_tb5 = 8; my ($nextpage5,$new_y5) = _table_b( $pdf, $page, $y, $data_princ_b, +$left_edge_of_table, $col_numbers_tb5 ); $page = $nextpage5; # gap to next table $y = $new_y5 - 20; } } # create table main sub _table { my ($pdf,$page,$boty,$data,$left_edge,$col_numbers_tb) = @_; my $pdftable = new PDF::Table; my ($next_page, undef, $new_y) = $pdftable->table( $pdf, $page, $data, x => $left_edge, # center main table on the page w => 650, # 495 width of main table on the page start_y => $boty-10, next_y => 500, start_h => $boty-10, next_h => 500, new_page_func => \&_page, # it brings header to other pages padding => 2, padding_right => 10, border => 0, background_color_odd => "#E0E0E0", background_color_even => "#FFFFFF", header_props => { # This param could be a pdf core font or user specified TTF. # See PDF::API2 FONT METHODS for more information font => $pdf->corefont("Helvetica-Bold", -encoding => "utf8" +), font_size => 10, font_color => '#000000', bg_color => '#FFFFFF', repeat => 1, # 1/0 eq On/Off if the header row should be r +epeated to every new page justify => 'center', }, column_props => [ map{ { justify => 'center', font => $font{'Helvetica'}{'Roman'}, font_size => 9, } }1..$col_numbers_tb, ], ); return ($next_page,$new_y); }; sub _table_a { my ($pdf,$page,$boty,$data,$left_edge,$col_numbers_tb) = @_; my $pdftable = new PDF::Table; my ($next_page, undef, $new_y) = $pdftable->table( $pdf, $page, $data, x => $left_edge, # center main table on the page w => 180, # 495 width of main table on the page start_y => $boty-10, next_y => 500, start_h => $boty-10, next_h => 500, new_page_func => \&_page, # it brings header to other pages padding => 2, padding_right => 10, border => 0, background_color_odd => "#E0E0E0", background_color_even => "#FFFFFF", header_props => { # This param could be a pdf core font or user specified TTF. # See PDF::API2 FONT METHODS for more information font => $pdf->corefont("Helvetica-Bold", -encoding => "utf8" +), font_size => 10, font_color => '#000000', bg_color => '#FFFFFF', repeat => 1, # 1/0 eq On/Off if the header row should be r +epeated to every new page justify => 'center', }, column_props => [ map{ { justify => 'center', font => $font{'Helvetica'}{'Roman'}, font_size => 9, } }1..$col_numbers_tb, ], ); return ($next_page,$new_y); }; sub _table_b { my ($pdf,$page,$boty,$data,$left_edge,$col_numbers_tb) = @_; my $pdftable = new PDF::Table; my ($next_page, undef, $new_y) = $pdftable->table( $pdf, $page, $data, x => 260, # center main table on the page w => 440, # 495 width of main table on the page start_y => $boty+10, next_y => 500, start_h => $boty+10, next_h => 500, new_page_func => \&_page, # it brings header to other pages padding => 2, padding_right => 10, border => 0, background_color_odd => "#E0E0E0", background_color_even => "#FFFFFF", header_props => { # This param could be a pdf core font or user specified TTF. # See PDF::API2 FONT METHODS for more information font => $pdf->corefont("Helvetica-Bold", -encoding => "utf8" +), font_size => 10, font_color => '#000000', bg_color => '#FFFFFF', repeat => 1, # 1/0 eq On/Off if the header row should be r +epeated to every new page justify => 'center', }, column_props => [ map{ { justify => 'center', font => $font{'Helvetica'}{'Roman'}, font_size => 9, } }1..$col_numbers_tb, ], ); return ($next_page,$new_y); }; # create new page sub _page { ++$page_num; my $page = $pdf->page; ##add stuff add_title($page); # horiz line my $g = $page->gfx(); $g->linewidth(1); $g->move(20,510); $g->line($width-20,510); $g->stroke; # page num $g->textlabel(760,15,$font_H,8,"Page $page_num", -color => '#808080', -align => 'right', ); return $page; }; sub _ob_disc { my $disc; # This is simulating random rows of data coming from the database $disc = [ ["A Number", "Name", "Date", "Reference"], ["23456", "Aname Another", "01/11/2014", "00007"], ["23456", "jhjhj ssaaa", "01/11/2014", "00007"], ["23456", "Loren asddf", "01/11/2014", "00007"], ["23456", "Serrt jahft", "01/11/2014", "00007"], ["23456", "Ojshfg treiu", "01/11/2014", "00007"], ["23456", "Rssskjj tehrrr", "01/11/2014", "00007"], ["23456", "Maru Smith", "01/11/2014", "00007"], ["23456", "Joe A Smith", "01/11/2014", "00007"], ["23456", "Marck Del", "01/11/2014", "00007"], ["23456", "Gujjnn Theeee", "01/11/2014", "00007"], ["23456", "Mary Lou", "01/11/2014", "00007"], ["23456", "Jackob Joen", "01/11/2014", "00007"], ["23456", "Marcouys De Larent", "01/11/2014", "00007"], ["23456", "Once Uon Time", "01/11/2014", "00007"], ["23456", "Nelson Mkkjhtt", "01/11/2014", "00007"], ]; return $disc }; sub _excluded { my $exc; # This is simulating random rows of data coming from the database push @$exc, ["Acc #", "Date", "Name", "Name #", "Others", "SSW", +"XXXS", "#1", "#2" , "#3","#4",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07 +/2014", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ["12345", "11/01/2014", "consequat quis", "3", "Joe Doe", "03/07/20 +14", "0", "O", "E" , "P","",], ; return $exc; }; sub _send_data_to_pdf { return shift @$principal, shift @$principal_a , shift @$principal_b; }; sub _get_data{ my ($q_principal, $q_principal_b ,$q_principal_c); my $h_principal = ["Acc #", "Name", "OB Date", "Number",],; # This is simulating random rows of data coming from the database $q_principal = [ [ ["12345", "Carl Sea", "03/13/2014", "4",], ], [ ["764539", "Deon gomes", "11/07/2013", "2",], ] ] ; unshift @{$_},$h_principal foreach @{$q_principal}; my $h_principal_v = ["Tie #", "Year", "MOdel",], # This is simulating random rows of data coming from the database $q_principal_b = [ [ ["1", "2000", "OLD",], ["2", "2001", "OLD",], ["3", "2002", "OLD",], ["4", "2003", "OLD",], ["5", "2004", "OLD",], ["6", "2005", "OLD",], ["6", "2011", "NEW",], ], [ ["A", "2000", "OLD",], ["B", "2001", "OLD",], ["C", "2002", "OLD",], ["D", "2003", "OLD",], ["E", "2004", "OLD",], ["F", "2005", "OLD",], ["G", "2011", "NEW",], ], ] ; unshift @{$_},$h_principal_v foreach @{$q_principal_b}; my $header_principal_o = ["NAme #","All", "DXS", "Delst","A #1","B #2" +, "C #3", "D #4",],; # This is simulating random rows of data coming from the database $q_principal_c = [ [ ["1","Stephen King", "5/5/1930", "N","O","P", "-", "-",], ["2","Charles Xing", "6/28/1550", "N","P","O", "-", "-",], ["3","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ["4","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ["5","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ["6","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ["7","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ["8","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ], [ ["A","Maru Louey", "5/5/1950", "N","O","P", "-", "-",], ["B","Gome Thing", "6/28/1950", "N","P","O", "-", "-",], ["C","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ["D","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ["E","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ["F","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ["G","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ["H","Dnieal Cruz", "07/25/1988", "N","O","E", "-", "-",], ], ]; unshift @{$_},$header_principal_o foreach @{$q_principal_c}; return $q_principal, $q_principal_b ,$q_principal_c; } sub add_title { my $page = shift; $page->gfx->textlabel( # PDF::API2 method 416, 566, # x, y $pdf->corefont("Helvetica-Bold"), 11, # font, size "Test Tables PDF", # text -color => '#000000', -align => 'center', ); }

Thanks for the help and looking!

Replies are listed 'Best First'.
Re^9: Making PDF Tables
by poj (Abbot) on Nov 07, 2014 at 13:03 UTC

    Now it's getting complicated !... To align the tables you need to make use of the 2nd argument returned from the table method, the number of pages that the table spans. Use this with some logic to determine which of the 2 tables is the longest and therefore where to start the next pair.

    The difficult bit with table B is deciding if the carry over is onto another page already created by table A or a completely new page. This requires some more logic in the new page function. I have done this by keeping track of the 'target page number' and comparing with the total number of pages in the document. Hopefully this example will give you some ideas.

    poj
Re^9: Making PDF Tables
by Anonymous Monk on Nov 07, 2014 at 18:49 UTC
    This time I guess I am stuck, trying to align these two tables side by side.
        Hi there!
        I thought it was a lost cause, but thanks, with what I have and what you posted I can make this work the way I need it for now. I wish this module would have the capabilities to do colspan, it would be very handy. But, like you mentioned, it can get complicated once you start placing tables side by side, even with all this I still like PERL for it versus JAVA.
        Thanks again!