将.XLSX电子表格转换为CSV的代码不能按预期工作

我有一个Excel电子表格,包含许多列和行。 我想把它变成一个CSV,但只包含CSV中的某些列。

这是我的代码:

#!/usr/bin/perl use strict; use warnings; use Spreadsheet::ParseXLSX; use Excel::Writer::XLSX; my $excel = Spreadsheet::ParseXLSX -> new(); my $workbook = $excel->parse('headers.xlsx'); my $worksheet = $workbook->worksheet(0); my $destination = 'csv.txt'; my $csv; my ($row_min, $row_max) = $worksheet->row_range(); my ($col_min, $col_max) = $worksheet->col_range(); for my $row ( $row_min .. $row_max ) { for my $col ( $col_min .. $col_max ) { # my $cell = $worksheet>{Cells}[$row][$col]; my $cell = $worksheet->get_cell( $row, $col ); if ($cell) { if ($col eq ( 'A' || 'S' || 'T' || 'AA' || 'AX' || 'BC' || 'D' || 'AN' || 'AV' )) { if ($col == $col_max) { $csv .= $cell->Value . "\n"; } else { $csv .= $cell->Value . ","; } } } } } open (my $fh, '>', $destination) or die '$! error trying to write'; print $fh $csv; close ($fh); 

当我运行它时,我没有得到任何错误或警告,这无助于确定问题。

任何人都可以识别任何错误

你的testing

 $col eq ( 'A' || 'S' || 'T' || 'AA' || 'AX' || 'BC' || 'D' || 'AN' || 'AV' ) 

find第一个是真正的文本string,即A ,并将其与$col进行比较,这不是你想要的。 你将不得不写

 $col eq 'A' || $col eq 'S' || $col eq 'T' || $col eq 'AA' || $col eq 'AX' || $col eq 'BC' || $col eq 'D' || $col eq 'AN' || $col eq 'AV' 

除了该模块不处理这样的列标签,所以你需要将它们转换为数字

我已经写了,这应该工作。 它首先构build一个散列,将每个列标签与前100列的数字相关联。 然后我用这个散列把你的标签列表转换成一个列号列表,然后迭代它。 (如果你感兴趣的话[1, 4, 19, 20, 27, 40, 48, 50, 55]它会产生[1, 4, 19, 20, 27, 40, 48, 50, 55] 。)它比遍历所有列更加整洁,而忽略了你不想要的列

它没有testing,因为我没有数据文件来testing,但它确实编译

我不太确定你的代码是否跳过一个单元格,如果它包含一个错误的值。 这将跳过包含数字零的空单元格和单元格,并且会导致CSV文件中的列未alignment。 我的代码部分是@csv_row = grep $_, @csv_row ,如果你同意我的意见,你可能想删除它

 #!/usr/bin/perl use strict; use warnings; use Spreadsheet::ParseXLSX; my ($source, $dest) = qw/ headers.xlsx headers.csv /; my $excel = Spreadsheet::ParseXLSX->new; my $workbook = $excel->parse($source); my $worksheet = $workbook->worksheet(0); my ($row_min, $row_max) = $worksheet->row_range; my %col_numbers; for ( my ($n, $name) = (1, 'A'); $n <= 100; ++$n, ++$name ) { $col_numbers{$name} = $n; } my @cols = sort { $a <=> $b } map $col_numbers{$_}, qw/ AST AA AX BC D AN AV /; open my $fh, '>', $dest or die qq{Unable to open "$dest" for output: $!}; for my $row ( $row_min .. $row_max ) { my @csv_row = map $worksheet->get_cell($row, $_)->unformatted, @cols; print $fh join(',', @csv_row), "\n"; } close $fh; 

首先,$ col是数字,所以你不应该对string列名进行testing。

其次,你需要例如

 $col==7 || $col==9 ||... 

如你所知,它只是testing$ col eq'A'(因为这是所有||的结果)。