मेरे पास एक बड़ी xlsx फ़ाइल (लगभग 127 एमबी) है और मैं Spreadsheet::Excel मॉड्यूल का उपयोग करके पढ़ना चाहता हूं, लेकिन मुझे 2GB RAM मशीन पर "मेमोरी से बाहर" त्रुटियां हो रही हैं। (ध्यान दें कि स्क्रिप्ट छोटी एक्सेल 2007 फाइलों के साथ ठीक काम करती है)

क्या स्मृति सीमा को प्रभावित किए बिना एक्सेल फ़ाइल लाइन को लाइन से पढ़ने का कोई तरीका है।? Google पर खोज करने पर मुझे http://discuss.joelonsoftware.com/default.asp? joel.3.160328.14 लेकिन मैं इस बारे में परिचित नहीं हूं कि स्प्रेडशीट को स्केलर में कैसे स्टोर किया जाए। क्या कोई एक्सेल 2007 फाइलों को स्केलर और प्रिंटिंग सेल वैल्यू के रूप में पढ़ने का उदाहरण दे सकता है। नीचे वर्तमान स्क्रिप्ट है जो मैं छोटी स्प्रैडशीट्स पर चला रहा हूं।

#!/usr/bin/perl
use Excel::Writer::XLSX;
use Spreadsheet::XLSX;
my $workbook  = Excel::Writer::XLSX->new('Book1.xlsx');
my $worksheet = $workbook->add_worksheet();
#  use strict;
my $excel = Spreadsheet::XLSX -> new ('Book2.xlsx');
my $date_format = $workbook->add_format();
$date_format->set_num_format('dd/mm/yy hh:mm');
# Columns of interest
@columns=(0,1,2,5,9,10,12,13,31);
@reportlist=("string1","String2","String3");
@actuallist=("ModifiedString1","ModifiedString2","ModifiedString3");
$max_list=$#reportlist;
foreach my $sheet (@{$excel -> {Worksheet}}) {
    printf("Sheet: %s\n", $sheet->{Name});
    $sheet -> {MaxRow} ||= $sheet -> {MinRow};
        foreach my $row ($sheet -> {MinRow} .. $sheet -> {MaxRow}) {
            $sheet -> {MaxCol} ||= $sheet -> {MinCol};
            for ($c=0;$c<=$#columns;$c++){
                $col=$columns[$c];
                my $cell = $sheet -> {Cells} [$row] [$col];
                    if($col==0){
                    $cell->{Val}=~ s/\ GMT\+11\:00//g;
                    $worksheet->write($row,$c,$cell->{Val},$date_format);
                    }
                    if ($cell) {
                        $worksheet->write($row,$c,$cell -> {Val});
                            for($z=0;$z<=$#reportisplist;$z++){
                                if(($cell->{Val})=~ m/$reportlist[$z]/i){
                                $worksheet->write($row,$c,$actuallist[$z]);
                                }
                            }
                    }
            }
        }
}
$workbook->close();
4
Linus 2 मार्च 2011, 08:14

4 जवाब

सबसे बढ़िया उत्तर

मैं पर्ल के साथ एक्सेल एक्सएलएसएक्स फाइलों के तेज और मेमोरी कुशल पढ़ने के लिए एक नए मॉड्यूल पर काम कर रहा हूं। यह अभी तक CPAN पर नहीं है (इसे और अधिक काम करने की आवश्यकता है) लेकिन आप इसे GitHub पर प्राप्त कर सकते हैं .

इसका उपयोग कैसे करें इसका एक उदाहरण यहां दिया गया है:

use strict;
use warnings;
use Excel::Reader::XLSX;

my $reader   = Excel::Reader::XLSX->new();
my $workbook = $reader->read_file( 'Book1.xlsx' );

if ( !defined $workbook ) {
    die $reader->error(), "\n";
}

for my $worksheet ( $workbook->worksheets() ) {

    my $sheetname = $worksheet->name();

    print "Sheet = $sheetname\n";

    while ( my $row = $worksheet->next_row() ) {

        while ( my $cell = $row->next_cell() ) {

            my $row   = $cell->row();
            my $col   = $cell->col();
            my $value = $cell->value();

            print "  Cell ($row, $col) = $value\n";
        }
    }
}

__END__

