Laravel-excel: Cara: menyimpan file csv/xls hanya menggunakan ajax

Dibuat pada 14 Jul 2016  ·  12Komentar  ·  Sumber: Maatwebsite/Laravel-Excel

Halo kawan-kawan,

Saya telah melihat bahwa beberapa dari kita mencoba menyajikan file dari permintaan ajax. Setelah beberapa penelitian, saya tidak menemukan solusi yang jelas untuk melakukannya. Tweak beberapa dari mereka, saya berhasil mengekspor data csv dan xls dari permintaan Ajax. Masalahnya, manipulasi berbeda jika tipe file adalah xls, karena pengkodean, jadi ada sedikit penyesuaian.

Data berasal dari kueri Eloquent yang khas, dikonversi ke Array:

PHP

if(!empty(Input::get('exportType'))) { //i use a custom get parameter here
            $dd = Excel::create('testFileName', function($excel) use ($data) {
                $excel->sheet('testSheetName', function($sheet) use ($data) {
                    $sheet->fromArray($data->get()->toArray());
                });
                $excel->setTitle($filename);
                $excel->setLastModifiedBy(Carbon::now()->toDayDateTimeString()); //updated has Carbon::now() only now throw exception on vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5.php l847 strlen()
            });

            //tweak for serving XLS file from ajax (or go trough download() Excel method for csv files)
            if(Input::get('exportType') == 'xls') {
                $dd = $dd->string();
                $response =  array(
                    'filename' => 'testFileName', //as we serve a custom response, HTTP header for filename is not setted by Excel. From the JS, you need to retrieve this value if type is XLS to set filename
                    'file' => "data:application/vnd.ms-excel;base64,".base64_encode($dd)
                );
                return response()->success($response); //do a json encode
            } else {
                //direct use of Excel download method for non-xls files - xls files need special JS treatment
                $dd->download(Input::get('exportType')); //not XLS, so CSV (didnt tried xlsx, pdf is blank but not sure it's related to this)
            }
            die; //prevent malformed binary data stream, not sure if needed
        }

JS

$.ajax({
      cache: false,
      url: url, //GET route 
      responseType: 'ArrayBuffer', //not sure if needed
      data:  exportParam, //exportType parameter here
      success: function (data, textStatus, request) {

//you could need to decode json here, my app do it automaticly, use a try catch cause csv are not jsoned

        //already json decoded? custom return from controller so format is xls
        if(jQuery.isPlainObject(data)) {
          data = data.data; //because my return data have a 'data' parameter with the content
        }

        //V1 - http://stackoverflow.com/questions/35378081/laravel-excel-using-with-ajax-is-not-working-properly
        //+V3 - http://stackoverflow.com/questions/27701981/phpexcel-download-using-ajax-call
        var filename = "";
        var disposition = request.getResponseHeader('Content-Disposition');
        if (disposition && disposition.indexOf('attachment') !== -1) {
          var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
          var matches = filenameRegex.exec(disposition);
          if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
        }
        if(!jQuery.isPlainObject(data)) { //is CSV - we use blob
           var type = request.getResponseHeader('Content-Type');
           var blob = new Blob([data], { type: type ,endings:'native'});
           var URL = window.URL || window.webkitURL;
           var downloadUrl = URL.createObjectURL(blob);
        }
        var a = document.createElement("a");
        a.href = jQuery.isPlainObject(data) ? data.file : downloadUrl; 
        a.download = jQuery.isPlainObject(data) ? data.filename : filename;
        document.body.appendChild(a);
        a.click();
        a.remove();
      },
      error: function (ajaxContext) {
        toastr.error('Export error: '+ajaxContext.responseText);
      }
    });

ps: ini bukan masalah

Komentar yang paling membantu

Saya perlu mengembalikan xlsx dari ajax, jadi saya mengubah sedikit lagi dan inilah yang saya dapatkan:

PHP
$data adalah kueri Eloquent yang dikonversi ke Array.

$myFile= Excel::create("filename", function($excel) use($data) {
   $excel->setTitle('title');
   $excel->sheet('sheet 1', function($sheet) use($data) {
     $sheet->fromArray($data, null, 'A1', true, true);
   });
});

