mstdmstd's avatar

Downloaded csv file with maatwebsite/excel has no content

Hello, In laravel 5.8 I installed maatwebsite/excel and in my composer.json :

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.1.3",
        "fideloper/proxy": "^4.0",
        "intervention/image": "^2.4",
        "laracasts/utilities": "^3.0",
        "laravel/framework": "5.8.*",
        "laravel/tinker": "^1.0",
        "maatwebsite/excel": "^3.1",
    },
...

But trying to upload data from db convirted to array as :
        $searchResultRows = SearchResult
            ::getByUserList($user_list_id)
            ->get()
            ->toArray();

//        echo '<pre>!!!count($searchResultRows))::'.print_r(count($searchResultRows),true).'</pre>';
//        echo '<pre>$searchResultRows)::'.print_r($searchResultRows,true).'</pre>';
        return \Excel::download( function ($excel) use ($searchResultRows) {
            $excel->sheet('mySheet', function ($sheet) use ($searchResultRows) {
                $sheet->fromArray($searchResultRows);
            });
        }, 'file.csv');

I have file.csv uploade, but it has 3 bytes in syze and content :

""

If to uncomment 2 lines with searchResultRows output I see my valid rows as I expected. What is wrong and how to get valid csv file uploaded?

Thanks!

0 likes
9 replies
aurawindsurfing's avatar

Hi @mstdmstd

It looks like you are taking a big shortcut. Follow their documentation closely. For starters just have a look here:

https://docs.laravel-excel.com/3.1/exports/

You can see straight away that you are not having export class in the right namespace:

<?php

namespace App\Exports;

use App\User;
use Maatwebsite\Excel\Concerns\FromCollection;

class UsersExport implements FromCollection
{
    public function collection()
    {
        return User::all();
    }
}

So you are not sending to Excel::export what it expects to get. It should look something like this:

use App\Exports\UsersExport;
use Maatwebsite\Excel\Facades\Excel;
use App\Http\Controllers\Controller;

class UsersController extends Controller 
{
    public function export() 
    {
        return Excel::download(new UsersExport, 'users.xlsx');
    }
}

Hope it helps!

1 like
mstdmstd's avatar

Thank you,that works in case I run laravel control in GET request, but that is laravel 5.8 / axios "^0.18", "vue": "^2.5.17" app and running request the file is not downloaded at all. I run my request in JS code :

                axios({
                    method: ( 'post' ),
                    url: this.$store.getters.apiUrl + '/personal/run-user-list-export-to-csv',
                    data: { user_id : user_id, user_list_id: user_list_id },
                }).then((response) => {
                    this.showPopupMessage("User list export", "User list successfully exported !", 'success');
                }).catch((error) => {
                    this.showPopupMessage("User list export", 'Error exporting user\'s list !', 'error');
                });

with control :

    public function run_user_list_export_to_csv() // http://127.0.0.1:8000/api/run-user-list-export-to-csv
    {
        $request= request();
        ...
        
        $ret= \Excel::download(new exportSearchResults($user_list_id), 'file.csv');  // if write RETURN this line file is not downloaded anyway...
        return response()->json( ['error_code' => 1, 'message' => '', 'ret' => $ret, HTTP_RESPONSE_INTERNAL_SERVER_ERROR ] );
    } // public function storerun_user_list_export_to_csv(UserLisRequest $request)

I browser's responce I see output :

{"error_code":1,"message":"","ret":{"headers":{}},"0":500}

But file is not downloaded. How correctly?

aurawindsurfing's avatar

Well this is a different thing. Google how to download a file with vuejs :-)

1 like
mstdmstd's avatar

