我有一个包含许多列和行的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);
运行时我没有收到任何错误或警告,这对确定问题没有帮助。
任何人都可以识别出任何错误吗?
答案 0 :(得分:2)
首先,$ col是数字,所以你不应该对字符串列名进行测试。
其次,你需要例如。
<interactive>:5:52:
Could not deduce (Num (a -> a)) arising from a use of ‘+’
from the context (Ord a, Num a)
如你所知,它只是测试$ col eq&#39; A&#39; (因为这是所有||&#39;)的结果。
答案 1 :(得分:1)
你的考试
$col eq ( 'A' || 'S' || 'T' || 'AA' || 'AX' || 'BC' || 'D' || 'AN' || 'AV' )
找到第一个 true 的文本字符串,即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'
除了模块没有像那样处理列标签,所以你需要将它们转换为数字
我写过这个,应该有效。它首先构建一个哈希,它将每个列标签与前100列的数字相关联。然后我使用该哈希将您的标签列表转换为列号列表,并对其进行迭代。 (如果你感兴趣,它会产生[1, 4, 19, 20, 27, 40, 48, 50, 55]
。)它比迭代所有列并忽略你不想要的那些更加整洁
它没有经过测试,因为我没有要测试的数据文件,但它确实编译了
如果代码包含 false 值,则我不能确定跳过单元格的代码。这将跳过空单元格和包含数字零的单元格,这将导致CSV文件中的列未对齐。我的代码部分是@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/ A S T 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;