Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package perl-Text-CSV_XS for openSUSE:Factory checked in at 2023-02-01 16:38:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Text-CSV_XS (Old) and /work/SRC/openSUSE:Factory/.perl-Text-CSV_XS.new.32243 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Text-CSV_XS" Wed Feb 1 16:38:40 2023 rev:48 rq:1062238 version:1.49 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Text-CSV_XS/perl-Text-CSV_XS.changes 2022-06-03 14:16:44.613322505 +0200 +++ /work/SRC/openSUSE:Factory/.perl-Text-CSV_XS.new.32243/perl-Text-CSV_XS.changes 2023-02-01 16:50:32.477545136 +0100 @@ -1,0 +2,12 @@ +Wed Jan 4 03:11:49 UTC 2023 - Tina Müller <timueller+p...@suse.de> + +- updated to 1.49 + see /usr/share/doc/packages/perl-Text-CSV_XS/ChangeLog + + 1.49 - 2023-01-03, H.Merijn Brand + * csv2xlsx --split=CxP [--split-label=C] + * Full documentation/manual for csv2xlsx + * Fix non-integer arguments to getline_all (issue 39) + * It's 2023 + +------------------------------------------------------------------- Old: ---- Text-CSV_XS-1.48.tgz New: ---- Text-CSV_XS-1.49.tgz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Text-CSV_XS.spec ++++++ --- /var/tmp/diff_new_pack.HkGGdn/_old 2023-02-01 16:50:32.865547435 +0100 +++ /var/tmp/diff_new_pack.HkGGdn/_new 2023-02-01 16:50:32.869547459 +0100 @@ -1,7 +1,7 @@ # # spec file for package perl-Text-CSV_XS # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %define cpan_name Text-CSV_XS Name: perl-Text-CSV_XS -Version: 1.48 +Version: 1.49 Release: 0 License: Artistic-1.0 OR GPL-1.0-or-later Summary: Comma-Separated Values manipulation routines @@ -27,7 +27,7 @@ Source1: cpanspec.yml BuildRequires: perl BuildRequires: perl-macros -Recommends: perl(Encode) >= 3.17 +Recommends: perl(Encode) >= 3.19 %{perl_requires} %description ++++++ Text-CSV_XS-1.48.tgz -> Text-CSV_XS-1.49.tgz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/CSV_XS.pm new/Text-CSV_XS-1.49/CSV_XS.pm --- old/Text-CSV_XS-1.48/CSV_XS.pm 2022-05-22 21:51:39.000000000 +0200 +++ new/Text-CSV_XS-1.49/CSV_XS.pm 2023-01-03 13:19:18.000000000 +0100 @@ -1,6 +1,6 @@ package Text::CSV_XS; -# Copyright (c) 2007-2022 H.Merijn Brand. All rights reserved. +# Copyright (c) 2007-2023 H.Merijn Brand. All rights reserved. # Copyright (c) 1998-2001 Jochen Wiedmann. All rights reserved. # Copyright (c) 1997 Alan Citterman. All rights reserved. # @@ -26,7 +26,7 @@ use Carp; use vars qw( $VERSION @ISA @EXPORT_OK %EXPORT_TAGS ); -$VERSION = "1.48"; +$VERSION = "1.49"; @ISA = qw( Exporter ); XSLoader::load ("Text::CSV_XS", $VERSION); @@ -2608,7 +2608,8 @@ This will return a reference to a list of L<getline ($fh)|/getline> results. In this call, C<keep_meta_info> is disabled. If C<$offset> is negative, as with C<splice>, only the last C<abs ($offset)> records of C<$fh> are taken -into consideration. +into consideration. Parameters C<$offset> and C<$length> are expected to be +an integers. Non-integer values are interpreted as integer without check. Given a CSV file with 10 lines: @@ -5033,7 +5034,7 @@ =head1 COPYRIGHT AND LICENSE - Copyright (C) 2007-2022 H.Merijn Brand. All rights reserved. + Copyright (C) 2007-2023 H.Merijn Brand. All rights reserved. Copyright (C) 1998-2001 Jochen Wiedmann. All rights reserved. Copyright (C) 1997 Alan Citterman. All rights reserved. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/CSV_XS.xs new/Text-CSV_XS-1.49/CSV_XS.xs --- old/Text-CSV_XS-1.48/CSV_XS.xs 2022-03-08 17:13:58.000000000 +0100 +++ new/Text-CSV_XS-1.49/CSV_XS.xs 2023-01-03 13:19:07.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (c) 2007-2022 H.Merijn Brand. All rights reserved. +/* Copyright (c) 2007-2023 H.Merijn Brand. All rights reserved. * Copyright (c) 1998-2001 Jochen Wiedmann. All rights reserved. * This program is free software; you can redistribute it and/or * modify it under the same terms as Perl itself. @@ -2195,14 +2195,14 @@ SetupCsv (&csv, hv, self); - if (SvIOK (off)) { + if (SvOK (off)) { skip = SvIV (off); if (skip < 0) { tail = -skip; skip = -1; } } - if (SvIOK (len)) + if (SvOK (len)) length = SvIV (len); while (c_xsParse (csv, hv, row, NULL, io, 1)) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/ChangeLog new/Text-CSV_XS-1.49/ChangeLog --- old/Text-CSV_XS-1.48/ChangeLog 2022-05-24 10:05:08.000000000 +0200 +++ new/Text-CSV_XS-1.49/ChangeLog 2023-01-03 13:19:48.000000000 +0100 @@ -1,3 +1,9 @@ +1.49 - 2023-01-03, H.Merijn Brand + * csv2xlsx --split=CxP [--split-label=C] + * Full documentation/manual for csv2xlsx + * Fix non-integer arguments to getline_all (issue 39) + * It's 2023 + 1.48 - 2022-05-24, H.Merijn Brand * It's 2022 * Update to Devel::PPPort-3.64 @@ -909,5 +915,5 @@ * Moved encoding and decoding to XS; added binary mode; added print () and getline () methods. -1998-06-05 Alan Citterman <a...@mfgrtl.com> +0.01 - 1998-06-05 Alan Citterman <a...@mfgrtl.com> * Initial version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/META.json new/Text-CSV_XS-1.49/META.json --- old/Text-CSV_XS-1.48/META.json 2022-05-24 13:30:00.000000000 +0200 +++ new/Text-CSV_XS-1.49/META.json 2023-01-03 14:38:07.000000000 +0100 @@ -1,28 +1,38 @@ { + "resources" : { + "homepage" : "https://metacpan.org/pod/Text::CSV_XS", + "x_IRC" : "irc://irc.perl.org/#csv", + "bugtracker" : { + "web" : "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Text-CSV_XS" + }, + "license" : [ + "http://dev.perl.org/licenses/" + ], + "repository" : { + "web" : "https://github.com/Tux/Text-CSV_XS", + "url" : "https://github.com/Tux/Text-CSV_XS", + "type" : "git" + } + }, + "meta-spec" : { + "version" : 2, + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" + }, + "abstract" : "Comma-Separated Values manipulation routines", "generated_by" : "Author", - "dynamic_config" : 1, - "license" : [ - "perl_5" + "author" : [ + "H.Merijn Brand <h.m.br...@xs4all.nl>" ], + "name" : "Text-CSV_XS", "prereqs" : { - "configure" : { - "requires" : { - "ExtUtils::MakeMaker" : "0" - } - }, - "runtime" : { - "recommends" : { - "Encode" : "3.17" - }, + "build" : { "requires" : { - "XSLoader" : "0", - "perl" : "5.006001", - "IO::Handle" : "0" + "Config" : "0" } }, - "build" : { + "configure" : { "requires" : { - "Config" : "0" + "ExtUtils::MakeMaker" : "0" } }, "test" : { @@ -30,38 +40,28 @@ "Tie::Scalar" : "0", "Test::More" : "0" } - } - }, - "author" : [ - "H.Merijn Brand <h.m.br...@xs4all.nl>" - ], - "version" : "1.48", - "meta-spec" : { - "version" : 2, - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec" - }, - "name" : "Text-CSV_XS", - "abstract" : "Comma-Separated Values manipulation routines", - "resources" : { - "homepage" : "https://metacpan.org/pod/Text::CSV_XS", - "x_IRC" : "irc://irc.perl.org/#csv", - "repository" : { - "type" : "git", - "web" : "https://github.com/Tux/Text-CSV_XS", - "url" : "https://github.com/Tux/Text-CSV_XS" }, - "license" : [ - "http://dev.perl.org/licenses/" - ], - "bugtracker" : { - "web" : "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Text-CSV_XS" + "runtime" : { + "requires" : { + "perl" : "5.006001", + "IO::Handle" : "0", + "XSLoader" : "0" + }, + "recommends" : { + "Encode" : "3.19" + } } }, + "dynamic_config" : 1, "release_status" : "stable", + "license" : [ + "perl_5" + ], "provides" : { "Text::CSV_XS" : { - "version" : "1.48", + "version" : "1.49", "file" : "CSV_XS.pm" } - } + }, + "version" : "1.49" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/META.yml new/Text-CSV_XS-1.49/META.yml --- old/Text-CSV_XS-1.48/META.yml 2022-05-24 13:30:00.000000000 +0200 +++ new/Text-CSV_XS-1.49/META.yml 2023-01-03 14:38:07.000000000 +0100 @@ -16,9 +16,9 @@ provides: Text::CSV_XS: file: CSV_XS.pm - version: '1.48' + version: '1.49' recommends: - Encode: '3.17' + Encode: '3.19' requires: IO::Handle: 0 Test::More: 0 @@ -31,4 +31,4 @@ homepage: https://metacpan.org/pod/Text::CSV_XS license: http://dev.perl.org/licenses/ repository: https://github.com/Tux/Text-CSV_XS -version: '1.48' +version: '1.49' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/Makefile.PL new/Text-CSV_XS-1.49/Makefile.PL --- old/Text-CSV_XS-1.48/Makefile.PL 2022-01-01 12:42:47.000000000 +0100 +++ new/Text-CSV_XS-1.49/Makefile.PL 2023-01-03 13:18:53.000000000 +0100 @@ -1,6 +1,6 @@ #!/usr/bin/perl -# Copyright PROCURA B.V. (c) 2006-2022 H.Merijn Brand +# Copyright PROCURA B.V. (c) 2006-2023 H.Merijn Brand require 5.006001; # <- also see postamble at the bottom for META.yml use strict; @@ -160,7 +160,8 @@ 'test_used: test', ' prove -vwb sandbox/used-by.pl', '', - 'doc docs: doc/CSV_XS.md doc/CSV_XS.html doc/CSV_XS.man', + 'doc docs: doc/CSV_XS.md doc/CSV_XS.html doc/CSV_XS.man \\', + ' doc/csv2xlsx.md doc/csv2xlsx.html doc/csv2xlsx.man', 'doc/CSV_XS.md: CSV_XS.pm', ' pod2markdown < $? > $@', 'doc/CSV_XS.html: CSV_XS.pm', @@ -169,6 +170,14 @@ ' pod2man < $? > $@', 'doc/CSV_XS.man: doc/CSV_XS.3', ' nroff -mandoc < $? > $@', + 'doc/csv2xlsx.md: examples/csv2xlsx', + ' pod2markdown < $? > $@', + 'doc/csv2xlsx.html: examples/csv2xlsx', + ' pod2html < $? 2>&1 | grep -v "^Cannot find" > $@', + 'doc/csv2xlsx.3: examples/csv2xlsx', + ' pod2man < $? > $@', + 'doc/csv2xlsx.man: doc/csv2xlsx.3', + ' nroff -mandoc < $? > $@', '', $min_vsn; } # postamble diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/README new/Text-CSV_XS-1.49/README --- old/Text-CSV_XS-1.48/README 2022-01-01 12:43:41.000000000 +0100 +++ new/Text-CSV_XS-1.49/README 2023-01-03 13:19:01.000000000 +0100 @@ -19,7 +19,7 @@ That process is described in the documentation. Copying: - Copyright (c) 2007-2022 H.Merijn Brand. All rights reserved. + Copyright (c) 2007-2023 H.Merijn Brand. All rights reserved. Copyright (c) 1998-2001 Jochen Wiedmann. All rights reserved. Portions Copyright (c) 1997 Alan Citterman. All rights reserved. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/cpanfile new/Text-CSV_XS-1.49/cpanfile --- old/Text-CSV_XS-1.48/cpanfile 2022-05-24 13:30:00.000000000 +0200 +++ new/Text-CSV_XS-1.49/cpanfile 2023-01-03 14:38:07.000000000 +0100 @@ -1,7 +1,7 @@ requires "IO::Handle"; requires "XSLoader"; -recommends "Encode" => "3.17"; +recommends "Encode" => "3.19"; on "configure" => sub { requires "ExtUtils::MakeMaker"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/err-csv/check.pl new/Text-CSV_XS-1.49/err-csv/check.pl --- old/Text-CSV_XS-1.48/err-csv/check.pl 2021-02-10 11:31:04.000000000 +0100 +++ new/Text-CSV_XS-1.49/err-csv/check.pl 2023-01-03 13:43:11.000000000 +0100 @@ -1,6 +1,6 @@ #!/pro/bin/perl -use 5.14.2; +use 5.014002; use warnings; our $VERSION = "0.01 - 20200130"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/examples/csv-check new/Text-CSV_XS-1.49/examples/csv-check --- old/Text-CSV_XS-1.48/examples/csv-check 2022-01-01 12:37:17.000000000 +0100 +++ new/Text-CSV_XS-1.49/examples/csv-check 2023-01-03 13:36:46.000000000 +0100 @@ -1,11 +1,11 @@ #!/pro/bin/perl # csv-check: Check validity of CSV file and report -# (m)'20 [21 May 2020] Copyright H.M.Brand 2007-2022 +# (m)'20 [21 May 2020] Copyright H.M.Brand 2007-2023 # This code requires the defined-or feature and PerlIO -use 5.12.0; +use 5.012000; use warnings; use Data::Peek; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/examples/csv-split new/Text-CSV_XS-1.49/examples/csv-split --- old/Text-CSV_XS-1.48/examples/csv-split 2021-02-10 11:31:04.000000000 +0100 +++ new/Text-CSV_XS-1.49/examples/csv-split 2023-01-03 13:36:56.000000000 +0100 @@ -1,6 +1,6 @@ #!/pro/bin/perl -use 5.14.0; +use 5.014000; use warnings; our $VERSION = "0.01 - 20201021"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/examples/csv2xls new/Text-CSV_XS-1.49/examples/csv2xls --- old/Text-CSV_XS-1.48/examples/csv2xls 2022-01-01 12:37:19.000000000 +0100 +++ new/Text-CSV_XS-1.49/examples/csv2xls 2023-01-03 13:37:08.000000000 +0100 @@ -1,9 +1,9 @@ #!/pro/bin/perl # csv2xls: Convert csv to xls -# (m)'20 [25 Mar 2020] Copyright H.M.Brand 2007-2022 +# (m)'20 [25 Mar 2020] Copyright H.M.Brand 2007-2023 -use 5.12.0; +use 5.012000; use warnings; our $VERSION = "1.80"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/examples/csv2xlsx new/Text-CSV_XS-1.49/examples/csv2xlsx --- old/Text-CSV_XS-1.48/examples/csv2xlsx 2022-01-01 12:37:21.000000000 +0100 +++ new/Text-CSV_XS-1.49/examples/csv2xlsx 2023-01-03 13:17:37.000000000 +0100 @@ -1,19 +1,19 @@ #!/pro/bin/perl # csv2xlsx: Convert csv to xlsx -# (m)'20 [30 Nov 2020] Copyright H.M.Brand 2007-2022 +# (m)'22 Copyright H.M.Brand 2007-2023 -use 5.14.0; +use 5.014000; use warnings; -our $VERSION = "1.11"; +our $VERSION = "1.20 - 2022-06-21"; sub usage { my $err = shift and select STDERR; print <<"EOU"; -usage: csv2xlsx [-s <sep>] [-q <quot>] [-w <width>] [-d <dtfmt>] - [-o <xlsx>] [file.csv] - -s <sep> use <sep> as seperator char, auto-detect, default = ',' +usage: csv2xlsx [options] [-o <xlsx>] [file.csv] + csv2xlsx --help | --man | --info + -s <sep> use <sep> as separator char, auto-detect, default = ',' The string "tab" is allowed. -e <esc> use <esc> as escape char, auto-detect, default = '"' The string "undef" is allowed. @@ -35,18 +35,27 @@ -f force usage of <xlsx> if already exists (unlink before use) -d <dtfmt> use <dtfmt> as date formats. Default = 'dd-mm-yyyy' -C <C:fmt> use <fmt> as currency formats for currency <C>, no default - -D cols only convert dates in columns <cols>. Default is everywhere. + -D cols only convert dates in columns <cols>. + Default is everywhere. -D0 is disable -L N limit export to N rows -u CSV is UTF8 --de Some CSV fields might be double-encoded. Try to fix that. -m merge multiple CSV's into a single xlsx (separate sheets) - -o is required, all arguments should be existing files + -o is required, all arguments should be existing files + -S <cp> Split CSV on COLUMNxPAT into separate sheets. See --man + or --info for options/features and examples. May repeat. + --sl=C Use column C as sheet label when splitting with -S -v [<lvl>] verbosity (default = 1) EOU exit $err; } # usage -use Getopt::Long qw(:config bundling passthrough); +use Text::CSV_XS; +use Excel::Writer::XLSX; +use List::Util qw( first ); +use Date::Calc qw( Delta_Days Days_in_Month ); +use Encode qw( from_to ); +use Getopt::Long qw(:config bundling passthrough ); my $quo = '"'; my $esc = '"'; my $wdt = 4; # Default minimal column width @@ -57,8 +66,10 @@ my $dtc; GetOptions ( - "help|?" => sub { usage (0); }, "V|version" => sub { say $0 =~ s{.*/}{}r, " [$VERSION]"; exit 0; }, + "help|?" => sub { usage (0); }, + "man" => sub { pod_nroff (); }, + "info" => sub { pod_text (); }, "c|s|sep=s" => \my $sep, # Set after reading first line in attempt to auto-detect "q|quo=s" => \$quo, @@ -80,10 +91,34 @@ "u|utf-8|utf8!" => \my $utf, "de|fix-utf8!" => \my $dutf, # double encoded? \x{c3}\x{ab} => \x{100} "m|merge!" => \my $mrg, + "S|split=s" => \my @split, + "sl|split-label=s"=> \my $split_sl, "L|row-limit=i" => \my $row_limit, - "v|verbose:1" => \$opt_v, + "v|verbose:2" => \$opt_v, ) or usage (1); +sub pod_text { + require Pod::Text::Color; + my $m = $ENV{NO_COLOR} ? "Pod::Text" : "Pod::Text::Color"; + my $p = $m->new (); + open my $fh, ">", \my $out or die "Cannot generate manual: $!\n"; + $p->parse_from_file ($0, $fh); + close $fh; + print $out; + exit 0; + } # pod_text + +sub pod_nroff { + first { -x "$_/nroff" } grep { -d } split m/:+/ => $ENV{PATH} or pod_text (); + + require Pod::Man; + my $p = Pod::Man->new (); + open my $fh, "|-", "nroff", "-man" or die "Cannot generate manual: $!\n"; + $p->parse_from_file ($0, $fh); + close $fh; + exit 0; + } # pod_nroff + if ($mrg) { my @csv; for (@ARGV) { @@ -93,7 +128,7 @@ next; } if (m/\.(?:csv|png|jpe?g|bmp|gif|tiff|xpm)$/i && -s) { - push @csv, $_; + push @csv => $_; next; } warn "Argument $_ is not an existing (CSV) file\n"; @@ -103,6 +138,36 @@ @ARGV = @csv; } +sub col2col { + my $l = shift; + $l =~ m/^[0-9]/ and return $l; + my $c = 0; + while ($l =~ s/^([A-Za-z])//) { + $c = 26 * $c + 1 + ord (uc $1) - ord ("A"); + } + $c; + } # col2col + +foreach my $split (@split) { + my ($col, $operator, $pat) = ($split =~ m{^ + ([0-9]+|[A-Z]+|[a-z]+) # Column: A, AB, 1, 14 + ([=/uU<>]) # Operator + (.*) # Pattern/string + \z}x) or usage (1); + my $case = $col =~ m/^[a-z]/ ? 1 : 0; + $split = { + col => col2col ($col), + op => $operator, + str => $pat, + ic => $case, + lbl => undef, + }; + if ($split_sl) { + ($col) = ($split_sl =~ m/^([0-9]+|[A-Z]+)$/) or usage (1); + $split->{lbl} = col2col ($col); + } + } + my $base = @ARGV && -f $ARGV[0] ? $ARGV[0] : "csv2xlsx"; $xls ||= $base =~ s/(?:\.csv)?$/.xlsx/ir; @@ -119,12 +184,6 @@ unlink $xls; } -# Don't split ourselves when modules do it _much_ better, and follow the standards -use Text::CSV_XS; -use Date::Calc qw( Delta_Days Days_in_Month ); -use Excel::Writer::XLSX; -use Encode qw( from_to ); - if ($dutf) { eval { require Encode::DoubleEncodedUTF8; }; if ($@) { @@ -149,15 +208,16 @@ foreach my $csvf (@args) { my $sheetname = $csvf =~ s{\.\w+$}{}ir =~ s{.*/}{}r || "Sheet 1"; ($_ = length $sheetname) > 31 and substr $sheetname, 31, $_ - 31, ""; - my $wks = $wbk->add_worksheet ($sheetname); - $utf && !$wks->can ("write_unicode") and $utf = 0; + my ($wks, $w, $h); + + $opt_v > 7 and warn "Parsing $csvf into $xls.$sheetname ...\n"; if ($csvf =~ m/\.(png|jpe?g|bmp|gif|tiff|xpm)$/i) { + $wks = $wbk->add_worksheet ($sheetname); $wks->insert_image (1, 1, $csvf); next; } - my ($h, $w, @w) = (0, 1); # data height, -width, and default column widths my $row; my $firstline; my $fh; @@ -218,19 +278,74 @@ } } - if (my $rows = $dtc) { - $rows =~ s/-$/-999/; # 3,6- - $rows =~ s/-/../g; - eval "\$dtc = { map { \$_ => 1 } $rows }"; + if (length $dtc) { + if ($dtc eq "0") { + $dtc = { -2 => 0 }; + } + else { + my $rows = $dtc; + $rows =~ s/-$/-999/; # 3,6- + $rows =~ s/-/../g; + eval "\$dtc = { map { \$_ => 1 } $rows }"; + } } + my @w; # data height, -width, and default column widths while ($row && @$row or $row = $csv->getline ($fh)) { $row_limit and $csv->record_number > $row_limit and last; my @row = @$row; - @row > $w and push @w, ($wdt) x (($w = @row) - @w); + + $opt_v > 8 and warn "@row\n"; + if (@split) { + my $ns = 0; + foreach my $split (@split) { + my ($i, $op, $str, $case) = @{$split}{qw( col op str ic )}; + my $v = $row[$i - 1]; # Column-index is one-based + if (defined $v) { + $op eq "U" and $ns += 1; + if ($case) { + $op eq "=" and $ns += ( lc $v eq lc $v ); + $op eq "/" and $ns += ( $v =~ m/$str/i ); + } + else { + $op eq "=" and $ns += ( $v eq $str ); + $op eq "/" and $ns += ( $v =~ m/$str/ ); + if ($v =~ m/^[0-9]+$/) { + $op eq "<" and $ns += ( $v < $str ); + $op eq ">" and $ns += ( $v > $str ); + } + else { + $op eq "<" and $ns += ( $v lt $str ); + $op eq ">" and $ns += ( $v gt $str ); + } + } + } + else { + $op eq "u" and $ns += 1; + } + } + + $opt_v > 8 and warn join " " => "Record", $csv->record_number, + "matched", $ns, "out of", scalar @split, "criteria\n"; + if ($ns == @split) { # All criteria PASS + if (@w) { + $wks->set_column ($_, $_, $w[$_]) for 0 .. $#w; + $wks = undef; + } + $split[0]{lbl} and $sheetname = $row[$split[0]{lbl} - 1]; + } + } + + unless ($wks) { + $wks = $wbk->add_worksheet ($sheetname); + $utf && !$wks->can ("write_unicode") and $utf = 0; + ($h, $w, @w) = (0, 1); + } + + @row > $w and push @w => ($wdt) x (($w = @row) - @w); foreach my $c (0 .. $#row) { my $val = $row[$c] // ""; - my $l = length $val; + my $l = length $val; $l > ($w[$c] // -1) and $w[$c] = $l; $dutf and $csv->is_binary ($c) and utf8::valid ($val) and @@ -294,3 +409,282 @@ } $opt_v and say "Writing $xls"; $wbk->close (); + +__END__ + +=head1 NAME + +csv2xlsx - Convert CSV to Excel 2007+ + +=head1 SYNOPSIS + + csv2xlsx [options] [file.csv] + + csv2xlsx test.csv + + csv2xlsx -f -o merged.xlsx -m foobar*.csv + +=head1 DESCRIPTION + +This tool converts CSV data to Excel-2007+. It can convert the CSV into a +single sheet, merge CSV files into multiple sheets in a workbook or split +a single CSV into multiple sheets. + +The tool supports encoding, formula handle, date conversion and some more. + +=head1 OPTIONS + +=over 2 + +=item -s S + +=item --sep=S + +use C<S> as separator character, auto-detect, default = C<,>. + +The literal string C<tab> is allowed. + +=item -q Q + +=item --quo=Q + +use C<Q> as quotation character, auto-detect, default = C<">. + +The literal string C<undef> is allowed to disable quotation. + +=item -e E + +=item --esc=E + +use C<E> as escape character, auto-detect, default = C<">. + +The literal string C<undef> is allowed to disable escapes. + +=item -w W + +=item --width=W + +Set column width. Default is to auto-size per column per sheet with a +minimum width of C<4>. + +=item -o FILE.xlsx + +=item -x FILE.xlsx + +=item --out=FILE.xlsx + +Specify the output filename. Default it the same name as the input-file +where the trailing C<.csv> will be replaced with C<.xlsx>. + +If a filename can not be automatically generated, it will default to +C<csv2xlsx.xlsx>. + +=item -d format + +=item --date-fmt=format + +Use C<format> as date formats. Default = C<dd-mm-yyyy>. + +=item -D range + +=item --date-col=range + +Only convert dates in columns C<range>. Default is everywhere. + +Ranges are numeric, where the first column has index C<1>. A range is a +definition of sections joined by C<,>s. A section is either a single column +or a start/finish-pair joined with a dash. A missing finish index on the +last segment is an open range (till the end of the line). + +If the range is C<0>, date conversion is disabled. + + -D 0 + -D 1,2,6 + -D 2,4-8,12- + +=item -C format + +=item --curr-fmt=format + +Use C<format> as currency formats for currency <C>, no default. + + -C '$:### ### ##0.00' + +=item -f + +=item --force + +Force usage of the output file if it already exists (unlink before use). + +=item -F + +=item --formulas + +Allow formula's. Otherwise fields starting with an equal sign C<=> are +forced to string type. + +There are several shortcuts here to specify different behavior: + +=over 2 + +=item --Fa=a + +Define formula action: C<none>/C<die>/C<croak>/C<diag>/C<empty>/C<undef> + +=item --Ft + +Formula's will be stored as text (formula actions: none) + +=item --Fd + +Formula's will cause a die + +=item --Fc + +Formula's will cause a croak + +=item --FD + +Formula's will cause a warning (this is the default) + +=item --Fe + +Formula's will be replaced by the empty string + +=item --Fu + +Formula's will be replaced with an undefined cell + +=back + +=item -u + +=item --utf-8 + +=item --utf8 + +CSV is UTF-8 encoded. Likely not needed, as most is auto-detected. + +=item --de + +=item --fix-utf8 + +Attempt to fix double-encoded UTF-8. e.g. C<\x{00c3}\x{00ab}> should have +been C<\x0100}>. YMMV. + +=item -m + +=item --merge + +Merge multiple CSV's into a single Excel (separate sheets). + +With this option, the option C<-o> is required. All arguments should be +existing files. Piping is not supported. + +=item -L N + +=item --row-limit=N + +Limit export to C<N> rows. + +=item -S CxP + +=item --split=CxP + +When dealing with big CSV datasets, this option enables you to split the +data over several sheets. When all the C<-S> options match in a single row, +that row will be the first row of a new sheet. (see also C<--sl=C>) + +=over 2 + +=item C + +The column that should be examined. C<A> = C<1>. If lower case, the value +of that column is matched case insensitive when appropriate. + + -S 7=ab Column G is literal "ab" + -S G=ab Column G is literal "ab" + -S g=ab Column G is literal "ab", or "aB", or "Ab", or "AB" + +=item x + +Defines the operation on the column + +=over 2 + +=item = + +Literal match + + -S G=ab Column G is literal "ab" + -S g=ab Column G is literal "ab", or "aB", or "Ab", or "AB" + +=item / + +Regex match + + -S G/b[a-z] Column G matches /b[a-z]/ + -S g/b[a-z] Column G matches /b[a-z]/i + +=item u U + +Check for defined + + -S Gu Column G is undefined + -S GU Column G is defined + +Similar for emptiness + + -S G= Column G is defined but empty + -S G/. Column G is defined and not empty + +=item < > + +Compare. If the value in the column is defined compare. If the values only +holds digits, do a numeric compare, otherwise do a string compare. + + -S G<42 Column G is defined and less than 42 (numeric) + -S G<ab Column G is defined and less than 42 (string) + + -S G>42 Column G is defined and greater than 42 (numeric) + -S G>ab Column G is defined and greater than 42 (string) + +=back + +=item P + +pattern or literal string. Quotation might be required differing per OS and +shell-environment. + +=back + +=item --sl=C + +When splitting with C<-S> / C<--split>, if all criteria match and a new +sheet is to be created, use the value in column C<C> of the matching row +as the new sheet label. + +=item -v [V] + +=item --verbose[=V] + +Set verbosity level. Default = 1. No argument will set to 2. + +=back + +=head1 SEE ALSO + +csv2xls - Convert CSV to old Excel + +=head1 AUTHOR + +H.Merijn Brand + +=head1 COPYRIGHT AND LICENSE + + Copyright (C) 2016-2023 H.Merijn Brand. All rights reserved. + +This library is free software; you can redistribute and/or modify it under +the same terms as Perl itself. + +=cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/examples/csvdiff new/Text-CSV_XS-1.49/examples/csvdiff --- old/Text-CSV_XS-1.48/examples/csvdiff 2022-01-01 12:37:22.000000000 +0100 +++ new/Text-CSV_XS-1.49/examples/csvdiff 2023-01-03 13:17:23.000000000 +0100 @@ -4,7 +4,7 @@ use warnings; # csvdiff: Show differences between CSV files -# (m)'19 [05 Mar 2019] Copyright H.M.Brand 2009-2022 +# (m)'19 [05 Mar 2019] Copyright H.M.Brand 2009-2023 our $VERSION = "1.02 - 20190305"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/examples/parser-xs.pl new/Text-CSV_XS-1.49/examples/parser-xs.pl --- old/Text-CSV_XS-1.48/examples/parser-xs.pl 2022-01-01 12:37:25.000000000 +0100 +++ new/Text-CSV_XS-1.49/examples/parser-xs.pl 2023-01-03 13:17:24.000000000 +0100 @@ -3,7 +3,7 @@ # This script can be used as a base to parse unreliable CSV streams # Modify to your own needs # -# (m)'08 [23 Apr 2008] Copyright H.M.Brand 2008-2022 +# (m)'08 [23 Apr 2008] Copyright H.M.Brand 2008-2023 use strict; use warnings; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/examples/rewrite.pl new/Text-CSV_XS-1.49/examples/rewrite.pl --- old/Text-CSV_XS-1.48/examples/rewrite.pl 2022-01-01 12:37:26.000000000 +0100 +++ new/Text-CSV_XS-1.49/examples/rewrite.pl 2023-01-03 13:17:26.000000000 +0100 @@ -4,7 +4,7 @@ use warnings; # rewrite.pl: Convert csv to csv -# (m)'17 [20 Sep 2017] Copyright H.M.Brand 2014-2022 +# (m)'17 [20 Sep 2017] Copyright H.M.Brand 2014-2023 our $VERSION = "0.05 - 20170920"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/examples/speed.pl new/Text-CSV_XS-1.49/examples/speed.pl --- old/Text-CSV_XS-1.48/examples/speed.pl 2022-01-01 12:37:28.000000000 +0100 +++ new/Text-CSV_XS-1.49/examples/speed.pl 2023-01-03 13:17:28.000000000 +0100 @@ -1,7 +1,7 @@ #!/usr/bin/perl -w # speed.pl: compare different versions of Text-CSV* modules -# (m)'08 [07 Apr 2008] Copyright H.M.Brand 2007-2022 +# (m)'08 [07 Apr 2008] Copyright H.M.Brand 2007-2023 require 5.006001; use strict; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Text-CSV_XS-1.48/t/77_getall.t new/Text-CSV_XS-1.49/t/77_getall.t --- old/Text-CSV_XS-1.48/t/77_getall.t 2017-03-02 13:28:39.000000000 +0100 +++ new/Text-CSV_XS-1.49/t/77_getall.t 2022-09-12 11:24:51.000000000 +0200 @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 61; +use Test::More tests => 81; BEGIN { require_ok "Text::CSV_XS"; @@ -28,13 +28,19 @@ $sub->(\@list); $sub->(\@list, 0); $sub->([@list[2,3]], 2); - $sub->([], 0, 0); - $sub->(\@list, 0, 10); - $sub->([@list[0,1]], 0, 2); - $sub->([@list[1,2]], 1, 2); + $sub->([], 0, 0); + $sub->(\@list, 0, 10); + $sub->([@list[0,1]], 0, 2); + $sub->([@list[1,2]], 1, 2); + $sub->([@list[1,2]], 1e0, 2); + $sub->([@list[1,2]], "1", 2); $sub->([@list[1..3]], -3); - $sub->([@list[1,2]], -3, 2); - $sub->([@list[1..3]], -3, 3); + $sub->([@list[1,2]], -3, 2); + $sub->([@list[1..3]], -3, 3); + + $sub->([$list[0]], 0, 1); + $sub->([$list[0]], 0, 1e0); + $sub->([$list[0]], 0, "1"); } # do_tests foreach my $eol ("\n", "\r") {