$myFile = $myFile->string('xlsx'); //change xlsx for the format you want, default is xls
$response =  array(
   'name' => "filename", //no extention needed
   'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($myFile) //mime type of used format
);
return response()->json($response);

js

$.ajax({
      cache: false,
      url: url, //GET route 
      data:  params, //your parameters data here
      success: function (response, textStatus, request) {
        var a = document.createElement("a");
        a.href = response.file; 
        a.download = response.name;
        document.body.appendChild(a);
        a.click();
        a.remove();
      },
      error: function (ajaxContext) {
        toastr.error('Export error: '+ajaxContext.responseText);
      }
    });

Semua 12 komentar

Terima kasih banyak ini berfungsi baik untuk CSV tetapi tidak untuk xls ,

Saya perlu mengembalikan xlsx dari ajax, jadi saya mengubah sedikit lagi dan inilah yang saya dapatkan:

PHP
$data adalah kueri Eloquent yang dikonversi ke Array.

$myFile= Excel::create("filename", function($excel) use($data) {
   $excel->setTitle('title');
   $excel->sheet('sheet 1', function($sheet) use($data) {
     $sheet->fromArray($data, null, 'A1', true, true);
   });
});

$myFile = $myFile->string('xlsx'); //change xlsx for the format you want, default is xls
$response =  array(
   'name' => "filename", //no extention needed
   'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($myFile) //mime type of used format
);
return response()->json($response);

js

$.ajax({
      cache: false,
      url: url, //GET route 
      data:  params, //your parameters data here
      success: function (response, textStatus, request) {
        var a = document.createElement("a");
        a.href = response.file; 
        a.download = response.name;
        document.body.appendChild(a);
        a.click();
        a.remove();
      },
      error: function (ajaxContext) {
        toastr.error('Export error: '+ajaxContext.responseText);
      }
    });

Terima kasih!!

saya mendapatkan kesalahan "Kelas 'Excel' tidak ditemukan". Bisakah Anda membantu saya?

@randomhoodie sumber apa saja bagaimana Anda mendapatkan solusi itu?

@eldyvoon seperti yang saya katakan, "Saya mengubah" jawaban asli, mengambil apa yang tidak saya butuhkan, membuatnya ringkas, dan duckduckgo (mesin pencari) untuk jenis mime ekstensi ms office xlsx, saya tidak yakin itu akan bekerja sampai saya mencobanya, tetapi saya mencobanya sebelum memposting, dan karena berhasil saya mempostingnya, kalau-kalau ada yang menganggapnya berguna.

Saya menemukan bahwa tidak ada javascript atau ajax yang diperlukan sama sekali. Saya memiliki halaman web dengan tautan untuk mengunduh banyak file csv/xls/xlsx yang berbeda dan saya tidak ingin halaman itu menyegarkan sama sekali. Yang saya lakukan hanyalah menghubungkan tautan ke tindakan yang mengembalikan yang berikut ...

fungsi publik getSpreadsheet() {
$barang = Barang::semua();
Excel::create('items', function($excel) use($items) {
$excel->sheet('ExportFile', function($sheet) use($items) {
$sheet->fromArray($items);
});
})->ekspor('xls');
}

Luar biasa!!!!

Terima kasih @randomhoodie!

Untuk paket 3.x, saya akan memperbarui PHP Anda dengan sesuatu seperti ini, sesuai dengan panduan peningkatan :

        $myFile = Excel::raw(new YOUR_Export_Class, \Maatwebsite\Excel\Excel::XLSX);

        $response =  array(
           'name' => "filename", //no extention needed
           'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($myFile) //mime type of used format
        );

        return response()->json($response);

Terima kasih @kynetiv , saya menggunakan versi 3.x, tetapi saya perlu menambahkan ekstensi seperti: filename.xlsx

