App-SpreadsheetUtils
view release on metacpan or search on metacpan
lib/App/SpreadsheetUtils.pm view on Meta::CPAN
specifications have been defined in <pm:App::CSVUtils> and can be used. See
existing utilities for examples.
*READING CSV DATA*
To read CSV data, normally your utility would provide handler for the
`on_input_data_row` hook and sometimes additionally `on_input_header_row`.
*OUTPUTTING STRING OR RETURNING RESULT*
To output string, usually you call the provided routine `$r->{code_print}`. This
routine will open the output files for you.
You can also return enveloped result directly by setting `$r->{result}`.
*OUTPUTTING CSV DATA*
To output CSV data, usually you call the provided routine `$r->{code_print_row}`.
This routine accepts a row (arrayref or hashref). This routine will open the
output files for you when needed, as well as print header row automatically.
You can also buffer rows from input to e.g. `$r->{output_rows}`, then call
`$r->{code_print_row}` repeatedly in the `after_read_input` hook to print all the
rows.
lib/App/SpreadsheetUtils.pm view on Meta::CPAN
*WRITING TO MULTIPLE CSV FILES*
Similarly, to write to many CSv files, you first specify `writes_multiple_csv`.
Then, you can supply handler for `on_input_header_row` and `on_input_data_row`
as usual. To switch to the next file, set
`$r->{wants_switch_to_next_output_file}` to true, in which case the next call to
`$r->{code_print_row}` will close the current file and open the next file.
*CHANGING THE OUTPUT FIELDS*
When calling `$r->{code_print_row}`, you can output whatever fields you want. By
convention, you can set `$r->{output_fields}` and `$r->{output_fields_idx}` to
let other handlers know about the output fields. For example, see the
implementation of <prog:csv-concat>.
_
args => {
name => {
schema => 'perl::identifier::unqualified_ascii*',
lib/App/SpreadsheetUtils.pm view on Meta::CPAN
$r->{input_parser} = $input_parser;
my @input_filenames;
if ($reads_multiple_csv) {
@input_filenames = @{ $util_args{input_filenames} // ['-'] };
} else {
@input_filenames = ($util_args{input_filename} // '-');
}
$r->{input_filenames} //= \@input_filenames;
BEFORE_INPUT_FILENAME:
$r->{input_filenum} = 0;
INPUT_FILENAME:
for my $input_filename (@input_filenames) {
$r->{input_filenum}++;
$r->{input_filename} = $input_filename;
if ($r->{input_filenum} == 1 && $before_open_input_files) {
log_trace "Calling before_open_input_files handler ...";
$before_open_input_files->($r);
if (delete $r->{wants_skip_files}) {
log_trace "Handler wants to skip files, skipping all input files";
last READ_CSV;
}
}
if ($before_open_input_file) {
log_trace "Calling before_open_input_file handler ...";
$before_open_input_file->($r);
if (delete $r->{wants_skip_file}) {
log_trace "Handler wants to skip this file, moving on to the next file";
next INPUT_FILENAME;
} elsif (delete $r->{wants_skip_files}) {
log_trace "Handler wants to skip all files, skipping all input files";
last READ_CSV;
}
}
log_info "[file %d/%d] Reading input file %s ...",
$r->{input_filenum}, scalar(@input_filenames), $input_filename;
my ($fh, $err) = _open_file_read($input_filename);
die $err if $err;
lib/App/SpreadsheetUtils.pm view on Meta::CPAN
for my $j (0 .. $#{ $r->{input_fields} }) {
$r->{input_fields_idx}{ $r->{input_fields}[$j] } = $j;
}
if ($on_input_header_row) {
log_trace "Calling on_input_header_row hook handler ...";
$on_input_header_row->($r);
if (delete $r->{wants_skip_file}) {
log_trace "Handler wants to skip this file, moving on to the next file";
next INPUT_FILENAME;
} elsif (delete $r->{wants_skip_files}) {
log_trace "Handler wants to skip all files, skipping all input files";
last READ_CSV;
}
}
# reindex the fields, should the above hook
# handler adds/removes fields. let's save the
# old fields_idx to orig_fields_idx.
$r->{orig_input_fields_idx} = $r->{input_fields_idx};
lib/App/SpreadsheetUtils.pm view on Meta::CPAN
$r->{input_row_as_hashref}{ $r->{input_fields}[$j] } = $r->{input_row}[$j];
}
}
if ($on_input_data_row) {
log_trace "Calling on_input_data_row hook handler (for first data row) ..." if $r->{input_rownum} <= 2;
$on_input_data_row->($r);
if (delete $r->{wants_skip_file}) {
log_trace "Handler wants to skip this file, moving on to the next file";
next INPUT_FILENAME;
} elsif (delete $r->{wants_skip_files}) {
log_trace "Handler wants to skip all files, skipping all input files";
last READ_CSV;
}
}
}
} # while getline
# XXX actually close filehandle except stdin
( run in 0.443 second using v1.01-cache-2.11-cpan-c6e0e5ac2a7 )