2

我创建了一个包含堆叠条形图的 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 版的Excel::Writer::XLSX

谢谢你的帮助。

4

2 回答 2

1

所以,把我相当冗长的评论变成一个答案。

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' },
);

当然,这只是一个快速而肮脏的解决方案。我建议为该模块编写一个错误报告,并将此问题/答案用作作者的参考。

于 2012-09-12T12:48:43.473 回答
0

正如@simbabque 所说,这是一个错误。

我已经在 Github 的 master 分支上修复了它(commit f4e4191e)。

它计划在未来 2 周内发布 0.51 版本。

更新:在 Excel::Writer::XLSX 的 0.51 版中已修复。

于 2012-09-12T23:06:49.283 回答