Jika Anda masih mengalami masalah ini pada tahun 2020. Perhatikan bahwa versi 3.x dari Laravel excel telah berubah jadi inilah solusinya

  1. Kirim data Anda melalui Ajax ke pengontrol Anda yang berinteraksi dengan Objek Laravel Excel
  2. Biarkan objek excel Laravel mengirim data Anda ke tampilan blade
  3. Simpan tampilan blade di server
  4. gunakan js untuk mengunduh file di server.
    Jadi idenya adalah mengekspor tampilan blade sebagai excel dan menyimpannya di lokasi disk tempat Anda dapat mengunduhnya
    javascript.

Contoh:

 $exports = new ReportsExporter($data, $columns);
  Excel::store($exports , 'filename.xlsx', 'custom_disk_location');

tentukan lokasi disk khusus Anda di sistem file konfigurasi seperti ini

'custom_disk_location' => [
            'driver' => 'local',
            'root' => public_path('files'),
        ],
...

ini akan memastikan file excel tidak disimpan di penyimpanan/aplikasi
tetapi akan menyimpannya di jalur publik/file di server Anda

kembali ke javascript Anda, unduh file seperti ini

function download(filename, path) {
        let element = document.createElement('a');
        element.setAttribute('href', path);
        element.setAttribute('download', filename);

        element.style.display = 'none';
        document.body.appendChild(element);

        element.click();

        document.body.removeChild(element);
    }

panggil fungsi unduh dengan meneruskan nama file dan jalur
download("namafile.xlsx", lokasi.asal+"file/namafile.xlsx");

setelah download ingat untuk kembali ke server dan hapus yang tersimpan di server seperti ini
unlink("file/namafile.xlsx");

Saya harap ini membantu siapa pun yang kesulitan mengunduh laravel-excel melalui ajax atau javascript.
Ini adalah opsi yang lebih baik karena memberi Anda lebih banyak fleksibilitas untuk menyesuaikan pengalaman pengguna Anda dan
beri mereka umpan balik mengenai status unduhan serta beri nama file Anda seperti yang Anda suka.

Saya perlu mengembalikan xlsx dari ajax, jadi saya mengubah sedikit lagi dan inilah yang saya dapatkan:

PHP
$data adalah kueri Eloquent yang dikonversi ke Array.

$myFile= Excel::create("filename", function($excel) use($data) {
   $excel->setTitle('title');
   $excel->sheet('sheet 1', function($sheet) use($data) {
     $sheet->fromArray($data, null, 'A1', true, true);
   });
});

$myFile = $myFile->string('xlsx'); //change xlsx for the format you want, default is xls
$response =  array(
   'name' => "filename", //no extention needed
   'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($myFile) //mime type of used format
);
return response()->json($response);

js

$.ajax({
      cache: false,
      url: url, //GET route 
      data:  params, //your parameters data here
      success: function (response, textStatus, request) {
        var a = document.createElement("a");
        a.href = response.file; 
        a.download = response.name;
        document.body.appendChild(a);
        a.click();
        a.remove();
      },
      error: function (ajaxContext) {
        toastr.error('Export error: '+ajaxContext.responseText);
      }
    });

Saya perlu mengembalikan xlsx dari ajax, jadi saya mengubah sedikit lagi dan inilah yang saya dapatkan:

PHP
$data adalah kueri Eloquent yang dikonversi ke Array.

$myFile= Excel::create("filename", function($excel) use($data) {
   $excel->setTitle('title');
   $excel->sheet('sheet 1', function($sheet) use($data) {
     $sheet->fromArray($data, null, 'A1', true, true);
   });
});

$myFile = $myFile->string('xlsx'); //change xlsx for the format you want, default is xls
$response =  array(
   'name' => "filename", //no extention needed
   'file' => "data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,".base64_encode($myFile) //mime type of used format
);
return response()->json($response);

js

$.ajax({
      cache: false,
      url: url, //GET route 
      data:  params, //your parameters data here
      success: function (response, textStatus, request) {
        var a = document.createElement("a");
        a.href = response.file; 
        a.download = response.name;
        document.body.appendChild(a);
        a.click();
        a.remove();
      },
      error: function (ajaxContext) {
        toastr.error('Export error: '+ajaxContext.responseText);
      }
    });

sangat baik

Apakah halaman ini membantu?
0 / 5 - 0 peringkat