Thanks for your feedback, I searched and found this https://laracasts.com/discuss/channels/laravel/issue-with-laravel-response-download-and-axios-post with sample in last post and I make like :

    public function run_user_list_export_to_csv() 
    {
        $request= request();
        ...
        $filename= $title.'.csv';
        $download_path= $filename;
        $ret= \Excel::download(new exportSearchResults($user_list_id), $download_path);
        \Log::info($ret);
        $headers = ['Content-Type: application/csv','Content-Disposition: attachment; filename={$filename}'];

        return response($download_path, 200,$headers);
    } // public function storerun_user_list_export_to_csv(UserLisRequest $request)

I see in log file output :

[2019-06-14 04:46:23] local.INFO: HTTP/1.0 200 OK
Cache-Control:       public
Content-Disposition: attachment; filename="aaa Z3  iuy65 .csv"
Date:                Fri, 14 Jun 2019 04:46:23 GMT
Last-Modified:       Fri, 14 Jun 2019 04:46:23 GMT

But no file is downloaded. Which is the right way ?

aurawindsurfing's avatar

Maybe it is simply that strange filename that you are trying to create?

filename="aaa Z3  iuy65 .csv"
mstdmstd's avatar
  1. No, that different. Name of uploaded file must be based on item title, I just tried to exclude invalid chars from file, rendering "aa%a Z$3 & iuy_65 ^"=> "aaa Z3 iuy65 .csv"

  2. Method

\Excel::store( new exportSearchResults($user_list_id), $download_path, 'local' );

works, but file is saved in app/storage/app/home/user/Downloads/itemtitle.csv subdirectory when I set path:

  $download_path= '/home/user/Downloads/'.$filename;

But that is a bit different I need, as I would like to run browsers download method...

mstdmstd's avatar
  1. I generate csv file but failed to download it in browser's download method. This way seemed preferable to me. But I can move generated csv file to some directory(say /home/user/ ) and to open it in client's csv app.

  2. How can I with vue js to define name of current user and his download directory (bearing in mind that clients can have different OS)

mstdmstd's avatar

I found this https://github.com/ynishi/vuecsv plugin and tried to install it.

$ npm install ynishi/vuecsv

> [email protected] postinstall /mnt/_work_sdb8/wwwroot/lar/wiznext/msg-laravel-application/node_modules/core-js
> node scripts/postinstall || echo "ignore"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!

The project needs your help! Please consider supporting of core-js on Open Collective or Patreon: 
> https://opencollective.com/core-js 
> https://www.patreon.com/zloirock 

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)


> [email protected] postinstall /mnt/_work_sdb8/wwwroot/lar/wiznext/msg-laravel-application/node_modules/bootstrap-vue
> opencollective postinstall || exit 0


                                                                                          Thanks for installing bootstrap-vue 
                                                                                     Please consider donating to our open collective
                                                                                            to help us maintain this package.

                                                                                               Number of contributors: 227
                                                                                                  Number of backers: 31
                                                                                                   Annual budget: 4                                                                                                 
                                                                                                 Current balance: ,190                                                                                               
                                                                                                                                                                                                                       
                                                                             Donate: https://opencollective.com/bootstrap-vue/donate                                                                                   
                                                                                                                                                                                                                       
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})                                                      
                                                                                                                                                                                                                       
+ [email protected]                                                                                                                                                                                                        
added 44 packages from 32 contributors and audited 17038 packages in 87.476s                                                                                                                                           
found 1 high severity vulnerability
  run `npm audit fix` to fix them, or `npm audit` for details

The output above was somewhat unusaual, but was it just advirtisement. Next I run :

 npm audit fix
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

up to date in 8.632s
fixed 0 of 1 vulnerability in 17038 scanned packages
  1 vulnerability required manual review and could not be updated

