Laravel-excel: Generate and export charts

Created on 22 Jun 2018  路  5Comments  路  Source: Maatwebsite/Laravel-Excel

Prerequisites

  • [ ] Able to reproduce the behaviour outside of your code, the problem is isolated to Laravel Excel.
  • [x] Checked that your issue isn't already filed.
  • [x] Checked if no PR was submitted that fixes this problem.

Versions

  • PHP version: 7.2.7
  • Laravel version: 5.6.24
  • Package version: 3.0.6

Description

I am trying to generate a simple demo chart in my code and export the exel file toghether with the chart, but I can't seem to find the documentation for doing such thing or if it even is or not supported.

Steps to Reproduce

Expected behavior:

Having a chart in my exel file, with the top left corner in C1.

Actual behavior:

The data is exported alright, but without the chart.

Additional Information

Here is the code I came up with, after reading some other issues and articles. I thought that the best place to try this was the AfterSheet event listener.

public function registerEvents(): array
{
    return [
        AfterSheet::class => function (AfterSheet $event) {
            $event->sheet->getDelegate()->getStyle('A1:B1')->applyFromArray(
                [
                    'font' => [
                        'bold' => true,
                        'color' => ['rgb' => 'ffffff'],
                    ],
                    'fill' => [
                        'fillType' => Fill::FILL_SOLID,
                        'color' => ['rgb' => 'c40809'],
                    ]
                ]
            );

            $label = [new DataSeriesValues('String', 'Worksheet!$B$1', null, 1)];
            $categories = [new DataSeriesValues('String', 'Worksheet!$B$2:$B$5', null, 4)];
            $values = [new DataSeriesValues('Number', 'Worksheet!$A$2:$A$5', null, 4)];

            $series = new DataSeries(DataSeries::TYPE_PIECHART, DataSeries::GROUPING_STANDARD,
                range(0, \count($values) - 1), $label, $categories, $values);
            $plot = new PlotArea(null, [$series]);

            $legend = new Legend();
            $chart = new Chart('chart name', new Title('chart title'), $legend, $plot);

            $chart->setTopLeftPosition('C1');
            $chart->setBottomRightPosition('F5');

            $event->sheet->getDelegate()->addChart($chart);
        },
    ];
}
help wanted

Most helpful comment

@Valdrinium Maatwebsite\Excel\Concerns\WithCharts concern is added. It will allow you to return the following:

/**
     * @return Chart|Chart[]
     */
    public function charts()
    {
        $label      = [new DataSeriesValues('String', 'Worksheet!$B$1', null, 1)];
        $categories = [new DataSeriesValues('String', 'Worksheet!$B$2:$B$5', null, 4)];
        $values     = [new DataSeriesValues('Number', 'Worksheet!$A$2:$A$5', null, 4)];

        $series = new DataSeries(DataSeries::TYPE_PIECHART, DataSeries::GROUPING_STANDARD,
            range(0, \count($values) - 1), $label, $categories, $values);
        $plot   = new PlotArea(null, [$series]);

        $legend = new Legend();
        $chart  = new Chart('chart name', new Title('chart title'), $legend, $plot);

        $chart->setTopLeftPosition('C1');
        $chart->setBottomRightPosition('F5');

        return $chart;
    }

All 5 comments

Did you import the AfterSheet::class correctly? For the rest it looks like it should work fine.

I did. Otherwise the type hinting would have thrown an error.

I think you have to set $writer->getDelegate()->setIncludeCharts(true);as well. You could use the BeforeWriting event for this.

Perhaps a good fit for a new concern WithCharts that would allow a chart instance (or multiple chart instances) to be returned. Feel free to create a PR for it.

@Valdrinium Maatwebsite\Excel\Concerns\WithCharts concern is added. It will allow you to return the following:

/**
     * @return Chart|Chart[]
     */
    public function charts()
    {
        $label      = [new DataSeriesValues('String', 'Worksheet!$B$1', null, 1)];
        $categories = [new DataSeriesValues('String', 'Worksheet!$B$2:$B$5', null, 4)];
        $values     = [new DataSeriesValues('Number', 'Worksheet!$A$2:$A$5', null, 4)];

        $series = new DataSeries(DataSeries::TYPE_PIECHART, DataSeries::GROUPING_STANDARD,
            range(0, \count($values) - 1), $label, $categories, $values);
        $plot   = new PlotArea(null, [$series]);

        $legend = new Legend();
        $chart  = new Chart('chart name', new Title('chart title'), $legend, $plot);

        $chart->setTopLeftPosition('C1');
        $chart->setBottomRightPosition('F5');

        return $chart;
    }
Was this page helpful?
0 / 5 - 0 ratings