Perl tem módulos para ler CSV e escrever XLSX, então você pode fazer isso no lado unix.
Você executaria isso como: perl csv2xlsx.pl file.csv "this is the tab name"
e criaria file.xlsx
que você pode enviar para o cliente.
#!perl
use strict;
use warnings;
use autodie;
use Text::CSV;
use Excel::Writer::XLSX;
# input validation left as an exercise
my $f_csv = shift @ARGV;
(my $f_xlsx = $f_csv) =~ s/\.csv$/.xlsx/;
my $worksheet_name = shift @ARGV;
# read the CSV data
my $csv = Text::CSV->new({binary => 1});
open my $fh, "<:encoding(utf8)", $f_csv;
my @data;
while (my $row = $csv->getline($fh)) {
push @data, $row;
}
$csv->eof or $csv->error_diag();
close $fh;
# write the xlsx
my $workbook = Excel::Writer::XLSX->new($f_xlsx);
my $worksheet = $workbook->add_worksheet($worksheet_name);
for (my $row = 0; $row < scalar @data; $row++) {
$worksheet->write_row($row, 0, $data[$row]);
}
$workbook->close();
Pesquisando um pouco mais o cpan, isso é um pouco mais simples e o arquivo do Excel gerado é mais bonito.
#!perl
use strict;
use warnings;
use autodie;
use Text::CSV;
use Spreadsheet::GenerateXLSX qw/generate_xlsx/;
# input validation left as an exercise
my ($f_csv, $worksheet_name) = @ARGV;
(my $f_xlsx = $f_csv) =~ s/.csv$/.xlsx/;
# read the CSV data
my $csv = Text::CSV->new({binary => 1});
open my $fh, "<:encoding(utf8)", $f_csv;
my $data = $csv->getline_all($fh);
$csv->eof or $csv->error_diag();
close $fh;
# write the xlsx
generate_xlsx($f_xlsx, $worksheet_name => $data);