我创建了一个包含堆积条形图的Excel工作表。 现在我想在第一个栏中没有颜色,但它仍然是蓝色的。 代码如下所示:
$chart->add_series(
categories => [ 'Sheet1', 1, $counter, 0, 0 ],
values => [ 'Sheet1', 1, $counter, 3, 3 ],
name => 'Waiting_time',
fill => { none => 1 },
border => { none => 1 },
);
的0.5版本
感谢您的帮助。
答案 0 :(得分:1)
所以,把我相当冗长的评论变成答案。
如果在Excel的图表属性窗口中查看XLSX文件,您会注意到填充颜色为“蓝色”,但边框设置为“无”。这很好,但你没有注意到它,因为你看不到边框丢失或者它与填充颜色相同。
无论如何,填充似乎不起作用。我检查了Excel :: Writer :: XLSX生成的XLSX存档中的chart.xml,并将其与我在Excel中将其更改为“no fill”并保存的地方进行了比较。 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' },
);
当然,这只是一个快速而肮脏的解决方案。我建议为该模块编写一个错误报告,并将此问题/答案作为作者的参考。
答案 1 :(得分:0)
正如@simbabque所说,这是一个错误。
我已经在Github(commit f4e4191e)的主分支上修复了它。
计划在0.51发布,可能会在接下来的两周内发布。
更新:在Excel :: Writer :: XLSX版本0.51中修复。