Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / (Perl) Spreadsheet-ParseExcel-0.32 / 6 сообщений из 6, страница 1 из 1
04.07.2008, 12:44
    #35411273
GKirill
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(Perl) Spreadsheet-ParseExcel-0.32
Написал скриптик для сохранения данных из Xls в Csv.
Использовал пакет Spreadsheet-ParseExcel-0.32 для чтения данных.
Файлики размером 40-60 метров. Чтобы не было проблем с памятью, использовал способ, описанный здесь .
При сохранении необходимо откидывать пустые строки.
Поэтому воспользовался свойством MaxRow.
Но оно почему-то на всех листах равно 32.
Почему? Данных гораздо больше.
Ниже приведен код скрипта.
Всем заранее спасибо за помощь.

PS. С перлом работаю всего полторы недели, поэтому прошу сильно не пинать.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
#!C:\Perl\bin\perl.exe 
#line  15 

use strict;
use warnings;
use Cwd;
use English qw( -no_match_vars );
use File::Basename;
use File::Spec::Functions;
use Getopt::Long;
use Pod::Usage;
use Readonly;
use Spreadsheet::ParseExcel;
use Encode 'encode', 'decode';
use Data::Dumper;
use Date::Simple (':all');

Readonly my $VERSION   => '0.01';
Readonly my $EMPTY_STR => q{};

my $delimiter = ";";
my ( $help, $man_page, $show_version );
 
GetOptions(
    'd|ofs:s' => \$delimiter,
    'help'    => \$help,
    'man'     => \$man_page,
    'version' => \$show_version,
) or pod2usage( 2 );

if ( $help || $man_page ) {
    pod2usage({
        -exitval =>  0 ,
        -verbose => $man_page ?  2  :  1 
    });
}; 

if ( $show_version ) {
    my $prog = basename( $PROGRAM_NAME );
    print "$prog v$VERSION\n";
    exit  0 ;
}

my @files = @ARGV or pod2usage('No input files');
my $cwd   = cwd();
my ( $num_files_processed, $num_out_files ) = (  0 ,  0  );

my $parse_excel = new Spreadsheet::ParseExcel(CellHandler => \&cell_handler,
                                              NotSetCell  =>  1 );

INPUT_FILE:
for my $file ( @files ) {
    unless ( -e $file && -s _ && -r _ ) {
        warn "'$file' doesn't exist, is zero-length or unreadable, skipping.\n";
        next INPUT_FILE;
    }
    
    my $prev_row        = 0;
    my $prev_col        = 0;
    my $prev_sheet      = -1;
    my $ws_worked_count = 0;
    my $out_fh;
    my $ws_name;
    my $max_row = 0;
    my $temp_value = '';
    my $check_value;
    my $last_row = 0;

    my $workbook = $parse_excel->Parse( $file );

    if ( ref $workbook->{'Worksheet'} ne 'ARRAY' ) {
        warn "'$file' has no worksheets (not an Excel spreadsheet?)\n";
        next INPUT_FILE;
    }

    sub cell_handler {

        my $workbook    = $_[0];
        my $sheet_index = $_[1];
        my $row         = $_[2];
        my $col         = $_[3];
        my $cell        = $_[4];
        
        if ($sheet_index != $prev_sheet) {
            my $ws = $workbook->{Worksheet}[$sheet_index];
            $ws_name = $ws->{Name};
            $max_row = $ws->{'MaxRow'};
        }
        
        if ( 
             (encode('cp1251',$ws_name) ne "Список")               and
             (encode('cp1251',$ws_name) ne "Справочники")          and
             (encode('cp1251',$ws_name) ne "Справочник налоговых") and
             (encode('cp1251',$ws_name) ne "Банки")                and
             (encode('cp1251',$ws_name) ne "Назначения")           and
             (encode('cp1251',$ws_name) ne "Методы платежа")       and
             (encode('cp1251',$ws_name) ne "Остатки")              and
             (encode('cp1251',$ws_name) ne "Циклические элементы") and
             (encode('cp1251',$ws_name) ne "Данные по вычетам")
           ) {
            
            if ($sheet_index != $prev_sheet) {
                if ($ws_worked_count > 0) {
                    close $out_fh;
                }
                $prev_row     = 0;
                $last_row     = 0;
                $temp_value   = '';
                $ws_worked_count++;
                $ws_name      =~ s/.txt//o;
                $ws_name      =~ tr[a-z][A-Z];
                my $out_file  = encode('cp1251', catfile($cwd, "CONV_$ws_name.csv"));
                open $out_fh, '>', $out_file
                    or die "Can't write to '$out_file': $!\n";
            }
            
            # Reset the col counter between rows
            if ($row != $prev_row) {
                $prev_col =  0 ;
                if ($row >  5 ) {
                    $check_value = $temp_value;
                    $check_value =~ s/$delimiter//g;
                    $check_value =~ s/\ //g;
                    if ($check_value) {
                        if ($row >  6 ) {
                            print {$out_fh} "\n";
                        }
                        print {$out_fh} $temp_value;
                    }
                    $temp_value = '';
                }
            }
            
            # Add delimiter between fields and newlines between rows, pad
            # any missing rows or columns, also print the formatted value
            # of the cell.
            if ($row >  4 ) {
                my $out_value;
                if ($cell->{Type} eq 'Numeric') {
                    $out_value = $cell->{Val};
                    $out_value =~ s/\./\,/g;
                }
                elsif ($cell->{Type} eq 'Date') {
                    $out_value = date('1899-12-30') + $cell->{Val};
                    $out_value++ if $cell->{Val} <  60 ;
                    $out_value = $out_value->format("%d.%m.%Y");
                }
                else {
                    $out_value = $cell->{_Value};
                    if ($out_value =~ m/\"/g) {
                        $out_value =~ s/\"/\"\"/g;
                        $out_value = "\"$out_value\"";
                    }
                }
                if ($row < $max_row) {
                    $temp_value = $temp_value . $delimiter for $prev_col + 1  .. $col;
                    $temp_value = $temp_value . encode('cp1251', $out_value);
                }
                elsif (
                        ($row = $max_row) and
                        ($last_row ==  0 )  and
                        ($out_value)      and
                        ($out_value ne ' ')
                      ) {
                    $last_row =  1 ;
                    print {$out_fh} "\n" . encode('cp1251', $out_value);
                }
                elsif (
                        ($row = $max_row) and
                        ($last_row ==  1 )
                      ) {
                    print {$out_fh} $delimiter for $prev_col + 1  .. $col;
                    print {$out_fh} encode('cp1251', $out_value);
                }
            }
            
            # Keep track of where we are
            $prev_row   = $row;
            $prev_col   = $col;
            $prev_sheet = $sheet_index;
        }
    }
    
    $num_files_processed++;
}

