1Data::Report(3)       User Contributed Perl Documentation      Data::Report(3)
2
3
4

NAME

6       Data::Report - Framework for flexible reporting
7

SYNOPSIS

9         use Data::Report;
10
11         # Create a new reporter.
12         my $rep = Data::Report::->create(type => "text"); # or "html", or "csv", ...
13
14         # Define the layout.
15         $rep->set_layout
16           ([ { name => "acct", title => "Acct",        width => 6  },
17              { name => "desc", title => "Description", width => 40, align => "<" },
18              { name => "deb",  title => "Debet",       width => 10, align => ">" },
19              { name => "crd",  title => "Credit",      width => 10, align => ">" },
20            ]);
21
22         # Start the reporter.
23         $rep->start;
24
25         # Add data, row by row.
26         $rep->add({ acct => 1234, desc => "Received", deb => "242.33"                  });
27         $rep->add({ acct => 5678, desc => "Paid",                      crd => "699.45" });
28         $rep->add({ acct => 1259, desc => "Taxes",    deb =>  "12.00", crd => "244.00" });
29         $rep->add({               desc => "TOTAL",    deb => "254.33", crd => "943.45" });
30
31         # Finish the reporter.
32         $rep->finish;
33

DESCRIPTION

35       Data::Report is a flexible, plugin-driven reporting framework. It makes
36       it easy to define reports that can be produced in text, HTML and CSV.
37       Textual ornaments like extra empty lines, dashed lines, and cell lines
38       can be added in a way similar to HTML style sheets.
39
40       The Data::Report framework consists of three parts:
41
42       The plugins
43           Plugins implement a specific type of report. Standard plugins
44           provided are "Data::Report::Plugin::Text" for textual reports,
45           "Data::Report::Plugin::Html" for HTML reports, and
46           "Data::Report::Plugin::Csv" for CSV (comma-separated) files.
47
48           Users can, and are encouraged, to develop their own plugins to
49           handle different styles and types of reports.
50
51       The base class
52           The base class "Data::Report::Base" implements the functionality
53           common to all reporters, plus a number of utility functions the
54           plugins can use.
55
56       The factory
57           The actual "Data::Report" module is a factory that creates a
58           reporter for a given report type by selecting the appropriate
59           plugin and returning an instance thereof.
60

BASIC METHODS

62       Note that except for the "create" method, all other methods are
63       actually handled by the plugins and their base class.
64
65   create
66       Reporter objects are created using the class method "create". This
67       method takes a hash (or hashref) of arguments to initialise the
68       reporter object.
69
70       The actual reporter object is implemented by one of the plugin modules,
71       selected by the "type" argument. Standard plugins are provided for
72       "text", "HTML" and "CSV" report types. The default type is "text".
73
74       When looking for a plugin to support report type "foo", the "create"
75       method will first try to load a module "My::Package::Foo" where
76       "My::Package" is the invocant class. If this module cannot be loaded,
77       it will fall back to "Data::Report::Plugin::Foo". Note that, unless
78       subclassed, the current class will be "Data::Report".
79
80       All other initialisation arguments correspond to attribute setting
81       methods provided by the plugins. For example, the hypothetical call
82
83         my $rpt = Data::Report->create(foo => 1, bar => "Hello!");
84
85       is identical to:
86
87         my $rpt = Data::Report->create;
88         $rpt->set_foo(1);
89         $rpt->set_bar("Hello!");
90
91       You can choose any combination at your convenience.
92
93   start
94       This method indicates that all setup has been completed, and starts the
95       reporter. Note that no output is generated until the "add" method is
96       called.
97
98       "start" takes no arguments.
99
100       Although this method could be eliminated by automatically starting the
101       reporter upon the first call to "add", it turns out that an aplicit
102       "start" makes the API much cleaner and makes it easier to catch
103       mistakes.
104
105   add
106       This method adds a new entry to the report. It takes one single
107       argument, a hash ref of column names and the corresponding values.
108       Missing columns are left blank.
109
110       In addition to the column names and values, you can add the special key
111       "_style" to designate a particular style for this entry. What that
112       means depends on the plugin that implements this reporter. For example,
113       the standard HTML reporter plugin prefixes the given style with "r_" to
114       form the class name for the row.  The style name should be a simple
115       name, containing letters, digits and underscores, starting with a
116       letter.
117
118       Example
119
120         $rpt->add({ date   => "2006-04-31",
121                     amount => 1000,
122                     descr  => "First payment",
123                     _style => "plain" });
124
125   finish
126       This method indicates that report generation is complete. After this,
127       you can call "start" again to initiate a new report.
128
129       "finish" takes no arguments.
130
131   close
132       This is a convenience method. If the output stream was set up by the
133       reporter itself (see "set_output", below), the stream will be closed.
134       Otherwise, this method will be a no-op.
135
136       "close" takes no arguments.
137

