powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / (Perl) Spreadsheet-ParseExcel-0.32
6 сообщений из 6, страница 1 из 1
(Perl) Spreadsheet-ParseExcel-0.32
    #35411273
GKirill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Написал скриптик для сохранения данных из 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
Период между сообщениями больше года.
(Perl) Spreadsheet-ParseExcel-0.32
    #38480987
Фотография 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 , не пора ли завязывать с некропостингом?
...
Рейтинг: 0 / 0
(Perl) Spreadsheet-ParseExcel-0.32
    #38484281
Фотография volodin661
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
(Perl) Spreadsheet-ParseExcel-0.32
    #38484368
netwind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
volodin661, ну так к Ленину по сейчас очередь, а вы пишете людям о проблемах, которые их уже давно не интересуют.
...
Рейтинг: 0 / 0
(Perl) Spreadsheet-ParseExcel-0.32
    #38484513
Фотография volodin661
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот смотри, netwind, тебя так живо заинтересовала данная тема ( малява от Volodin661 мертвецу),
что ты сам втянулся и начал писать; иными словами, незримая связь между живыми и мёртвыми существует
и порождает новые связи.
...
Рейтинг: 0 / 0
(Perl) Spreadsheet-ParseExcel-0.32
    #38484581
Фотография Warstone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netwind,

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


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