簡體   English   中英

在 Perl 中使用 Spreadsheet::ParseExcel,但需要幫助

[英]Using Spreadsheet::ParseExcel in Perl, but need help

我有一個使用 Spreadsheet::ParseExcel 的 Perl 程序。 但是,出現了兩個我一直無法弄清楚如何解決的困難。 該程序的腳本如下:

#!/usr/bin/perl
use strict;
use warnings;
use Spreadsheet::ParseExcel;
use WordNet::Similarity::lesk;
use WordNet::QueryData;

my $wn = WordNet::QueryData->new();
my $lesk = WordNet::Similarity::lesk->new($wn);
my $parser = Spreadsheet::ParseExcel->new();
my $workbook = $parser->parse ( 'input.xls' );

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

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

    my $sheetname = $worksheet->get_name();
    my ( $row_min, $row_max ) = $worksheet->row_range();
    my ( $col_min, $col_max ) = $worksheet->col_range();
    my $target_col;
    my $response_col;

# Skip worksheet if it doesn't contain data
    if ( $row_min > $row_max ) {
       warn "\tWorksheet $sheetname doesn't contain data. \n";
       next WORKSHEET;
    }

# Check for column headers
    COLUMN:
    for my $col ( $col_min .. $col_max ) {

        my $cell = $worksheet->get_cell( $row_min, $col );
        next COLUMN unless $cell;

        $target_col   = $col if $cell->value() eq 'Target';
        $response_col = $col if $cell->value() eq 'Response';
    }

    if ( defined $target_col && defined $response_col ) {

        ROW:
        for my $row ( $row_min + 1 .. $row_max ) {
            my $target_cell   = $worksheet->get_cell( $row, $target_col);
            my $response_cell = $worksheet->get_cell( $row, $response_col);
            if ( defined $target_cell && defined $response_cell ) {
                my $target   = $target_cell->value();
                my $response = $response_cell->value();

                my $value    = $lesk->getRelatedness( $target, $response );

                print "Worksheet   = $sheetname\n";
                print "Row         = $row\n";
                print "Target      = $target\n";
                print "Response    = $response\n";
                print "Relatedness = $value\n";                

            }
            else {

                warn "\tWroksheet $sheetname, Row = $row doesn't contain target and response data.\n";
                next ROW;
            }
        }    
    }
    else {

        warn "\tWorksheet $sheetname: Didn't find Target and Response headings.\n";
        next WORKSHEET;
    }  
}

所以,我的兩個問題:

首先,有時程序會返回錯誤“在文件中找不到 Excel 數據”,即使數據在那里。 每個 Excel 文件的格式都相同。 只有一張紙,A 列和 B 列分別標記為“目標”和“響應”,其下方是單詞列表。 但是,它並不總是返回此錯誤。 它適用於一個 Excel 文件,但不適用於不同的 Excel 文件,即使兩者的格式完全相同(是的,它們也是相同的文件類型)。 我找不到任何理由不讀取第二個文件,因為它與第一個文件相同。 唯一的區別是第二個文件是使用 Excel 宏創建的; 然而,這有什么關系呢? 文件類型和格式完全相同。

其次,變量 '$target' 和 '$response' 需要格式化為字符串,以便 'my $value' 表達式工作。 如何將它們轉換為字符串格式? 分配給每個變量的值是來自 Excel 電子表格相應單元格的一個詞。 我不知道那是什么格式(並且 Perl 中沒有明顯的方法供我檢查)。

有什么建議?

關於您的第一個問題,“未找到數據”錯誤表明文件格式存在一些問題。 我已經在偽 Excel 文件(例如具有 xls 擴展名的 Html 或 CSV 文件)中看到了此錯誤。 我還看到第三方應用程序生成的格式錯誤的文件出現此錯誤。

您可以通過對工作文件和非工作文件進行 hexdump/xxd 轉儲並查看整體結構是否大致相同(例如,如果它在開始時具有相似的幻數並且不是 Html)來對文件進行初始驗證)。

也可能是 Spreadsheet::ParseExcel 的問題。 我是那個模塊的維護者。 如果您願意,可以在文檔中的電子郵件地址向我發送“好”和“壞”文件,我會查看它們。

首先,如果您得到“未找到數據”,您可以感謝專有的 Excel 數據文件格式以及即使是好的 Perl 庫也無法從中提取信息。

我強烈建議您將 Excel 數據導出為易於解析的格式,例如 CSV,特別是考慮到您所描述的數據布局的簡單性質。 可能有辦法讓 Excel 處理批處理,但我不知道。 快速搜索找到了一個使用 OpenOffice 進行批量轉換工具

一旦您接受 Excel 數據文件不會很好地播放,您的其余問題就沒有實際意義了。

在客戶無法確定他每周發送的 XLS 是真正采用 XLS 格式還是只是 CSV 格式之后,我編寫了此代碼....HTH!

sub testForXLS ()
{
my ( $FileName )    = @_;
my $signature       = '';
my $XLSsignature    = 'D0CF11E0A1B11AE10000';

open(FILE, "<$FileName")||die;
read(FILE, $buffer, 10, 0);
close(FILE);

foreach (split(//, $buffer))
    { $signature .= sprintf("%02x", ord($_)); }

$signature =~ tr/a-z/A-Z/;

if ( $signature eq $XLSsignature )
{ return 1; } else { return 0; }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM