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
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
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
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.
js