jschlies's avatar

Using Laravel Excel to insert a Chart into an Excel Worksheet

PHP 8.4

    "laravel/framework": "^12.31",
    "laravel/sanctum": "^4.2",
    "laravel/ui": "^4.6",

May I please pointed to an example of a Worksheet Export that generates a spreadsheet with an embedded chart?

I presume this is the documentation I should be looking at. https://docs.laravel-excel.com/

The examples found here are throwing errors. https://docs.laravel-excel.com/3.1/exports/charts.html#charts

This snippet I found generates an empty chart or no chart at all.

0 likes
3 replies
jschlies's avatar
public function charts ()
{
    // Define data series values (replace with your actual data ranges)
    $dataSeriesLabels = [
        new DataSeriesValues('String', 'Worksheet!$B$1', null, 1), // Example label
    ];
    $xAxisTickValues  = [
        new DataSeriesValues('String', 'Worksheet!$B$2:$B$8', null, 2), // Example categories
    ];
    $dataSeriesValues = [
        new DataSeriesValues('Number', 'Worksheet!$C$2:$C$8', null, 7), // Example values
    ];

    // Create the data series
    $series = new DataSeries(
        DataSeries::TYPE_BARCHART, // Chart type
        DataSeries::GROUPING_CLUSTERED,
        range(0, count($dataSeriesValues) - 1),
        $dataSeriesLabels,
        $xAxisTickValues,
        $dataSeriesValues
    );

    // Create the plot area and legend
    $plotArea = new PlotArea(new Layout(), [$series]);
    $legend   = new Legend(Legend::POSITION_RIGHT, null, false);

    // Create the chart
    $chart = new Chart(
        'chart1', // Chart name
        null, // Title
        $legend,
        $plotArea,
        true, // plotVisibleOnly
        0, // displayBlanksAs
        null, // xAxisLabel
        null  // yAxisLabel
    );

    // Position the chart in the Excel sheet
    $chart->setTopLeftPosition('E1');
    $chart->setBottomRightPosition('L15');

    return [$chart];
}
Teddy-James's avatar

You might want to check the latest version examples or try using PhpSpreadsheet directly for chart support. Laravel Excel wraps it, but chart exports can be tricky. Some users generate the chart via PhpSpreadsheet, then pass it to Laravel Excel for the export.

imranbru's avatar

To resolve this issue in Laravel 12 using Laravel Excel, you must ensure your export class implements the WithCharts concern. The most common reason charts appear empty or fail to render is a mismatch between the Worksheet Name referenced in your DataSeriesValues and the actual title of the sheet.

Here is a clean, working example of a Chart Export:

namespace App\Exports;

use Maatwebsite\Excel\Concerns\FromCollection; use Maatwebsite\Excel\Concerns\WithCharts; use Maatwebsite\Excel\Concerns\WithTitle; use PhpOffice\PhpSpreadsheet\Chart\Chart; use PhpOffice\PhpSpreadsheet\Chart\DataSeries; use PhpOffice\PhpSpreadsheet\Chart\DataSeriesValues; use PhpOffice\PhpSpreadsheet\Chart\Legend; use PhpOffice\PhpSpreadsheet\Chart\PlotArea; use PhpOffice\PhpSpreadsheet\Chart\Title;

class SalesChartExport implements FromCollection, WithCharts, WithTitle { public function title(): string { return 'Report'; }

public function collection()
{
    return collect([
        ['Category', 'Values'],
        ['Ads', 450],
        ['Social', 300],
        ['Direct', 200],
        ['Search', 600],
    ]);
}

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

    $series = new DataSeries(
        DataSeries::TYPE_BARCHART,
        DataSeries::GROUPING_CLUSTERED,
        range(0, count($values) - 1),
        $label,
        $categories,
        $values
    );

    $plot   = new PlotArea(null, [$series]);
    $legend = new Legend(Legend::POSITION_RIGHT, null, false);
    $chart  = new Chart('SalesChart', new Title('Yearly Sales'), $legend, $plot);

    $chart->setTopLeftPosition('D2');
    $chart->setBottomRightPosition('L15');

    return $chart;
}

}

Please or to participate in this conversation.