Spreadsheet-Read
view release on metacpan or search on metacpan
* Tested with perl-5.40
* xlscat --no-empty to skip empty columns too
* Spreadsheet::ParseExcel::FmtDefault might not be available
0.90 - 13 Feb 2024, H.Merijn Brand
* Consistent return value for parses ($type) on failure (issue#52)
* New options for xlscat (--no-empty, --clip=N)
* Support for hidden sheets
0.89 - 02 Jan 2024, H.Merijn Brand
* Auto-use BOM in CSV *files* with xlscat script
* Fix duplicate option letter (typo) (Erix)
* It's 2024
0.88 - 07 Nov 2023, H.Merijn Brand
* Guard $_ globbering from external bitrotted code
* Use recommended and suggested versions based on known CVEs
* Improve user feedback on failing xlsx2csv & xlscat
* Fix static docs for groff-1.24
* Basic support for Excel::ValueReader::XLSX (issue#50)
* Allow backend for parser option without version check
scripts/xlscat view on Meta::CPAN
use Data::Dumper;
use Spreadsheet::Read;
use Getopt::Long qw(:config bundling noignorecase passthrough);
my $opt_c; # Generate CSV
my $opt_F = ""; # Fields to print
my $opt_v = 0; # Verbosity for xlscat
my $opt_d = 0; # Debug level for Spreadsheet::Read
my $opt_h = 0; # Number of header lines for grep or -L
my $opt_D = 0; # Dump: 0 = none, 1 = array, 2 = hash
my $clip = 1;
my $enc_bom; # CSV input encoding derived from BOM
my $enc_i; # Input encoding
my $enc_o; # Output encoding
GetOptions (
"help|?" => sub { usage (0); },
"V|version" => sub { print "$CMD [$VERSION] Spreadsheet::Read [$Spreadsheet::Read::VERSION]\n"; exit 0; },
"list" => sub { list_parsers (); },
# Input CSV
"c|csv" => sub { $opt_c = "," },
"m|ms" => sub { $opt_c = ";" },
scripts/xlscat view on Meta::CPAN
$opt_i and $pattern = "(?i:$pattern)";
$pattern = qr{$pattern};
$opt_v > 1 and warn "Matching on $pattern\n";
}
my $file = shift;
if (defined $file and $file ne "-") {
$opt_v > 1 and warn "Using $file as input\n";
-f $file or usage 1, "the file argument is not a regular file";
-s $file or usage 1, "the file is empty";
if ($file =~ m/\.csv$/i and open my $fh, "<", $file) { # Auto-BOM
my $l = <$fh>;
close $fh;
if ($l =~ s/^\x00\x00\xfe\xff//) { $enc_bom = "utf-32be" }
elsif ($l =~ s/^\xff\xfe\x00\x00//) { $enc_bom = "utf-32le" }
elsif ($l =~ s/^\xfe\xff//) { $enc_bom = "utf-16be" }
elsif ($l =~ s/^\xff\xfe//) { $enc_bom = "utf-16le" }
elsif ($l =~ s/^\xef\xbb\xbf//) { $enc_bom = "utf-8" }
elsif ($l =~ s/^\xf7\x64\x4c//) { $enc_bom = "utf-1" }
elsif ($l =~ s/^\xdd\x73\x66\x73//) { $enc_bom = "utf-ebcdic" }
elsif ($l =~ s/^\x0e\xfe\xff//) { $enc_bom = "scsu" }
elsif ($l =~ s/^\xfb\xee\x28//) { $enc_bom = "bocu-1" }
elsif ($l =~ s/^\x84\x31\x95\x33//) { $enc_bom = "gb-18030" }
elsif ($l =~ s/^\x{feff}//) { $enc_bom = "" }
if ($enc_bom and open $fh, "<:encoding($enc_bom)", $file) {
$opt_v > 1 and warn "Opened $file with encoding $enc_bom after BOM detection\n";
read $fh, (my $bom), 1; # Skip BOM
$file = $fh;
push @RDarg, parser => "CSV";
}
}
}
else {
$opt_v > 1 and warn "Working as a pipe\n";
$file = *ARGV;
}
scripts/xlscat view on Meta::CPAN
if ($clip_len) {
$_ = substr $_, 0, $clip_len - 1 for grep { length > $clip_len } $uval, $fval;
}
$opt_v > 2 and warn "$_:$r '$uval' / '$fval'\n";
$opt_A and
push @att, [ @{$s->{attr}[$_][$r]}{qw( fgcolor bgcolor bold uline halign )} ];
$opt_f && $s->{attr}[$_][$r]{formula}
? "=".$s->{attr}[$_][$r]{formula}
: defined $s->{cell}[$_][$r] ? $opt_u ? $uval : $fval : "";
} $c[0] .. $c[1];
$r == 1 && $row[0] && defined $enc_bom and $row[0] =~ s/^\N{BOM}//;
exists $print{col} and @row = @row[grep{$_<@row}@{$print{col}}];
$is_grep && $r > $opt_h &&
! first { defined $_ && $_ =~ $pattern } @row and next;
$skip_empty && ! first { length } @row and next;
if ($opt_first) {
@row >= $opt_first && $first{$row[$opt_first - 1]}++ and next;
}
if ($opt_D) {
ddumper ($opt_D == 1 ? \@row :
{ map { $s->{cell}[$_ + 1][1] => $row[$_] } 0 .. $#row });
( run in 0.681 second using v1.01-cache-2.11-cpan-131fc08a04b )