isaackearl's avatar

Cannot download Excel files... (maatwebsite) even though they generate fine.

Hello!

I'm having serious trouble downloading files that I've generated. Right now I'm using maatwebsite/laravel-excel to generate excel docs and everything works great until I try and download the file!

Here is the function I created that generates my file:

public function generateFileForInvoice($withholdingInvoice)
    {
        /** @var LaravelExcelWriter $file */
        $file = Excel::create($withholdingInvoice->name, function ($excel) use ($withholdingInvoice) {

            /** @var LaravelExcelWriter $excel */
            $excel->sheet('Withholdings', function ($sheet) use ($withholdingInvoice) {
                /** @var \Maatwebsite\Excel\Excel $sheet */
                $sheet->loadView('withholding.invoice', ['withholdingInvoice' => $withholdingInvoice]);
            });

            $excel->sheet('Totals', function ($sheet) use ($withholdingInvoice) {
                /** @var \Maatwebsite\Excel\Excel $sheet */
                $sheet->loadView('withholding.totals', ['withholdingInvoice' => $withholdingInvoice]);
            });

        });

        $file->store('xls')->download();
    }

When I hit my endpoint it download a file but it is all garbled and busted and what not.

The crazy part is that the file that gets generated looks perfect if I just open it from the file system where i store it (developing locally).

This has lead me to believe that my headers are messed up or something but I'm fairly certain they are all correct.. this is what I have:

Cache-Control:cache, must-revalidate
Connection:keep-alive
Content-Disposition:attachment; filename="1_2017-01-01.xls"
Content-Type:application/vnd.ms-excel; charset=UTF-8
Date:Fri, 13 Jan 2017 08:27:05 GMT
Expires:Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified:Fri, 13 Jan 2017 08:27:05
Pragma:public
Server:nginx/1.10.0 (Ubuntu)
Transfer-Encoding:chunked

I've been messing with this stuff trying to get it to work for awhile now and any help would be appreciated. Another tactic I'm trying is to use the built in laravel function for downloading the file...

        return response()->download($filePath, $filename, $headers);

So I know the file is already generated properly.. I just need to figure out a way to download it through browser where it won't be garbled...

As you can see I can pass in custom headers etc so any tips would be appreciated.

Thanks!

0 likes
14 replies
bobbybouwmann's avatar

Not completely sure but seems you can either save or download the file: http://www.maatwebsite.nl/laravel-excel/docs/export#export

So indeed the best option is to store the file locally and then use a download response to download the file. For downloading this the file you can either use this

// Opens the file in the browser by simply returning the file.

return response()->file($path);

Or this

// Returns a download response using the correct headers.

return response()->download($path, $filename);
isaackearl's avatar

@bobbybouwmann

Yes I've switched to that now but I actually get the exact same result. I should have been more clear.

koerel's avatar

I have this code:

    public function exportExcel()
    {
        $users = $this->getAllUsers();
        Excel::create('user-export', function ($excel) use ($users) {
            $excel->sheet('Users', function ($sheet) use ($users) {
                $sheet->loadView('xls.users', [
                    'users' => $users
                ]);
            });
        })->download();
    }

When I send a normal GET request, it downloads just fine. I have :

 "name": "maatwebsite/excel",
 "version": "v2.0.10",

The only difference seems to be that I don't use the store method before the download method. Maybe give that a try?

isaackearl's avatar

@craigpaul

I have made a web endpoint GET request... which downloads the file, but when I open it, it is garbled.

@koerel

yes I gave that a try and it does the download only but it is still garbled the same way.

I've tried simplifying my file and I've realized that it literally doesn't seem to matter what file I generate.. it is messed up every time (the file is fine on the local filesystem, but if I try and download it then it is borked).

update

So I managed to finally get a working file... However I don't understand the solution and I would rather it work normally like it does for everyone else.

I added ob_end_clean right before the download.. and this works whether I use laravel's response()->download($filePath)... or if I use laravel-excel's ->download() command.

// I don't know why I need this or if it screws other things up...
ob_end_clean();  
return response()->download($filePath, $filename, $headers);

I have no idea why this suddenly works now, but if I could avoid using this then that would be great.

as a side note I have this in composer.json

        "maatwebsite/excel": "^2.1",

here is a website where someone else had the same issue and used ob_end_clean to fix it... http://simpledeveloper.com/how-to-fix-laravel-response-image-download-in-laravel/

If anybody knows how I can fix this without the workaround let me know.. thanks!

koerel's avatar

Are you by any chance 'echo'ing or 'var_dump'ing anything between the request and the response? That might cause your issue...

isaackearl's avatar

@koerel Good thought. I checked to make sure, and there aren't any.

I've read some threads about it being trailing whitespace in a configuration file after <?php or something, but they seem fine to me.

Dan's avatar

@isaackearl I know this is probably the least helpful answer here, but have you tried exporting an xlsx file instead of xls. I ran into issues where the file i was exporting was corrupted on load into Excel, however simply changing the exported file type fixed it all!

isaackearl's avatar

@Dan I appreciate the suggestion, however I have already tried this. Thank you though!

I have a workaround for now.. until I can figure out the real reason why it fails for me. I just put this before the download:

ob_end_clean();  

and everything works fine... However I don't like using something that seems like a workaround for a problem elsewhere in my code... So I'm hoping Ill eventually figure out what the issue is.

2 likes
devopsamit's avatar

one of the major reason i found is if request is called via ajax or vue..it will store the excel file in storage/frameworks/cache/laravel excel..in this case we need to call via axios for files to be downloaded..

1 like

Please or to participate in this conversation.