In comp.unix.shell, Kenny McCormack <
[email protected]> wrote:
First of all, I know the standard way - the way I've been doing it for decades - which is to:
1) From Excel, write it out as a text file (tab delimited).
2) Work on it in Linux, using, e.g., AWK, creating a new tab-delimited file.
3) Load the tab-delimited file back into Excel
...
I believe there are packages available for the more popular scripting languages, such as Perl, Tcl, maybe Python, but not for AWK, that do
this. But I've never used any of them. Even though I'm doing my main processing in AWK, I would not have a problem with using something in
one of these other languages, if someone can/would "spoon feed" me on
how to do it.
The case of read/write one sheet in one xls file is covered in the
sample code in the documentation for the Perl module. Here's my version
of that sample code:
#!/usr/bin/perl -w
# Parse and dump xls files, from the Spreadsheet::ParseExcel documentation.
# This version puts all the sheets in a single file.
# 1 June 2001
use strict;
use Spreadsheet::ParseExcel;
my $oExcel = new Spreadsheet::ParseExcel;
my $xlsfile = shift;
die "$0: usage 'parsexls foo.xls > foo.out'\n"
unless (defined($xlsfile) and (-f $xlsfile));
#1.1 Normal Excel97
my $oBook = $oExcel->Parse($xlsfile);
my($iR, $iC, $oWkS, $oWkC);
print "FILE :", $oBook->{File} , "\n";
print "COUNT :", $oBook->{SheetCount} , "\n";
print "AUTHOR:", $oBook->{Author} , "\n";
my $nl;
for(my $iSheet=0; $iSheet < $oBook->{SheetCount} ; $iSheet++) {
$oWkS = $oBook->{Worksheet}[$iSheet];
print "--------- SHEET:", $oWkS->{Name}, "\n";
for(my $iR = $oWkS->{MinRow} ;
defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow} ; $iR++) {
$nl = '';
for(my $iC = $oWkS->{MinCol} ;
defined $oWkS->{MaxCol} && $iC <= $oWkS->{MaxCol} ; $iC++) {
$oWkC = $oWkS->{Cells}[$iR][$iC];
if ($oWkC) {
print "\t" if $nl;
print $oWkC->Value;
$nl = "\n";
} else {
print "\t" if $nl;
}
} # for column in row
print $nl;
} # for row in sheet
} # for sheet in book
exit
__END__
And here's my tsvtoxls reverse tool:
#!/usr/bin/perl -w
# Turn one or more TSV files into an XLS file.
# Each input file will be a sheet.
#
# Usage:
# tsvtoxls TSVfile [ TSVfile ] output.xls
# March 2011
use strict;
use Spreadsheet::WriteExcel;
# WriteExcel objects
use vars qw(
$WB $WS
);
# Other vars
use vars qw(
@sheetfiles $outfile $thisfile $line @values $value
);
for $thisfile (@ARGV) {
if( $thisfile =~ /[.]xls$/i) {
if(!defined($outfile)) {
$outfile = $thisfile;
} else {
die "$0: cannot have two output files: $outfile and $thisfile\n";
}
next;
}
if(! -f $thisfile) {
die "$0: this file $thisfile is not a file\n";
}
push(@sheetfiles, $thisfile);
}
if($#sheetfiles < 0) {
die "$0: no input files\n";
}
if(!defined($outfile)) {
die "$0: no output file\n";
}
$WB = Spreadsheet::WriteExcel->new($outfile);
for $thisfile (@sheetfiles) {
if(!open(SHEET, "< $thisfile")) {
warn "$0: cannot open $thisfile: $!, skipping\n";
next;
}
$thisfile =~ s:.*/::; # drop directory
$thisfile =~ s/[.]tsv$//; # drop suffix
$thisfile =~ tr/_/ /; # underscore to space
$WS = $WB->addworksheet($thisfile);
while(defined($line = <SHEET>)) {
chomp $line;
@values = split(/\t/, $line);
# row = line from file, start in column 0
$WS->write_row($., 0, \@values);
}
close SHEET;
}
$WB->close;
__END__
Also, one of the issues that I'm trying to get around is that when you
do step 3 in the above list, you then have to mess around a fair
amount in Excel to re-size your columns, and restore other bits of meta-information that got lost in step 1. This again, would be nice
to have be automated by the command line tool that I am seeking. As
noted, I had previously done this using Excel macros.
Those spreadsheet modules could probably read all the column, row, and
cell formatting from one shhet and apply it to another. I haven't tried.
I think I set column widths once, but I can't find my code for that now.
Also note, there's an a whole separate module for xlxs, but interface
is pretty similar as I recall.
Elijah
------
comp.lang.perl.misc will be good for further Perl questions
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)