将.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'(因为这是所有||的结果)。