Laravel-excel: [QUESTION] Use existing file as a template to append new data before export

Created on 22 Feb 2019  ·  5Comments  ·  Source: Maatwebsite/Laravel-Excel

Prerequisites

Versions

  • PHP version: 7.2
  • Laravel version: 5.7
  • Package version: 3.1

Description

I'm trying to edit an existing file to use as a template. I now that for this version, this function is not developed to use easily. But I would like to know if using the functions inside the plugin and playing with the function resisterEvents() I could do it by myself.

I got to download an existing file and select a sheet. But not to edit it.

This is my code:

    /**
     * @return array
     */
    public function registerEvents(): array
    {
        return [
            BeforeWriting::class  => function(BeforeWriting $event) {
                $event->writer->reopen(storage_path('app/public/files/mytemplate.xlsx'),Excel::XLSX);
                $event->writer->getSheetByIndex(0);
                return $event->getWriter()->getSheetByIndex(0);
            }
        ];
    }

Some suggestions?

Many thanks

Additional Information

I tried to add info in a value with this code inside the function resisterEvents() and doesn't work:

AfterSheet::class => function(AfterSheet $event) {
       $event->sheet->setCellValue('G2', 'Hello world');
}

And also to append data through function query()

question

Most helpful comment

->reopen() is an internal method and should be used with caution. You can probably work around it by passing new LocalTemporaryFile(storage_path('app/public/files/mytemplate.xlsx')) to reopen.

Editing existing files (templates) is on our roadmap (version 3.3), but without a specific release date.

If you need it on priority, please have a look at our Commercial Support section: https://laravel-excel.com/commercial-support .

All 5 comments

Finally this worked for me on version 3.1.0. In the actual version 3.1.10 this doesn't work because reopen function has changed. Waiting for new updates and improvements of editing an existing file.

->reopen() is an internal method and should be used with caution. You can probably work around it by passing new LocalTemporaryFile(storage_path('app/public/files/mytemplate.xlsx')) to reopen.

Editing existing files (templates) is on our roadmap (version 3.3), but without a specific release date.

If you need it on priority, please have a look at our Commercial Support section: https://laravel-excel.com/commercial-support .

Thanks for this quick answer.

I will try this way.

This is not a priority right now but I'm testing because I will need to add data to an existing excel with macros and dynamic tables, adding data and recalculating excel formulas. I'm trying all of this because I know this is not easy to do with a complex excel.

If I find out something good I will report you

In case of an update please comment as soon as possible

Hello, @MarFelix. I was facing same problem and now I have a workaround that I'm using. This may help you.
I digged deep in Mattwebsite code to understand how the export is done. So remember this steps that is used to download the file:

  1. Call Excel class passing your Export class (this example is using download method)
  2. The Excel class identify which Writer should be used and call the export method in this Writer.
  3. The Writer open your Export (and call BeforeExport event), then populate a NEW sheet, then call its own write method.
  4. The write method (Writer class) will call the BeforeWriting event and write on file for others types than XLSX

So that's why the BeforeWriting don't work, and if you use it on BeforeExport it will work but in a NEW sheet.

To workaround I add a flag on the method to get the export data (in my case FromCollection). This way it will not be process on step 2. Then, on BeforeWriting I mark the flag, get the wanted sheet and call the export method on it.

That's the code:

public function collection()
{
    if ($this->calledByEvent) { // flag
        return $this->myCollectionToExport;
    }

    return collect([]);
}

public function registerEvents(): array
{
    return [
        BeforeWriting::class => function(BeforeWriting $event) {
            $templateFile = new LocalTemporaryFile(storage_path('app/public/files/mytemplate.xlsx'));
            $event->writer->reopen($templateFile, Excel::XLSX);
            $event->writer->getSheetByIndex(0);

            $this->calledByEvent = true; // set the flag
            $event->writer->getSheetByIndex(0)->export($event->getConcernable()); // call the export on the first sheet

            return $event->getWriter()->getSheetByIndex(0);
        },
    ];
}

Take a look on download and write methods of Maatwebsite\Excel\Writer, it will be very helpfull.

With this information and steps, it would be possible to create a more complex workaround.

Was this page helpful?
3 / 5 - 1 ratings

Related issues

disto picture disto  ·  3Comments

octoxan picture octoxan  ·  3Comments

ellej16 picture ellej16  ·  3Comments

lucatamtam picture lucatamtam  ·  3Comments

pamekar picture pamekar  ·  3Comments