0

原帖太长:Fetching zero cells in XLS file using Spreadsheet::ParseExcel

xls 的数据结构。文件如下所示:

      col1      col2    col3   col4   col5 
row1  School    1
row2  Dean      John
row3  No.stu.   55
row4  some irrelevant stuff 
row5  School2   2
row6  Dean      Tony 
row7  No. stu.  60 
row8  some irrelevant stuff
row9  School    3
row10 Dean      James
row11 No.stu.   56
row12 No. teacher 20
row13 School    4
row14 Dean      Tom
row15 No.stu.   79
row16 No. teacher 21
row17 course    
row18           math    2
row19           eng     4      
row20 teacher   name    age   gender   race 
row21           Jane    20    female   white  
row22 student   name    Lee 
row23           SAT     1434
row24           gender  male  

正如 imran 所建议的,我使用 Spreadsheet::ParseExcel 使用了以下结构;

    my %data;
    my $state = "";
    my $school = "";
    my $student = "";
    my ( $row_min, $row_max ) = $worksheet->row_range();
    my $row = $row_min;
    while ($row <= $row_max) {
        my $cell0 = $worksheet->get_cell( $row, 0 );
        my $cell1 = $worksheet->get_cell( $row, 1 );

        if (defined($cell0)) {
            my $key = $cell0->value();
            if ($key eq 'School') {
                $state = 'school';
                $school = $cell1->value();
            } elsif ($key eq 'course') {
                $state = 'course';
            } elsif ($key eq 'teacher') {
                $state = 'teacher';
            } elsif ($key eq 'student') {
                $state = 'student');
                $student = $worksheet->get_cell( $row, 2 )->value();
            } else {
                $data{$school}{$key} = $cell1->value();
            }
        } elsif ($state eq 'course') {
            # process columns for course
        } elsif ($state eq 'teacher') {
            # process columns for teacher
        } elsif ($state eq 'student') {
            # process columns for student
        }
        $row++;
    }

效果很好。

但似乎在 each 中state,它从第二行开始解析。也就是说,如果我们将 course 声明为一个状态,它会从下一行开始处理,直到到达下一行state。但是,例如,如果每个学校的课程状态的数据结构略有不同,即state课程的键和值之一在同一行,

     School    1 
     course    math    
               eng
     ...
     School     2
     course    phy
     ...   
     School     3 
     course    chem 
               gym 
               music 

如果我坚持使用原始代码:

 } elsif ($key eq 'course') {
                $state = 'course';
                $course = $worksheet->get_cell( $row, 1 )->value();
    }

相应的哈希表为:

} elsif ($state eq 'course') {
            my $key = $cell1->value();
            $data{$school}{$course}{$key} =$cell1->value();
}

但是,它只能解析

 '1' => {
                   'math' => {
                               'eng' => 'eng'
                             },
       }
'3' => {
   'chem' => {
                               'gym' => 'gym',
                               'music' => 'music
                             },
      }

并且没有解析school2.

问题是,如果这个模块有任何灵活性可以让我从我想要的任何地方解析?

此致,

4

1 回答 1

2

我认为您需要下面的结构,而不是上面提到的结构:

'1' => {
               'course' => {
                           'math' => 'math'
                           'eng' => 'eng'
                         },
   }
'3' => {
               'course' => {
                           'chem' => 'chem'
                           'gym' => 'gym',
                           'music' => 'music
                         },
  }

因此,您的哈希名称应以学校编号开头,里面当然有哈希,里面有所有课程的键值对。

这样,您以后也可以很容易地解析它。

编辑:

你可以把你的代码改成这样(我不知道你这样做的确切方式):

 } elsif ($key eq 'course') {
            $state = 'course';
            $course = $state;
            $key = $worksheet->get_cell( $row, 1 )->value();
            $data{$school}{$course}{$key} = $key;
}

像这样的东西应该可以工作,您可能需要根据您的要求进行一些更改。

于 2013-04-23T07:14:50.477 回答