如何使用Spreadsheet::ParseXLSX正确读取.xlsx格式Excel文件
报错根因
你的代码存在核心逻辑错误:
- 代码中
use Spreadsheet::ParseXLSX引入了专门解析.xlsx格式的模块,但实际实例化的是Spreadsheet::ParseExcel对象——后者是用来解析旧版.xls格式文件的,根本不支持.xlsx格式解析。 - 调用Parse方法解析.xlsx时失败返回
undef,你没有做返回值校验就直接访问对象属性,自然会触发未初始化值的警告,FILE、COUNT等属性输出为空。 - 额外问题:使用了老式的
new Class间接对象调用语法,容易引发隐式的类加载问题,不推荐使用。
正确实现方式
基础修复版(仅支持.xlsx格式)
#!/usr/bin/perl use strict; use warnings; use Spreadsheet::ParseXLSX; # 入参校验 die "Usage: $0 <xlsx_file_path>\n" unless @ARGV; my $file = $ARGV[0]; die "Error: File $file not exist or unreadable\n" unless -r $file; # 正确实例化XLSX解析器 my $parser = Spreadsheet::ParseXLSX->new(); my $workbook = $parser->parse($file); # 解析失败时直接抛出明确错误,不要继续执行 die "Parse xlsx failed: " . $parser->error() . "\n" unless defined $workbook; # 读取基础属性 print "FILE : $file\n"; print "SHEET COUNT : " . $workbook->sheet_count() . "\n"; my $props = $workbook->get_properties(); print "AUTHOR: " . $props->{author} . "\n" if defined $props->{author}; # 示例:遍历所有工作表读取单元格内容 for my $sheet_idx (0 .. $workbook->sheet_count()-1) { my $sheet = $workbook->worksheet($sheet_idx); print "\n=== Worksheet: " . $sheet->get_name() . " ===\n"; my ($row_start, $row_end) = $sheet->row_range(); my ($col_start, $col_end) = $sheet->col_range(); for my $row ($row_start .. $row_end) { for my $col ($col_start .. $col_end) { my $cell = $sheet->get_cell($row, $col); next unless $cell; print "[$row,$col] " . $cell->value() . "\n"; } } }
兼容版(同时支持.xls和.xlsx格式)
如果需要同时处理两种格式的Excel文件,可以通过文件后缀判断选择对应解析器,代码示例:
use strict; use warnings; use Spreadsheet::ParseExcel; use Spreadsheet::ParseXLSX; die "Usage: $0 <excel_file_path>\n" unless @ARGV; my $file = $ARGV[0]; die "File $file not readable\n" unless -r $file; my $parser; if ($file =~ /\.xlsx$/i) { $parser = Spreadsheet::ParseXLSX->new(); } elsif ($file =~ /\.xls$/i) { $parser = Spreadsheet::ParseExcel->new(); } else { die "Unsupported file format, only .xls and .xlsx are supported\n"; } my $workbook = $parser->parse($file); die "Parse failed: " . $parser->error() . "\n" unless defined $workbook; # 后续属性读取、单元格遍历逻辑和基础修复版完全一致
注意事项
- 永远不要省略解析结果的校验:文件加密、损坏、格式不匹配时
parse方法都会返回undef,跳过校验直接访问属性必然触发未初始化警告。 - 尽量避免使用
new Class的间接对象写法,统一使用Class->new()的构造方式,减少语法歧义引发的异常。 - Spreadsheet::ParseXLSX和Spreadsheet::ParseExcel的API接口完全兼容,解析完成后读取工作表、单元格的方法没有区别,不需要为不同格式写两套遍历逻辑。
内容的提问来源于stack exchange,提问作者Monica
相关产品推荐
相关产品推荐