ATTRIBUTE HANDLING METHODS

139   get_type
140       The reporter type.
141
142   set_layout
143       This is the most important attribute, since it effectively defines the
144       report layout.
145
146       This method takes one argument, an array reference. Each element of the
147       array is a hash reference that corresponds to one column in the report.
148       The order of elements definines the order of the columns in the report,
149       but see "set_fields" below.
150
151       The following keys are possible in the hash reference:
152
153       "name"
154           The name of this column. The name should be a simple name,
155           containing letters, digits and underscores, starting with a letter.
156
157           The standard HTML reporter plugin uses the column name to form a
158           class name for each cell by prefixing with "c_". Likewise, the
159           classes for the table headings will be formed by prefixing the
160           column names with "h_". See "ADVANCED EXAMPLES", below.
161
162       "title"
163           The title of this column. This title is placed in the column
164           heading.
165
166       "width"
167           The width of this column.  Relevant for textual reporters only.
168
169           By default, if a value does not fit in the given width, it will be
170           spread over multiple rows in a pseudo-elegant way. See also the
171           "truncate" key, below.
172
173       "align"
174           The alignment of this column. This can be either "<" for left-
175           aligned columns, or ">" to indicate a right-aligned column.
176
177       "truncate"
178           If true, the values in this column will be truncated to fit the
179           width of the column.  Relevant for textual reporters only.
180
181   set_style
182       This method can be used to set an arbitrary style (a string) whose
183       meaning depends on the implementing plugin. For example, a HTML plugin
184       could use this as the name of the style sheet to use.
185
186       The name should be a simple name, containing letters, digits and
187       underscores, starting with a letter.
188
189   get_style
190       Returns the style, or "default" if none.
191
192   set_output
193       Designates the destination for the report. The argument can be
194
195       a SCALAR reference
196           All output will be appended to the designated scalar.
197
198       an ARRAY reference
199           All output lines will be pushed onto the array.
200
201       a SCALAR
202           A file will be created with the given name, and all output will be
203           written to this file. To close the file, use the "close" method
204           described above.
205
206       anything else
207           Anything else will be considered to be a file handle, and treated
208           as such.
209
210   set_stylist
211       The stylist is a powerful method to control the appearance of the
212       report at the row and cell level. The basic idea is taken from HTML
213       style sheets. By using a stylist, it is possible to add extra spaces
214       and lines to rows and cells in a declarative way.
215
216       When used, the stylist should be a reference to a possibly anonymous
217       subroutine with three arguments: the reporter object, the style of a
218       row (as specified with "_style" in the "add" method), and the name of a
219       column as defined in the layout. For table headings, the row name
220       "_head" is used.
221
222       The stylist routine will be repeatedly called by the reporter to obtain
223       formatting properties for rows and cells. It should return either
224       nothing, or a hash reference with properties.
225
226       When called with only the "row" argument, it should return the
227       properties for this row.
228
229       When called with row equal to "*" and a column name, it should return
230       the properties for the given column.
231
232       When called with a row and a column name, it should return the
233       properties for the given row/column (cell).
234
235       All appropriate properties are merged to form the final set of
236       properties to apply.
237
238       The following row properties are recognised. Between parentheses the
239       backends that support them.
240
241       "skip_before"
242           (Text) Produce an empty line before printing the current row.
243
244       "skip_after"
245           (Text) Produce an empty line after printing the current row, but
246           only if other data follows.
247
248       "line_before"
249           (Text) Draw a line of dashes before printing the current row.
250
251       "line_after"
252           (Text) Draw a line of dashes after printing the current row.
253
254       "cancel_skip"
255           (Text) Cancel the effect of a pending "skip_after"
256
257       "ignore"
258           (All) Ignore this row. Useful for CSV backends where only the raw
259           data matters, and not the totals and such.
260
261       The following cell properties are recognised. Between parentheses the
262       backends that support them.
263
264       "indent"
265           (Text) Indent the contents of this cell with the given amount.
266
267       "wrap_indent"
268           (Text) Indent wrapped contents of this cell with the given amount.
269
270       "truncate"
271           (Text) If true, truncate the contents of this cell to fit the
272           column width.
273
274       "line_before"
275           (Text) Draw a line in the cell before printing the current row. The
276           value of this property indicates the symbol to use to draw the
277           line. If it is 1, dashes are used.
278
279       "line_after"
280           (Text) Draw a line in the cell after printing the current row. The
281           value of this property indicates the symbol to use to draw the
282           line. If it is 1, dashes are used.
283
284       "raw_html"
285           (Html) Do not escape special HTML characters, allowing pre-prepared
286           HTML code to be placed in the output. Use with care.
287
288       "ignore"
289           (All) Ignore this column. Note that to prevent surprising results,
290           the column must be ignored in all applicable styles, including the
291           special style "_head" that controls the heading.
292
293       "class"
294           (Html) Class name to be used for this cell. Default class name is
295           "h_CNAME" for table headings and "c_CNAME" for table rows, where
296           CNAME is the name of the column.
297
298       Example:
299
300         $rep->set_stylist(sub {
301           my ($rep, $row, $col) = @_;
302
303           unless ( $col ) {
304               return { line_after => 1 } if $row eq "total";
305               return;
306           }
307           return { line_after => 1 } if $col eq "amount";
308           return;
309         });
310
311       Each reporter provides a standard (dummy) stylist called
312       "_std_stylist". Overriding this method is equivalent to using
313       "set_stylist".
314
315   get_stylist
316       Returns the current stylist, if any.
317
318   set_topheading
319       Headings consist of two parts, the top heading, and the standard
320       heading. Bij default, the top heading is empty, and the standard
321       heading has the names of the columns with a separator line (depnendent
322       on the plugin used).
323
324       This method can be used to designate a subroutine that will provide the
325       top heading of the report.
326
327       Example:
328
329         $rpt->set_topheading(sub {
330           my $self = shift;
331           $self->_print("Title line 1\n");
332           $self->_print("Title line 2\n");
333           $self->_print("\n");
334         });
335
336       Note the use of the reporter provided "_print" method to produce
337       output.
338
339       When subclassing a reporter, a method "_top_heading" can be defined to
340       provide the top heading. This is equivalent to an explicit call to
341       "set_topheading", but doesn't need to be repeatedly and explicitly
342       executed for each new reporter.
343
344   get_topheading
345       Returns the current top heading routine, if any.
346
347   set_heading
348       This method can be used to designate a subroutine that provides the
349       standard heading of the report.
350
351       In normal cases using this method is not necessary, since setting the
352       top heading will be sufficient.
353
354       Each reporter plugin provides a standard heading, implemented in a
355       method called "_std_header". This is the default value for the
356       "heading" attribute. A user-defined heading can use
357
358         $self->SUPER::_std_header;
359
360       to still get the original standard heading produced.
361
362       Example:
363
364         $rpt->set_heading(sub {
365           my $self = shift;
366           $self->_print("Title line 1\n");
367           $self->_print("Title line 2\n");
368           $self->_print("\n");
369           $self->SUPER::_std_heading;
370           $self->_print("\n");
371         });
372
373       Note the use of the reporter provided "_print" method to produce
374       output.
375
376       When subclassing a reporter, the method "_std_heading" can be
377       overridden to provide a customized top heading. This is equivalent to
378       an explicit call to "set_topheading", but doesn't need to be repeatedly
379       and explicitly executed for each new reporter.
380
381   get_heading
382       Returns the current standard heading routine, if any.
383
384   set_fields
385       This method can be used to define what columns (fields) should be
386       included in the report and the order they should appear. It takes an
387       array reference with the names of the desired columns.
388
389       Example:
390
391         $rpt->set_fields([qw(descr amount date)]);
392
393   get_fields
394       Returns the current set of selected columns.
395
396   set_width
397       This method defines the width for one or more columns. It takes a hash
398       reference with column names and widths. The width may be an absolute
399       number, a relative number (to increase/decrease the width, or a
400       percentage.
401
402       Example:
403
404         $rpt->set_width({ amount => 10, desc => '80%' });
405
406   get_widths
407       Returns a hash with all column names and widths.
408

ADVANCED EXAMPLES

410       This example subclasses Data::Report with an associated plugin for type
411       "text". Note the use of overriding "_top_heading" and "_std_stylist" to
412       provide special defaults for this reporter.
413
414         package POC::Report;
415
416         use base qw(Data::Report);
417
418         package POC::Report::Text;
419
420         use base qw(Data::Report::Plugin::Text);
421
422         sub _top_heading {
423             my $self = shift;
424             $self->_print("Title line 1\n");
425             $self->_print("Title line 2\n");
426             $self->_print("\n");
427         }
428
429         sub _std_stylist {
430             my ($rep, $row, $col) = @_;
431
432             if ( $col ) {
433                 return { line_after => "=" }
434                   if $row eq "special" && $col =~ /^(deb|crd)$/;
435             }
436             else {
437                 return { line_after => 1 } if $row eq "total";
438             }
439             return;
440         }
441
442       It can be used as follows:
443
444         my $rep = POC::Report::->create(type => "text");
445
446         $rep->set_layout
447           ([ { name => "acct", title => "Acct",   width => 6  },
448              { name => "desc", title => "Report", width => 40, align => "<" },
449              { name => "deb",  title => "Debet",  width => 10, align => "<" },
450              { name => "crd",  title => "Credit", width => 10, align => ">" },
451            ]);
452
453         $rep->start;
454
455         $rep->add({ acct => "one", desc => "two", deb => "three", crd => "four", _style => "normal" });
456         $rep->add({ acct => "one", desc => "two", deb => "three", crd => "four", _style => "normal" });
457         $rep->add({ acct => "one", desc => "two", deb => "three", crd => "four", _style => "special"});
458         $rep->add({ acct => "one", desc => "two", deb => "three", crd => "four", _style => "total"  });
459
460         $rep->finish;
461
462       The output will look like:
463
464         Title line 1
465         Title line 2
466
467         Acct                                      Report  Debet           Credit
468         ------------------------------------------------------------------------
469         one                                          two  three             four
470         one                                          two  three             four
471         one                                          two  three             four
472                                                           ==========  ==========
473         one                                          two  three             four
474         ------------------------------------------------------------------------
475
476       This is a similar example for a HTML reporter:
477
478         package POC::Report;
479
480         use base qw(Data::Report);
481
482         package POC::Report::Html;
483
484         use base qw(Data::Report::Plugin::Html);
485
486         sub start {
487             my $self = shift;
488             $self->{_title1} = shift;
489             $self->{_title2} = shift;
490             $self->{_title3} = shift;
491             $self->SUPER::start;
492         }
493
494         sub _top_heading {
495             my $self = shift;
496             $self->_print("<html>\n",
497                           "<head>\n",
498                           "<title>", $self->_html($self->{_title1}), "</title>\n",
499                           '<link rel="stylesheet" href="css/', $self->get_style, '.css">', "\n",
500                           "</head>\n",
501                           "<body>\n",
502                           "<p class=\"title\">", $self->_html($self->{_title1}), "</p>\n",
503                           "<p class=\"subtitle\">", $self->_html($self->{_title2}), "<br>\n",
504                           $self->_html($self->{_title3}), "</p>\n");
505         }
506
507         sub finish {
508             my $self = shift;
509             $self->SUPER::finish;
510             $self->_print("</body>\n</html>\n");
511         }
512
513       Note that it defines an alternative "start" method, that is used to
514       pass in additional parameters for title fields.
515
516       The method "_html" is a convenience method provided by the framework.
517       It returns its argument with sensitive characters escaped by HTML
518       entities.
519
520       It can be used as follows:
521
522         package main;
523
524         my $rep = POC::Report::->create(type => "html");
525
526         $rep->set_layout
527           ([ { name => "acct", title => "Acct",   width => 6  },
528              { name => "desc", title => "Report", width => 40, align => "<" },
529              { name => "deb",  title => "Debet",  width => 10, align => "<" },
530              { name => "crd",  title => "Credit", width => 10, align => ">" },
531            ]);
532
533         $rep->start(qw(Title_One Title_Two Title_Three_Left&Right));
534
535         $rep->add({ acct => "one", desc => "two", deb => "three", crd => "four", _style => "normal" });
536         $rep->add({ acct => "one", desc => "two", deb => "three", crd => "four", _style => "normal" });
537         $rep->add({ acct => "one", desc => "two", deb => "three", crd => "four", _style => "normal" });
538         $rep->add({ acct => "one", desc => "two", deb => "three", crd => "four", _style => "total"  });
539
540         $rep->finish;
541
542       The output will look like this:
543
544         <html>
545         <head>
546         <title>Title_One</title>
547         <link rel="stylesheet" href="css/default.css">
548         </head>
549         <body>
550         <p class="title">Title_One</p>
551         <p class="subtitle">Title_Two<br>
552         Title_Three_Left&amp;Right</p>
553         <table class="main">
554         <tr class="head">
555         <th align="left" class="h_acct">Acct</th>
556         <th align="left" class="h_desc">Report</th>
557         <th align="right" class="h_deb">Debet</th>
558         <th align="right" class="h_crd">Credit</th>
559         </tr>
560         <tr class="r_normal">
561         <td align="left" class="c_acct">one</td>
562         <td align="left" class="c_desc">two</td>
563         <td align="right" class="c_deb">three</td>
564         <td align="right" class="c_crd">four</td>
565         </tr>
566         <tr class="r_normal">
567         <td align="left" class="c_acct">one</td>
568         <td align="left" class="c_desc">two</td>
569         <td align="right" class="c_deb">three</td>
570         <td align="right" class="c_crd">four</td>
571         </tr>
572         <tr class="r_normal">
573         <td align="left" class="c_acct">one</td>
574         <td align="left" class="c_desc">two</td>
575         <td align="right" class="c_deb">three</td>
576         <td align="right" class="c_crd">four</td>
577         </tr>
578         <tr class="r_total">
579         <td align="left" class="c_acct">one</td>
580         <td align="left" class="c_desc">two</td>
581         <td align="right" class="c_deb">three</td>
582         <td align="right" class="c_crd">four</td>
583         </tr>
584         </table>
585         </body>
586         </html>
587
588       See also the examples in "t/09poc*.t".
589

AUTHOR

591       Johan Vromans, "<jvromans at squirrel.nl>"
592

BUGS

594       Disclaimer: This module is derived from actual working code, that I
595       turned into a generic CPAN module. During the process, some features
596       may have become unstable, but that will be cured in time. Also, it is
597       possible that revisions of the API will be necessary when new
598       functionality is added.
599
600       Please report any bugs or feature requests to "bug-data-report at
601       rt.cpan.org", or through the web interface at
602       <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Data-Report>.  I will
603       be notified, and then you'll automatically be notified of progress on
604       your bug as I make changes.
605

SUPPORT

607       Development of this module takes place on GitHub:
608       <https://github.com/sciurius/perl-Data-Report>.
609
610       After installing, you can find documentation for this module with the
611       perldoc command.
612
613           perldoc Data::Report
614
615       Please report any bugs or feature requests using the issue tracker on
616       GitHub.
617

ACKNOWLEDGEMENTS

620       Copyright 2006,2008,2020 Squirrel Consultancy, all rights reserved.
621
622       This program is free software; you can redistribute it and/or modify it
623       under the same terms as Perl itself.
624
625
626
627perl v5.34.0                      2022-01-21                   Data::Report(3)
Impressum