2010-12-02 30 views
1

Y at-il un moyen de prendre facilement 3 fichiers texte et le transformer en une feuille excel multi-onglet via un script?Y at-il un moyen de prendre facilement 3 fichiers texte et le transformer en une feuille excel multi-onglet via un script?

Les fichiers sont file1.txt, fichier 2.txt, fichier3.txt - je voudrais le sortir sur excelsheet1.xls avec 3 onglets.

+0

Faut-il vraiment être .xls? Il serait très facile de les assembler dans un seul fichier .csv avec un script Perl, et sur la plupart des systèmes, les fichiers .csv s'ouvriront automatiquement dans Excel. – Ertebolle

+0

bien, j'en ai besoin dans des onglets. Mais, si cela n'est pas possible -single csv serait mon option suivante – samsam

Répondre

4

Vous ne mentionnez pas le format des fichiers texte, par conséquent le code d'exemple réel est difficile, mais vous pouvez utiliser Spreadsheet::WriteExcel pour cela. Regardez la méthode add_worksheet() pour créer de nouveaux onglets. Étant donné que vous dites que chaque ligne est un nombre suivi d'un texte, je présume qu'il s'agit de deux colonnes par ligne avec un espace délimitant les première et deuxième colonnes et seulement des chiffres dans la première colonne. Si ce n'est pas vrai, l'expression rationnelle ci-dessous devrait être ajustée. Cela dit, voici un exemple de code.

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Spreadsheet::WriteExcel; 

sub read_file{ 
     my $f = shift; 
     my @row; 
     open(my $fh, '<', $f) or die $!; 
     while(<$fh>){ 
       chomp; 
       s/^(d+)s+//; # assuming format of "1 Text heren2 More textn" 
       if(defined $1){ 
         push(@row, [$1, $_]); 
       } 
     } 
     close($fh) or die $!; 

     return @row; 
} 

if($#ARGV < 1){ 
     die "$0: file1 [file2 ... filen] output.xls\n"; 
} 
my $xl = Spreadsheet::WriteExcel->new(pop); 

foreach my $file (@ARGV){ 
     if(-f $file){ 
       my @rows = read_file($file); 
       my $sheet = $xl->add_worksheet($file); 
       for my $row (0..$#rows){ 
         my @cols = @{$rows[$row]}; 
         for my $col (0..$#cols){ 
           $sheet->write($row, $col, $cols[$col]); 
         } 
       } 
     } 
} 

fichiers d'entrée sont données sur la ligne de commande et traitées dans l'ordre, tournant chacun dans un onglet nommé d'après le nom du fichier. Le nom du fichier de sortie est indiqué en dernier sur la ligne de commande, après un ou plusieurs noms de fichier d'entrée.

EDIT: Maintenant, y compris les améliorations FM mentionnées dans son commentaire et un CLI trivial pour spécifier le nom du fichier de sortie.

+0

Les fichiers texte sont juste le texte droit ils commencent tous par un nombre avec une phrase à côté du nombre – samsam

+0

Est-ce que cela signifie "Une seule colonne d'enregistrements délimités par le retour à la ligne" ? – Sorpigal

+1

@Sorpigal Réponse utile. Serait encore mieux s'il utilisait des boucles 'for' idiomatiques:' pour ma $ row (0 .. $ # rows) '. Et s'il utilisait des handles de fichiers lexicaux: 'open (my $ fh, '<', $ file_name)'. Nitpicking, je suppose. En note, voir également cette réponse récente sur les deux styles de boucle: http://stackoverflow.com/questions/4330287/perl-performance-for1-200000-vs-for-1-200000/4330560#4330560. – FMc