After that package.json :

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },
    "devDependencies": {
        "axios": "^0.18",
        "bootstrap": "^4.0.0",
        "cross-env": "^5.1",
        "jquery": "^3.4.1",
        "laravel-mix": "^4.0.7",
        "lodash": "^4.17.5",
        "popper.js": "^1.12",
        "resolve-url-loader": "^2.3.1",
        "sass": "^1.15.2",
        "sass-loader": "^7.1.0",
        "vue": "^2.5.17",
        "vue-template-compiler": "^2.6.10"
    },
    "dependencies": {
        "cors": "^2.8.5",
        "remove": "^0.1.5",
        "v-tooltip": "^2.0.2",
        "vee-validate": "^2.2.5",
        "vee-validate-laravel": "^1.1.0",
        "vue-js-modal": "^1.3.31",
        "vue-moment": "^4.0.0",
        "vue-notification": "^1.3.16",
        "vue-router": "^3.0.6",
        "vue-select": "^3.1.0",
        "vue-slider-component": "^3.0.31",
        "vue2-filters": "^0.6.0",
        "vuecsv": "github:ynishi/vuecsv",
        "vuejs-paginate": "^2.1.0",
        "vuex": "^3.1.0"
    }
}

I tried to use this https://jsfiddle.net/ynishif/1ztu8x8q/ fiddle, But I Got error referenced at my file :

app.js?dt=1560770053:2823 Uncaught ReferenceError: VueCSV is not defined
    at Module../node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/components/Horizontal/personal/userLists/list.vue?

in /Horizontal/personal/userLists/list.vue:

<script>
    ... 
    import Vue from 'vue';
    Vue.component("csv-download", VueCSV.CsvDownload)

I am very confused as VueCSV is not defined anywhere, but it works if mentioned fiddle.

What did I miss?

mstdmstd's avatar

I tried to import vuecsv in my *.vue file and after installing of vuecsv.min.js I have /node_modules/vuecsv/dist/vuecsv.min.js file and in my vue file I tried to make like :

<script>

    import {bus} from '../../../../app';
    import appMixin from '../../../../appMixin';

    //import
    import VueCSV from '/vuecsv/dist/vuecsv.min.js';    // /node_modules/vuecsv/dist/vuecsv.min.js
    Vue.use(VueCSV);

    Vue.component("csv-download" , VueCSV.CsvDownload )

but in console I see error :

ERROR in ./resources/js/components/Horizontal/personal/userLists/list.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/components/Horizontal/personal/userLists/list.vue?vue&type=script&lang=js&)
Module not found: Error: Can't resolve '/vuecsv/dist/vuecsv.min.js' in '/mnt/_work_sdb8/wwwroot/lar/wiznext/msg-laravel-application/resources/js/components/Horizontal/personal/userLists'
 @ ./resources/js/components/Horizontal/personal/userLists/list.vue?vue&type=script&lang=js& (./node_modules/babel-loader/lib??ref--4-0!./node_modules/vue-loader/lib??vue-loader-options!./resources/js/components/Horizontal/personal/userLists/list.vue?vue&type=script&lang=js&) 124:0-48 127:8-14 132:30-36
 @ ./resources/js/components/Horizontal/personal/userLists/list.vue?vue&type=script&lang=js&
 @ ./resources/js/components/Horizontal/personal/userLists/list.vue
 @ ./resources/js/routes.js
 @ ./resources/js/app.js
 @ multi ./resources/js/app.js ./resources/sass/Horizontal/app.scss ./resources/sass/Horizontal/style_lg.scss ./resources/sass/Horizontal/style_md.scss ./resources/sass/Horizontal/style_sm.scss ./resources/sass/Horizontal/style_xs_320.scss ./resources/sass/Horizontal/style_xs_480.scss ./resources/sass/Horizontal/style_xs_600.scss

If i modify import line as :

    import VueCSV from 'vuecsv';    // /node_modules/vuecsv/dist/vuecsv.min.js

I see error in npm console :

This dependency was not found:

* Vue in ./node_modules/vuecsv/dist/vuecsv.min.js

To install it, you can run: npm install --save Vue

sure I have vue installed.

Which way is right? Can it be that this plugin is not working at? Can you propose similar ?

Please or to participate in this conversation.