|
NAMEText::Report - Perl extension for generating mixed columnar formatted reports and report templatesVERSIONVersion 1.003SYNOPSISuse Text::Report; # Let's build a simple report complete with title lines, footer # and two disparate data sets in tabular form # Create a new report object: $rpt = Text::Report->new(debug => 'error', debugv => 1); # Create a title block: $rpt->defblock(name => 'title_lines'); # Create a separator: $rpt->insert('dbl_line'); # Create a data block: $rpt->defblock(name => 'data1', title => 'Statistical Analysis Of Gopher Phlegm Over Time', useColHeaders => 1, sortby => 1, sorttype => 'alpha', orderby => 'ascending', columnWidth => 14, columnAlign => 'left', pad => {top => 2, bottom => 2},); # Create another data block: $rpt->defblock(name => 'data2', title => 'Resultant Amalgamum Firnunciation Per Anum', useColHeaders => 1, sortby => 1, sorttype => 'numeric', orderby => 'ascending', columnWidth => 10, columnAlign => 'right', pad => {top => 2, bottom => 2},); # Create a separator: $rpt->insert('dotted_line'); # Create a footer block: $rpt->defblock(name => 'footer'); # Add column headers: @header = qw(gopher_a gopher_b gopher_c bobs_pudding); @header2 = qw(avg mean meaner meanest outraged paralyzed); $i = 0; for(@header){$rpt->setcol('data1', ++$i, head => $_);} $i = 0; for(@header2){$rpt->setcol('data2', ++$i, head => $_);} # Change column settings for 'bobs_pudding' data: $rpt->setcol('data1', 4, align => 'right', width => 16); @data = ( ['a1', 'a2', 'a3', 'b4'], ['b1', 'b2', 'b3', 'c4'], ['c1', 'c2', 'c3', 'c4'],); @data2 = ( ['562.93', '121.87', '53.95', '46.05', '39.00', '129.00'], ['123.62', '191.25', '14.62', '52.58', '63.14', '256.32'],); # Fill our blocks with some useful data: $rpt->fill_block('title_lines', ['Simple Report'], ['Baltimore Zoological Research Lab']); $rpt->fill_block('data1', @data); $rpt->fill_block('data2', @data2); $rpt->fill_block('footer', ['Acme Cardboard - All Rights Reserved'], ['Apache Junction, Arizona']); # Get our formatted report: @report = $rpt->report('get'); # Print report: for(@report){print $_, "\n";} Simple Report Baltimore Zoological Research Lab ================================================================================ STATISTICAL ANALYSIS OF GOPHER PHLEGM OVER TIME ----------------------------------------------- gopher_a gopher_b gopher_c bobs_pudding ______________ ______________ ______________ ________________ a1 a2 a3 b4 b1 b2 b3 c4 c1 c2 c3 c4 RESULTANT AMALGAMUM FIRNUNCIATION PER ANUM ------------------------------------------ avg mean meaner meanest outraged paralyzed __________ __________ __________ __________ __________ __________ 123.62 191.25 14.62 52.58 63.14 256.32 562.93 121.87 53.95 46.05 39.00 129.00 ................................................................................ Acme Cardboard - All Rights Reserved Apache Junction, Arizona Beautiful isn't it. And the coolest thing... You can save the report template and use it over and over and over... DESCRIPTIONBeing a Practical Reporting language, it only seems fitting that one should be able to generate nicely formatted reports with Perl without ever having to do this stuff (and worse)format = @<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<< @||||||||||| @>>>>> $@###.## $bla, $foo, $blek, $bar, $gnu . over and over again. And clearing accumulators and writing vast amounts of polemic, convoluted code and cursing. And slamming doors and kicking things that bark and meow. And eventually, while sobbing uncontrollably, copying and pasting the stuff into a spreadsheet at 3:30 A.M.. I have seen this. Ugly stuff. Gives me the creeps. Well guess what? This type of aberrant behavior will soon be a thing of the past. You may even tear page 168 out of your (2nd edition) Camel Book now. Sure, go ahead. What, it's not your book? Ahh, do it anyway. Whoever does own it will thank you. Unless it's a library book. Then you've got problems. With Text::Report you can create beautiful text based reports on the fly and even collect csv data for retrieval just in case you still have some primal urge to do the spreadsheet thing. You will never have to touch another perl "format" function ever again. Just initialize a new report object, tweak the global settings to your liking, create page title and footer blocks, some separators, and data blocks (tabular data) to your heart's content. When you're done building you can save the report template to be used later for the same type of report or you can begin stuffing table data into your data blocks. And that's it. You can now print the report or write it to a file. Text::Report will very likely get you so excited that you will mistakenly phone up family members and try to explain it to them. METHODS
The "new" method
creates a new report object instance and defines the attributes of the object.
Attributes are passed as key => value pairs:
The following options let you diddle with the global report defaults. Keep in mind that you may also specify these locally as well which, I find, is easier for most reports. These options are also available using the method $obj->configure().
The "configure" method
is used to tweak global report settings.
(You may also use the following options with new())
The "defblock" method
names and sets parameters for a particular report block such as number of
columns, sort column, default column alignment (which can also be set using
setcol() method), et al.
This is where you create a data block. It will usually be a table structure that you will use to display all of that data you have been collecting from some petri dish in some dark lab somewhere.
The "setblock" method
gives you the opportunity to alter an existing data block's properties with
the exception of the block name.
The "setcol" method
allows you to set and change certain column properties.
The "insert" method
allows you to insert a block to be used as a separator where
$linetype is either 'dotted_line' | 'dbl_line' |
'single_line' | 'under_line' | 'blank_line'.
The "fill_block" method
is where the pudding meets the highway. The data sent, as a 3-dimensional
array or table, is parsed according to the properties that were set when the
block was defined in defblock() or the default properties that were set
at the global or report level.
The "report" method is
how you retrieve the final, formatted report or csv data. The report is
returned as an array where each element is a row or line of the report. The
csv data is returned as an AoA.
MISCELLANEOUS METHODS
The "get_csv" method
returns csv data in an array of arrays.
The "rst_block" method
resets named block to defaults. If $block_name does
not exist, creates new block $block_name and applies
defaults.
The "del_block" method
deletes named block.
The "clr_block_data"
method clears report data & csv data from block
$block_name.
The "clr_block_headers"
method clears header data from block
$block_name.
The "named_blocks"
method returns an array list of all defined named blocks.
No arguments
The "linetypes" method
returns an array list of all predefined line types.
No arguments EXAMPLESExample 1
Generate a report of gas price comparisons on a per zip code basis using Ashish Kasturia's Gas::Prices <http://search.cpan.org/~ashoooo/Gas-Prices-0.0.4/lib/Gas/Prices.pm> use Gas::Prices; use Text::Report; # --- US zip code list my @code = qw(85202 85001 85201); # --- Create our report object my $rpt = Text::Report->new(debug => 'off', width => 95); # --- Define a block for the title area accepting the current # --- default width of 95 chars and centered justification $rpt->defblock(name => 'pageHead'); # --- Add two lines to block 'pageHead' $rpt->fill_block('pageHead', ["Gasoline Pricing At Stations By Zip Code"],[scalar(localtime(int(time)))]); # --- Insert a text decoration # --- We are using the autoindex feature and allowing Text::Report # --- to keep track of the order in which our blocks appear. We determine # --- that order by the order in which we call defblock() or insert() $rpt->insert('dbl_line'); # --- We have data returning for 3 different zip codes and want to present # --- that data as pricing per zip code in one report. Create 3 blocks, # --- using each zip code as part of the block name. The structure will be # --- the same for each block in this case. foreach my $zip(@code) { $rpt->defblock(name => 'station_data'.$zip, column => { 1 => {width => 20, align => 'left', head => 'Station'}, 2 => {width => 35, align => 'left', head => 'Address'}, 3 => {width => 7, align => 'right', head => 'Regular'}, 4 => {width => 7, align => 'right', head => 'Plus'}, 5 => {width => 7, align => 'right', head => 'Premium'}, 6 => {width => 7, align => 'right', head => 'Diesel'}, }, # Block title title => "Station Comparison For Zip Code $zip", # Yes, use column headers useColHeaders => 1, # Yes "sort" using column 1 sortby => 1, # Sort alphabetically sorttype => 'alpha', # Sort low to high orderby => 'ascending', # pad these blocks with 2 blank lines on top and bottom pad => {top => 2, bottom => 2},); } # --- Now that we've constructed the report template, all that's left is to # --- fetch and add the data foreach my $zip(@code) { my $gasprice = Gas::Prices->new($zip); my $stations = $gasprice->get_stations; sleep 3; my @data; foreach my $gas(@{$stations}) { # Remove state & zip (personal preference) $gas->{station_address} =~ s/(.*?)\,\s+\w{2}\s+\d{5}/$1/; push(@data, [ $gas->{station_name}, $gas->{station_address}, $gas->{unleaded_price}, $gas->{plus_price}, $gas->{premium_price}, $gas->{diesel_price}]); } $rpt->fill_block('station_data'.$zip, @data); } # --- Get the formatted report & print to screen my @report = $rpt->report('get'); for(@report){print $_, "\n";} exit(1); Here is the resultant output from example 1: Gasoline Pricing At Stations By Zip Code Mon Jul 9 10:13:33 2007 =============================================================================================== STATION COMPARISON FOR ZIP CODE 85202 ------------------------------------- Station Address Regular Plus Premium Diesel ____________________ ___________________________________ _______ _______ _______ _______ 7-ELEVEN 815 S DOBSON RD, MESA 2.799 N/A N/A N/A 7-ELEVEN 2050 W GUADALUPE RD, MESA 2.799 N/A N/A N/A 7-ELEVEN 1210 W GUADALUPE RD, MESA 2.879 N/A N/A N/A 7-ELEVEN 815 S ALMA SCHOOL RD, MESA 2.819 N/A 3.059 N/A CHEVRON 1205 W BASELINE RD, MESA 2.859 N/A 3.099 2.939 CHEVRON 1808 E BROADWAY RD, TEMPE 2.839 2.969 3.139 N/A CHEVRON 414 W GUADALUPE RD, MESA 2.779 2.919 3.019 N/A CIRCLE K 751 N ARIZONA AVE, GILBERT 2.779 2.979 3.089 2.899 CIRCLE K 2196 E APACHE BLVD, TEMPE 2.799 2.929 N/A N/A CIRCLE K 2012 W SOUTHERN AVE, MESA 2.759 2.889 N/A 2.949 CIRCLE K 2808 S DOBSON RD, MESA 2.779 2.929 3.099 2.899 Circle K 417 S Dobson Rd, Mesa 2.799 2.929 3.099 N/A Circle K 1145 W Main St, Mesa 2.799 2.929 3.099 N/A Circle K 1955 W UNIVERSITY DR, Mesa 2.799 N/A N/A N/A Circle K 735 W Broadway Rd, Mesa 2.819 2.949 3.119 N/A MOBIL 1817 W BASELINE RD, MESA 2.899 N/A N/A N/A Quik Trip 1331 S COUNTRY CLUB DR, Mesa 2.799 2.899 2.999 N/A Quik Trip 2311 W BROADWAY RD, Mesa 2.799 2.899 2.999 N/A SHELL 2180 E BROADWAY RD, TEMPE 2.899 2.999 3.129 2.999 SHELL 2165 E BASELINE RD, TEMPE 2.909 3.009 N/A N/A Shell 1810 S COUNTRY CLUB DR, Mesa 2.799 2.799 2.929 2.849 Shell 1158 W UNIVERSITY DR, Mesa 2.999 3.009 2.879 N/A Shell 2005 W BROADWAY RD, Mesa 2.819 2.799 3.129 2.949 Shell 6349 S MCCLINTOCK DR, Tempe 2.799 2.799 3.119 2.829 Texaco 2816 S COUNTRY CLUB DR, Mesa 2.789 N/A N/A 2.899 UNBRANDED 2997 N ALMA SCHOOL RD, CHANDLER 2.779 N/A N/A N/A Unbranded 1510 S COUNTRY CLUB DR, Mesa 2.809 N/A 2.809 3.049 Unbranded 756 W SOUTHERN AVE, Mesa 2.699 N/A N/A 2.899 Unbranded 1821 S COUNTRY CLUB DR, Mesa 2.829 2.959 2.899 N/A Unbranded 5201 S MCCLINTOCK DR, Tempe 2.789 2.899 2.999 N/A STATION COMPARISON FOR ZIP CODE 85001 ------------------------------------- Station Address Regular Plus Premium Diesel ____________________ ___________________________________ _______ _______ _______ _______ CHEVRON 2402 E WASHINGTON ST, PHOENIX 2.899 N/A 3.139 2.999 CIRCLE K 699 E BUCKEYE RD, PHOENIX 2.839 2.969 N/A N/A CIRCLE K 602 N 1ST AVE, PHOENIX 2.779 2.909 3.079 N/A Circle K 1501 W Mcdowell Rd, Phoenix 2.759 2.909 3.099 2.949 Circle K 309 E Osborn Rd, Phoenix 2.759 2.909 N/A 2.949 Circle K 614 W ROOSEVELT ST, Phoenix 2.759 N/A 3.059 N/A Circle K 702 W Mcdowell Rd, Phoenix 2.779 N/A 3.099 N/A Circle K 10 E BUCKEYE RD, Phoenix 2.819 N/A N/A N/A Circle K 2400 E Mcdowell Rd, Phoenix 2.779 2.949 3.119 N/A Circle K 1602 E Washington St, Phoenix 2.879 3.029 3.199 N/A Circle K 1732 W VAN BUREN ST, Phoenix 2.839 2.969 3.139 N/A Circle K 1342 W THOMAS RD, Phoenix 2.779 N/A N/A N/A Circle K 1945 E Van Buren St, Phoenix 2.879 3.029 3.199 N/A Circle K 1834 W Grant St, Phoenix 2.839 2.969 N/A N/A Circle K 1523 E MCDOWELL RD, Phoenix 2.789 2.759 N/A N/A Circle K 1001 N 16Th St, Phoenix 2.879 3.029 N/A N/A Circle K 2041 W Van Buren St, Phoenix 2.839 2.969 N/A N/A Circle K 1007 N 7Th St, Phoenix 2.879 N/A N/A N/A Circle K 702 E Mcdowell Rd, Phoenix 2.819 2.969 3.119 N/A Circle K 2535 N CENTRAL AVE, Phoenix 2.899 N/A N/A N/A Circle K 966 E Van Buren St, Phoenix 2.859 3.009 N/A N/A Circle K 2850 N 7Th St, Phoenix 2.859 3.029 N/A N/A Phillips 66 1045 N 24TH ST, Phoenix 2.799 N/A N/A 2.899 SHELL 305 E THOMAS RD, PHOENIX 2.899 N/A N/A N/A Shell 922 N 7TH ST, Phoenix 2.879 2.989 N/A N/A Shell 2401 E VAN BUREN ST, Phoenix 2.849 N/A N/A 3.079 UNBRANDED 2817 N 7TH ST, PHOENIX 2.839 N/A N/A N/A UNBRANDED 125 E MCDOWELL RD, PHOENIX 2.819 N/A N/A N/A Unbranded 2045 S 7TH AVE, Phoenix 2.959 2.949 2.989 2.959 Unbranded 1919 S 7TH ST, Phoenix 2.899 N/A N/A 3.299 STATION COMPARISON FOR ZIP CODE 85201 ------------------------------------- Station Address Regular Plus Premium Diesel ____________________ ___________________________________ _______ _______ _______ _______ 7-ELEVEN 815 S ALMA SCHOOL RD, MESA 2.819 N/A 3.059 N/A 7-ELEVEN 815 S DOBSON RD, MESA 2.799 N/A N/A N/A 7-ELEVEN 758 E BROWN RD, MESA 2.859 2.959 N/A N/A ARCO 25 W MCKELLIPS RD, MESA 2.799 N/A N/A N/A CHEVRON 808 E MCKELLIPS RD, MESA 2.869 2.999 3.099 2.939 CIRCLE K 2196 E APACHE BLVD, TEMPE 2.799 2.929 N/A N/A Chevron 357 N Stapley Dr, Mesa 2.839 N/A 3.099 N/A Circle K 735 W Broadway Rd, Mesa 2.819 2.949 3.119 N/A Circle K 11 E Mckellips Rd, Mesa 2.779 N/A N/A N/A Circle K 1550 N Country Club Dr, Mesa 2.779 N/A N/A N/A Circle K 410 N Center St, Mesa 2.779 N/A 3.099 2.849 Circle K 1205 E BROADWAY RD, Mesa 2.799 N/A N/A N/A Circle K 417 S Dobson Rd, Mesa 2.799 2.929 3.099 N/A Circle K 1145 W Main St, Mesa 2.799 2.929 3.099 N/A Circle K 1154 W 8Th St, Mesa 2.799 2.929 3.099 N/A Circle K 1955 W UNIVERSITY DR, Mesa 2.799 N/A N/A N/A Circle K 330 E BROADWAY RD, Mesa 2.799 2.929 N/A N/A Circle K 1160 E UNIVERSITY DR, Mesa 2.879 N/A N/A N/A Circle K 310 N Mesa Dr, Mesa 2.819 N/A N/A N/A Quik Trip 517 W MCKELLIPS RD, Mesa 2.799 2.899 2.999 N/A Quik Trip 1331 S COUNTRY CLUB DR, Mesa 2.799 2.899 2.999 N/A Quik Trip 2311 W BROADWAY RD, Mesa 2.799 2.899 2.999 N/A Quik Trip 816 W UNIVERSITY DR, Mesa 2.799 2.899 2.999 N/A SHELL 1957 N COUNTRY CLUB DR, MESA 2.999 N/A N/A 2.969 SHELL 16 W MCKELLIPS RD, MESA 2.889 2.989 N/A 2.939 Shell 2174 E University Dr, Tempe 2.819 2.779 2.929 2.949 Shell 2005 W BROADWAY RD, Mesa 2.819 2.799 3.129 2.949 Shell 1158 W UNIVERSITY DR, Mesa 2.999 3.009 2.879 N/A Texaco 1601 N BEELINE HWY, Scottsdale 2.899 2.999 3.089 N/A Unbranded 756 W SOUTHERN AVE, Mesa 2.699 N/A N/A 2.899 More examples will be added over time and will be made available at <http://www.full-duplex.com/svcs04.html> somewhere on the page. TODOPage breaks and pagination. I originally developed Text::Report for electronic media and really had no need to introduce the added overhead and complexity of page numbering, order and vertical sizing. I have used Text::Report in a line-printer environment and everything looks great, however paginating for precut paper presents issues. The need to laser print, at least for me and those who I know are using this package, has not yet presented itself.I tell you this only so that you know that I know that Text::Report is lacking a bit in the hardcopy print arena. BUGSNone that I'm aware of at the moment, but as sure as The Sun Also Rises, someone, perhaps soon, will discover what I will call "some new features". Some features may require adjustments. Some features may require removal. I am preparing myself for the inevitable.You may report any bugs or feature requests to "bug-text-report at rt.cpan.org", or through the web interface at <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Text-Report>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. SUPPORTYou can find documentation for this module with the perldoc command.perldoc Text::Report You can also look for information at:
ACKNOWLEDGEMENTSSEE ALSOCPAN - http://search.cpan.org/AUTHORDavid Huggins, (davidius AT cpan DOT org), <http://www.full-duplex.com>, <http://www.in-brandon.com>COPYRIGHT AND LICENSECopyright (C) 2007 by Full-Duplex Communications, Inc. All rights reserved.This program 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 2 of the License, or (at your option) any later version. This program 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. If you need a copy of the GNU General Public License write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Visit the GSP FreeBSD Man Page Interface. |