AbevJava bevallások gyártása CSV vagy XLS fájlokból

Pár havonta megkeres egy ismerősöm, hogy van egy Excel táblája, amiből 0908M lapokat kéne készíteni.

Ezzel a Perl szkripttel szoktam csinálni:


use encoding cp1250;

binmode STDOUT, ':encoding(cp852)'; 

while( $txt = <*.txt> ){
  ( $fn ) = ( $txt =~ /^(.*)\.txt$/ );

  print "fájl: '$txt'\n";

  open( IN, '<:encoding(cp1250)', $txt );
  $sor = <IN>;
  chomp( $sor );
  @mezo_kod = split( /[ ]*\t[ ]*/, $sor );
  $sorszam=1;
  while( $sor = <IN> ){
    chomp($sor);

    @mezo_ertek = split( /[ ]*\t[ ]*/, $sor );

    next unless( defined $mezo_ertek[0] );

    open( OUT, '>:encoding(cp1250)', "${fn}-${sorszam}.imp" );
    for( $i=0; $i < scalar( @mezo_kod ); $i++ ){
      $mezo_ertek[$i] = '' unless( defined($mezo_ertek[$i]) );
      $mezo_ertek[$i] =~ s/\s+/ /g;
      print OUT $mezo_kod[$i], '=', $mezo_ertek[$i], "\n";
    }
    close( OUT );

    $sorszam++;
  }
  close( IN );
}

A tabulátorral elválasztott szöveg formában (CSV) lementett táblázat első sorában az .IMP fájlba kerülő mezők azonosítóinak kell szerepelni ($ny_azon, $sorok_száma, $d_lapok_száma, 13841, 13843, 16697, 16698, 13846, stb.), a szkript az első sorból vett adatok alapján egy-egy IMP fájlt készít a táblázat soraiból, amiket aztán egy mozdulattal be lehet töltetni az AbevJavá-val.

Az azonosítókat a legegyszerűbb egy "Teszt import fájl"-ból kinyerni. Kitöltünk egy lapot az AbevJavá-ban a nyomtatványból, majd a "Szerviz/Fejlesztőknek/Teszt import fájl" menüben elkészíttetünk egy .IMP fájlt. Az általunk begépelt teszt adatok alapján könnyen kikereshetők a szükséges mezők azonosítói, a többi üres mezővel pedig nem kell foglalkozni.

Zeller javaslatára készítettem egy XLS fájlokat feldolgozó változatot is:



use strict;

use Spreadsheet::ParseExcel;
my $parser = Spreadsheet::ParseExcel->new();

sub cell($$$);

while( my $xls = <*.xls> ){
  my $wb = $parser->Parse($xls);
  unless( defined($wb) ){ print "'$xls' nem Excel fajl?\n"; next; }

  foreach my $ws ( $wb->worksheets() ){
    my ( $col_min, $col_max, $row_min, $row_max ) = ( $ws->col_range(), $ws->row_range() );

    if( $col_max > $col_min && cell( $ws, $row_min, $col_min ) eq '$ny_azon' ){
      my $sorszam = 0;
      foreach my $row (($row_min+1)..$row_max){
        next unless( cell($ws, $row, $col_min) );

        open( OUT, '>:encoding(cp1250)', $xls.'_'.$ws->{Name}.'_'.$sorszam++.'.imp' );
        print OUT cell($ws, $row_min, $_), '=', cell($ws, $row, $_), "\n" foreach($col_min..$col_max);
        close( OUT );
      }
      print "fajl: $xls   lap:  $ws->{Name}   sor: $sorszam\n";
    }
  }
}

sub cell($$$){
  my( $ws, $row, $col ) = @_;
  my $c =  $ws->get_cell($row,$col);
  my $s =  $c? $c->value(): '';
     $s =~ s/\s+/ /g;
     $s =~ s/^\s+//;
     $s =~ s/\s+$//;
  return $s;
}

Ez a szkript sorra veszi az .XLS fájlokat, és .IMP fájlokat gyárt azokból a lapokból, amiknek a bal felső cellájában '$ny_azon' található.

Hozzászólások

Érdemes lehet megnézni a Spreadsheet::ParseExcel modult, nem kell csv-s mentéssel bajlódni.