printf "Done, processed %s Excel files, created %s data files.\n",
    $num_files_processed, $num_out_files;

__END__

# ----------------------------------------------------
=head1 NAME

TO_CSV - convert Excel data to delimited text files

=head1 VERSION

This documentation refers to TO_CSV version  1 . 00 / 01 .

=head1 SYNOPSIS

  TO_CSV [options] File1.xls [File2.xls ...]

Options:

  -d|-ofs       Output field delimiter (default is ;)
  --help        Show brief help and exit
  --man         Show full documentation
  --version     Show version and exit

=head1 DESCRIPTION

For each worksheet within an Excel spreadsheet, creates a delimited 
file.  By default, the output files will use a ; character as the 
delimiter.  Use the "-d" switch to specify something else.

=head1 SEE ALSO

Spreadsheet::ParseExcel.

=head1 AUTHOR

Ken Youens-Clark

=head1 COPYRIGHT

Copyright (c)  2005  Ken Youens-Clark

This library is free software;  you can redistribute it and/or modify 
it under the same terms as Perl itself.

=cut

__END__
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
28.11.2013, 02:37
    #38480987
volodin661
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(Perl) Spreadsheet-ParseExcel-0.32
Эх, GKirill,
написано же в описании на чистом англ. языке:


row_range() --

Returns a two-element list ($min, $max) containing the minimum and maximum defined rows in the worksheet. If there is no row defined $max is smaller than $min.


Модератор:
volodin661 , не пора ли завязывать с некропостингом?
...
Рейтинг: 0 / 0
30.11.2013, 09:55
    #38484281
volodin661
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(Perl) Spreadsheet-ParseExcel-0.32
volodin661Эх, GKirill,
написано же в описании на чистом англ. языке:


row_range() --

Returns a two-element list ($min, $max) containing the minimum and maximum defined rows in the worksheet. If there is no row defined $max is smaller than $min.


Модератор:
volodin661 , не пора ли завязывать с некропостингом?


ленина в мавзолее 90 лет значит можно, а мне и пару строк черкнуть виртуальном мире нельзя?
...
Рейтинг: 0 / 0
30.11.2013, 13:17
    #38484368
netwind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(Perl) Spreadsheet-ParseExcel-0.32
volodin661, ну так к Ленину по сейчас очередь, а вы пишете людям о проблемах, которые их уже давно не интересуют.
...
Рейтинг: 0 / 0
30.11.2013, 17:32
    #38484513
volodin661
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(Perl) Spreadsheet-ParseExcel-0.32
вот смотри, netwind, тебя так живо заинтересовала данная тема ( малява от Volodin661 мертвецу),
что ты сам втянулся и начал писать; иными словами, незримая связь между живыми и мёртвыми существует
и порождает новые связи.
...
Рейтинг: 0 / 0
30.11.2013, 19:06
    #38484581
Warstone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
(Perl) Spreadsheet-ParseExcel-0.32
netwind,

Предлагаю ему 3 дня ридонли.
...
Рейтинг: 0 / 0
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / (Perl) Spreadsheet-ParseExcel-0.32 / 6 сообщений из 6, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]