अपडेट करें: यह मॉड्यूल कभी भी सीपीएएन गुणवत्ता तक नहीं पहुंचा। इसके बजाय स्प्रेडशीट::ParseXLSX आज़माएं।

5
jmcnamara 28 अक्टूबर 2014, 12:33

क्या आपने XLSX को csv में बदलने और इसे एक सादे पाठ फ़ाइल के रूप में पढ़ने का प्रयास किया है?

4
Rasika 2 मार्च 2011, 08:16

इसे आजमाएं। मान लें कि आपने स्प्रेडशीट :: रीड पर्ल मॉड्यूल स्थापित किया है, जो फ़ाइल को पढ़ने के लिए उपयोग करने के लिए वास्तविक पार्सर मॉड्यूल को निर्धारित कर सकता है, कोड अंशों के नीचे इनपुट वर्कबुक की पहली वर्कशीट के सेल को पढ़ता है और प्रिंट करता है। कॉन्फ़िगर करने के लिए उपलब्ध सभी विकल्पों को देखने के लिए आप $workbook ऑब्जेक्ट की जांच कर सकते हैं। इस मॉड्यूल का उपयोग "सीएसवी", "एक्सएलएस" जैसे अन्य प्रारूपों में फ़ाइलों को पढ़ने के लिए भी किया जा सकता है। यहाँ ट्यूटोरियल का लिंक दिया गया है जो मुझे उपयोगी लगा: http://search.cpan.org/~hmbrand/Spreadsheet-Read/Read .pm

ReadData को विकल्पों को पास करके कॉन्फ़िगर किया जा सकता है। इसमें प्रत्येक 2 विकल्पों में से कई विकल्प हैं जो "सेल" हैं और "आरसी" का उपयोग फ़ाइल पढ़ने से संबंधित व्यवहार को संशोधित करने के लिए किया जा सकता है। डिफ़ॉल्ट रूप से दोनों विकल्प सत्य पर सेट होते हैं। यदि "कोशिकाएं" सत्य हैं तो रीडडाटा कार्यपुस्तिका के कक्षों को लौटाई गई वस्तु में हैश में संग्रहीत करता है। यदि "आरसी" सत्य है तो रीडडाटा कार्यपुस्तिका की कोशिकाओं को लौटाए गए ऑब्जेक्ट में सरणी में संग्रहीत करता है। नीचे दिए गए कोड के टुकड़े में, सेल => 0 सेट करके, शीट की सामग्री को हैश प्रारूप में $वर्कबुक ऑब्जेक्ट में संग्रहीत नहीं किया जाएगा, इस प्रकार स्मृति में कुछ स्थान की बचत होगी। डिफ़ॉल्ट रूप से यह विकल्प सत्य है अर्थात 1 और इसी तरह। साथ ही पूरी फाइल को पढ़ने से रोकने के लिए, आप विकल्प "आरसी" को गलत पर भी सेट कर सकते हैं।

use Spreadsheet::Read;
############################################################################
# function input  : file in xlsx format with absolute path 
# function output : prints 1st worksheet content if exist
############################################################################
sub print_xlsx_file{

    my $file_path = shift;
    my $workbook = ReadData($file_path,cells => 0 );
    if(defined $workbook->[0]{'error'}){
        print "Error occurred while processing $file_path:".
              $workbook->[0]{'error'}."\n";
        exit(-1);
    }
    my $worksheet = $workbook->[1];
    my $max_rows = $worksheet->{'maxrow'};
    my $max_cols = $worksheet->{'maxcol'};

    for my $row_num (1..($max_rows))
    {
        for my $col_num (1..($max_cols)){
            print $worksheet->{'cell'}[$col_num][$row_num]."\n";
        }
    }
}
# call above function
# print_xlsx_file("/home/chammu/mybook.xlsx");
0
chammu 31 अगस्त 2014, 19:49

सीएसवी समाधान एक अच्छा है। लेकिन xlsb के रूप में बचत करने पर भी विचार करें - यह कुछ एक्सेल क्षमताओं की अनुमति देते हुए अक्सर समान फ़ाइल-आकार का सिकुड़न प्रदान करेगा। (इसे एक टिप्पणी के रूप में पोस्ट किया होगा लेकिन प्रतिष्ठा नहीं है ... अभी तक)।

0
N Mason 15 फरवरी 2017, 14:06