Perl技术实现:将XLSX转为Hash时基于列标题设置超级键
问题修复:通过列标题指定Perl哈希的超级键
核心问题剖析
现有代码的错误根源:
- 未定义变量
$col,导致无法定位「Symbol」列的索引位置,判断逻辑完全失效 - 获取超级键的逻辑嵌套在行循环中,仅在标题行(行0)会触发判断,但数据行不会执行该分支,最终
$super_key始终为空 - 原代码中
$value的列索引错误(用了Symbol列的索引2,实际应该对应Type列的索引1)
修复方案
- 先遍历标题行,定位「Symbol」列的索引,避免硬编码列位置
- 从行1开始遍历数据行,跳过标题行
- 用预先获取的Symbol列索引,提取每行的Symbol值作为超级键
修复后的代码
use Data::Dumper; use Text::Iconv; use Spreadsheet::XLSX; my $converter = Text::Iconv->new("utf-8", "windows-1251"); my $excel = Spreadsheet::XLSX->new('file.xlsx', $converter); foreach my $sheet (@{$excel->{Worksheet}}) { next unless $sheet->{Name} eq "sheet1"; my %data; my $symbol_col_idx; # 遍历标题行,获取Symbol列的索引 for my $col (0 .. $sheet->{MaxCol}) { if ($sheet->{Cells}[0][$col]{Val} eq "Symbol") { $symbol_col_idx = $col; last; } } die "未找到Symbol列" unless defined $symbol_col_idx; # 遍历数据行(跳过标题行) for my $row (1 .. $sheet->{MaxRow}) { my $super_key = $sheet->{Cells}[$row][$symbol_col_idx]{Val}; my $key = $sheet->{Cells}[$row][0]{Val}; my $value = $sheet->{Cells}[$row][1]{Val}; my $value2 = $sheet->{Cells}[$row][3]{Val}; $data{$super_key}->{$key}->{$value} = $value2; } print Dumper \%data; }
代码说明
- 先确定Symbol列的索引,适配列顺序变更的场景,无需硬编码列位置
- 数据行从索引1开始,避免把表头数据混入哈希
- 修正了原代码中Type列索引的错误,确保哈希层级对应正确
- 增加了错误判断,若未找到Symbol列则终止程序,避免后续逻辑出错
最终输出示例
运行修复后的代码,会得到符合预期的哈希结构:
$VAR1 = { 'X' => { 'JOHN' => { 'SUV' => 'R' } }, 'Y' => { 'ROB' => { 'MPV' => 'B' }, 'JAMES' => { '4X4' => 'G' } } };
内容的提问来源于stack exchange,提问作者paaven
相关产品推荐
相关产品推荐

