Formats, sprintf and Report Generation

21.1 printf / sprintf

%s %d %f %e %g String, integer, float, scientific, general %x %X %o %b Hex, hex uppercase, octal, binary %5s / %-5s / %05d Width, left-justify, zero-pad %.2f / %.3s Precision / maximum string length

Version string (sprintf '%vd', '1.22.333')

printf "%-20s %8s %10s\n", 'Item', 'Qty', 'Price';
printf "%-20s %8d %10.2f\n", $_->{name}, $_->{qty}, $_->{price} for @items;
my $s = sprintf '%05d|%x|%o|%b|%e|%s|%%|%*d', 42, 255, 8, 5, 12345.678, 'str', 6, 7;
my $padded = sprintf '%-*s|', 10, 'left';     # width from an argument
my $comma = reverse join ',', unpack '(A3)*', reverse 1234567;   # "1,234,567"

21.2 Perl Formats (Legacy Report Writer)

Formats are a historical feature (the "R" in Perl). For modern reports, use printf, Text::Table, Text::ASCIITable, Text::CSV, Template Toolkit, or spreadsheet modules (Excel::Writer::XLSX).

our ($name, $qty, $price);
format STDOUT_TOP =
Name                 Qty     Price
-------------------- ----- --------
.
format STDOUT =
@<<<<<<<<<<<<<<<<<<< @>>>> @###.##
$name,               $qty, $price
.
for my $item (@items) {
    ($name, $qty, $price) = @$item{qw(name qty price)};
    write;
}

21.3 Templating

use Template;     # Template Toolkit (CPAN)
my $tt = Template->new;
$tt->process(\"Hello [% name %]! [% FOREACH i IN items %][% i %] [% END %]\n",
             { name => 'Ana', items => [1, 2, 3] }) or die $tt->error;
# Also: Text::Template, Mojo::Template, Text::Xslate (fast), HTML::Template