CallBackery
view release on metacpan or search on metacpan
lib/CallBackery/GuiPlugin/AbstractTable.pm view on Meta::CPAN
size => 100,
},
],
);
Every entry adds one column and takes these keys:
=over
=item type
The kind of column to generate. Only C<qrCode> exists so far. It embeds the
content as a QR code image.
=item content
Where the content comes from: either the key of a field in the table data, or
a code reference which is called with the record hash reference and returns
the string to encode. A record whose content is undefined or empty gets no
image.
=item insertAfter
Optional. The zero based index in L</tableCfg> the new column is placed after.
The indices of all extra columns refer to the original L</tableCfg>, so
several extra columns cannot shift each other around. Without it the column
follows the column named by C<content>, which is therefore mandatory for a
code reference content.
=item label
Optional column heading, translated like any other label. It defaults to the
heading of the column named by C<content>.
=item size
Optional edge length of the image in pixels, 100 by default. The row height
and the column width are adjusted to fit.
=back
C<extraCols> is ignored for a CSV export, which has nowhere to put an image.
A C<qrCode> column needs L<Text::QRCode>, which is loaded on first use so that
installations without QR code exports do not have to carry it.
=cut
sub makeExportAction {
my $self = shift;
my %args = @_;
my $type = $args{type} // 'XLSX';
my $extraCols = $args{extraCols};
my $label = $args{label} // trm("Export %1", $type);
my $filename = $args{filename}
// localtime->strftime('export-%Y-%m-%d-%H-%M-%S.').lc($type);
return {
label => $label,
action => 'download',
addToContextMenu => true,
key => 'export_csv',
actionHandler => sub {
my $self = shift;
my $args = shift;
my $data = $self->getTableData({
formData => $args,
firstRow => 0,
lastRow => $self->getTableRowCount({ formData=>$args })
});
# Use the (translated) table headers in row 1.
# Or the keys if undefined.
my $loc = CallBackery::Translate->new(localeRoot=>$self->app->home->child("share"));
$loc->setLocale($self->user->userInfo->{lang} // 'en');
my $tCfg = $self->tableCfg;
my $tra = sub {
my $label = shift;
return undef unless defined $label;
return ref $label eq 'CallBackery::Translate'
? $loc->tra($label->[0])
: $label;
};
my @titles = map { $tra->($_->{label}) // $_->{key} } @$tCfg;
if ($type eq 'CSV') {
my $csv = Text::CSV->new;
$csv->combine(@titles);
my $csv_str = $csv->string . "\n";
for my $record (@$data) {
$csv->combine(map {
my $v = $record->{$_->{key}};
if ($_->{type} eq 'date') {
$v= localtime($v/1000)->strftime("%Y-%m-%d %H:%M:%S %z");
}
$v} @$tCfg);
$csv_str .= $csv->string . "\n";
}
my $asset = Mojo::Asset::Memory->new;
$asset->add_chunk($csv_str);
return {
asset => $asset,
type => 'text/csv',
filename => $filename,
}
}
elsif ($type eq 'XLSX') {
# a spreadsheet is the only export that can hold images, so
# the extra columns exist here and are ignored for CSV
my $plan = $self->_exportColumnPlan($tCfg, $extraCols);
open my $xh, '>', \my $xlsx or die "failed to open xlsx fh: $!";
my $workbook = Excel::Writer::XLSX->new($xh);
my $worksheet = $workbook->add_worksheet();
my $col = 0;
for my $p (@$plan) {
if (my $tc = $p->{col}) {
$worksheet->write(0, $col, $tra->($tc->{label}) // $tc->{key});
( run in 0.682 second using v1.01-cache-2.11-cpan-8dfa8b56332 )