Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Looping in PDF::Table module

by divinafaudan (Initiate)
on Jul 23, 2013 at 19:35 UTC ( #1045941=perlquestion: print w/replies, xml ) Need Help??
divinafaudan has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am new to perl and i was given a task to create a pdf using pdf::api2 and pdf::table. I am able to create the pdf, however, when i tried to loop tables/rows using foreach (since the data were queried from the database), it gave me syntax error. Does looping tables/rows are possible using the said two modules? Please check my codes below

foreach my $ship_prod (@SHIP_PRODS){ my($_t_id,$p_id,$stat_id,$qty) = split(/$SEP_CHAR/,$sh +ip_prod); $rows = ["", "$ALL_PRODS{$p_id}",""] if(exists($ALL_MAN{$p_id}) && length($ALL_MAN{$p_id}) > 0){ $rows = ["", "$ALL_MAN{$p_id}",""] } # build the table layout $pdftable->table( # required params $pdf,$page, $thirdtable, x => 5, start_y => 470, next_y => 450, start_h => 200, next_h => 250, # some optional params w => 600, padding => 5, padding_right => 10, font_size => 8, ) }

Replies are listed 'Best First'.
Re: Looping in PDF::Table module
by Eliya (Vicar) on Jul 24, 2013 at 03:41 UTC

    If you get a syntax error, it's likely that fixing it will get you a long way... In this case, you're missing a semicolon:

    $rows = ["", "$ALL_PRODS{$p_id}",""]; ^

      Thank you for your response. I miss look the ;. It fixed the error.Thank you so much for pointing it out :)

Re: Looping in PDF::Table module
by rnewsham (Deacon) on Jul 24, 2013 at 07:00 UTC

    As you have provided incomplete code with no example data and no error messages, it is difficult to say where your problem is.

    The documentation for PDF::Table indicates that your data should be in an array.

    It can be used to display text data in a table layout within the PDF. The text data must be in a 2d array (such as returned by a DBI statement handle fetchall_arrayref() call).
    Perhaps if you loop over your data to construct your array then pass that to generate the table in the pdf, it will do what you want.

    Here is a rough example of how your code could be modified, as the code is incomplete this is untested.

    my @tabledata; foreach my $ship_prod (@SHIP_PRODS){ my($_t_id,$p_id,$stat_id,$qty) = split(/$SEP_CHAR/,$ship_prod); $rows = ["", "$ALL_PRODS{$p_id}",""]; if(exists($ALL_MAN{$p_id}) && length($ALL_MAN{$p_id}) > 0){ $rows = ["", "$ALL_MAN{$p_id}",""]; } push @tabledata, $rows; } # build the table layout $pdftable->table( # required params $pdf, $page, \@tabledata, x => 5, start_y => 470, next_y => 450, start_h => 200, next_h => 250, # some optional params w => 600, padding => 5, padding_right => 10, font_size => 8, )

    A few brief pointers on your code:

    • use strict and warnings, I am guessing you are not using these, based on the fact that you do not declare $rows with my in the snippet provided.
    • Indent Indent Indent, whatever scheme for indenting you wish to use is fine as long as it is consistent, this will make your code far easier for you and everyone else to read
    • Variable names, everyone has their own opinion on good variable names however I don't think many people would like $_t_id. Abbreviations can save some time typing but if it hinders readability and understanding you have to ask is it worth it. In your example code $p_id I can guess to be product_id but $stat_id and $_t_id are not obvious, nor is ALL_MAN
    A tip for submitting questions to PerlMonks, break your problem down into a small but complete example that can be executed to see the exact error.

      Hi, Thanks a lot for your advises, i do learn from it. I only got one problem now, how to make a dynamic pdf file. I mean the table height and the start position where the next table will be written by the program because in pdf::table module, i need to specify the x and y coordinates on where should the program start to write the table in pdf.

        The table() method returns 3 values:

        1. PDF::API2::Page object instance that the table ends on
        2. count of pages that the table spans
        3. y position of the table bottom

        With that info (in particular 1 and 3) you can compute where to place the next table.  Sample code:

        #!/usr/bin/perl -w use strict; use PDF::API2; use PDF::Table; my $pdftable = new PDF::Table; my $pdf = new PDF::API2(-file => "test.pdf"); my $page = $pdf->page; # some sample data (3 tables) my @data; for my $t (1..3) { my $table = []; for my $r (1..50) { push @$table, [ map "Table $t : $_$r", 'A'..'E' ]; } push @data, $table; } my $page_height = 700; my $top_y = 750; my $y = $top_y; for my $table (@data) { my ($p_last, undef, $y_bot) = $pdftable->table( $pdf, $page, $table, x => 50, w => 500, start_y => $y, next_y => $top_y, start_h => $page_height - ($top_y-$y), next_h => $page_height, # some optional params padding => 5, padding_right => 10, background_color_odd => "#eee", background_color_even => "#ddd", ); $page = $p_last; $y = $y_bot - 30; # vertical distance between tables if ($y < 50) { # page wrap $page = $pdf->page; $y = $top_y; } } $pdf->saveas();

        The properties x, start_y, next_y, start_h, next_h define the coordinates and size of the table. The start_y and start_h set the table position and height on the first page of the pdf. If there is more data than can be displayed on the first page it will continue on further pages with the y coordinates and height defined by next_y and next_h.

        Here is an example that I extracted from one of my working programs, I have trimmed it down to remove irrelevant code so it is not a complete working example but should give you an idea.

        use PDF::API2; use PDF::Table; my $pdftable = new PDF::Table; my $pdf = new PDF::API2(-file => 'reports/report.pdf'); $pdf->mediabox('A4'); my $page = $pdf->page; # define header properties my $hdr_props = { # This param could be a pdf core font or user specified TTF. # See PDF::API2 FONT METHODS for more information font => $pdf->corefont("Times", -encoding => "utf8"), font_size => 10, font_color => '#555555', bg_color => 'grey', repeat => 1, # 1/0 eq On/Off if the header row should be repea +ted to every new page }; # build the table layout $pdftable->table( # required params $pdf, $page, \@pdf_report_data, # report data in an array of hashes x => 50, w => 495, start_y => 755, # sets the y position of the table on the firs +t page next_y => 775, # sets the y position of tables on subsequent +pages start_h => 730, # sets the height of the table on the first pa +ge next_h => 750, # sets the height of the table on subsequent p +ages # some optional params padding => 5, padding_right => 10, background_color_odd => "white", # cell background colour f +or odd rows background_color_even => "lightgrey", # cell background colour f +or even rows header_props => $hdr_props, # loads the header properties as d +efined above ); # do other stuff with $pdf # save pdf $pdf->saveas();

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1045941]
Approved by erzuuli
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2018-11-17 00:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My code is most likely broken because:
















    Results (200 votes). Check out past polls.

    Notices?
    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!