所以,把我相当冗长的评论变成一个答案。
Excel::Writer::XLSX 中似乎缺少某些内容。
如果您在 Excel 的图表属性窗口中查看您的 XLSX 文件,您会注意到填充颜色为“蓝色”,但边框设置为“无”。这很好,但是您没有注意到它,因为您看不到边框丢失或者它是否与填充颜色相同。
无论如何,填充似乎不起作用。我检查了 Excel::Writer::XLSX 生成的 XLSX 存档中的 chart.xml,并将其与我在 Excel 中将其更改为“无填充”并保存的文件进行了比较。Excel 创建了很多开销,但归结为:
<!-- Perl -->
<c:spPr>
<a:solidFill></a:solidFill>
<a:ln>
<a:noFill />
</a:ln>
</c:spPr>
<!-- after Excel -->
<c:spPr>
<a:noFill/>
<a:ln>
<a:noFill/>
</a:ln>
</c:spPr>
我们可以清楚地看到应该有一个noFill
元素。
现在如果我们看一下Excel::Writer::XLSX::Chart中的代码,有一个方法叫做_write_sp_pr
. 这使图表变得有意义。它依次调用两种方法,一种用于线条,一种用于填充。
# Write the a:solidFill element for solid charts such as pie and bar.
if ( $series->{_fill}->{_defined} ) {
$self->_write_a_solid_fill( $series->{_fill} );
}
# Write the a:ln element.
if ( $series->{_line}->{_defined} ) {
$self->_write_a_ln( $series->{_line} );
}
第二个,_write_a_ln
,负责none => 1
:
sub _write_a_ln {
# [...]
# Write the line fill.
if ( $line->{none} ) {
# Write the a:noFill element.
$self->_write_a_no_fill();
}
# [...]
}
这很棒。所以没有线。但是填充颜色的检查在哪里?
sub _write_a_solid_fill {
my $self = shift;
my $line = shift;
$self->{_writer}->startTag( 'a:solidFill' );
if ( $line->{color} ) {
my $color = $self->_get_color( $line->{color} );
# Write the a:srgbClr element.
$self->_write_a_srgb_clr( $color );
}
$self->{_writer}->endTag( 'a:solidFill' );
}
事实证明,没有。如果没有设置颜色,则省略。但这会导致 Excel 使用默认颜色,它必须是蓝色。
要为您解决此问题,请尝试以下monkeypatch。将这些内容添加到创建带有图表的 XLSX 文件的程序的顶部。它会处理不填充的问题。它是_write_sp_pr
原始模块代码的完整子代码,并混合了一些附加逻辑。
use Excel::Writer::XLSX;
{
no warnings 'redefine';
sub Excel::Writer::XLSX::Chart::_write_sp_pr {
my $self = shift;
my $series = shift;
if ( !$series->{_line}->{_defined} and !$series->{_fill}->{_defined} ) {
return;
}
$self->{_writer}->startTag( 'c:spPr' );
# Write the a:solidFill element for solid charts such as pie and bar.
if ( $series->{_fill}->{_defined} ) {
# Check if a noFill element is needed
if ( $series->{_fill}->{none} ) {
# Write the a:noFill element.
$self->_write_a_no_fill();
} else {
# Write the line fill.
$self->_write_a_solid_fill( $series->{_fill} );
}
}
# Write the a:ln element.
if ( $series->{_line}->{_defined} ) {
$self->_write_a_ln( $series->{_line} );
}
$self->{_writer}->endTag( 'c:spPr' );
}
}
这里有更多代码可以快速尝试:
use strict; use warnings;
#### put above code here
# Create a new Excel workbook
my $workbook = Excel::Writer::XLSX->new( 'perl.xlsx' );
# Add a worksheet
my $worksheet = $workbook->add_worksheet();
foreach my $row (0 .. 9) {
foreach my $col (0 .. 4) {
$worksheet->write($row, $col, $row+1);
}
}
my $chart = $workbook->add_chart( type => 'bar' );
$chart->add_series(
categories => [ 'Sheet1', 1, 5, 0, 0 ],
values => [ 'Sheet1', 1, 5, 3, 3 ],
name => 'Waiting_time',
fill => { none => 1 },
border => { color => 'red' },
);
当然,这只是一个快速而肮脏的解决方案。我建议为该模块编写一个错误报告,并将此问题/答案用作作者的参考。