Hallo Leute,
Ich habe gesehen, dass einige von uns versuchen, eine Datei aus einer Ajax-Anfrage bereitzustellen. Nach einiger Recherche habe ich keine eindeutige Lösung dafür gefunden. Ich habe einige davon optimiert und erfolgreich CSV- und XLS-Daten aus einer Ajax-Anfrage exportiert. Die Sache ist, dass die Manipulation aufgrund der Codierung anders ist, wenn der Dateityp xls ist, also gibt es ein paar Optimierungen.
Die Daten stammen aus einer typischen Eloquent-Abfrage, konvertiert in 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: das ist kein problem
Vielen Dank, es funktioniert gut für CSV, aber nicht für xls.
Ich musste eine xlsx von ajax zurückgeben, also habe ich noch einmal ein wenig optimiert und das habe ich am Ende:
PHP
$data ist eine in Array konvertierte Eloquent-Abfrage.
$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);
}
});
Danke!!
Ich erhalte den Fehler "Klasse 'Excel' nicht gefunden". Können Sie mir bitte helfen?
@randomhoodie eine Quelle, wie Sie zu dieser Lösung gekommen sind?
@eldyvoon wie ich sagte, "ich habe die ursprüngliche Antwort optimiert", nimm weg, was ich nicht brauchte, mach es kompakt und duckduckgo (Suchmaschine) für den Mime-Typ der ms office xlsx-Erweiterung, ich war mir nicht sicher, ob es so war Ich werde funktionieren, bis ich es ausprobiert habe, aber ich habe es vor dem Posten versucht, und da es funktioniert hat, habe ich es gepostet, falls es jemand nützlich finden würde.
Ich fand, dass überhaupt kein Javascript oder Ajax benötigt wird. Ich habe eine Webseite mit Links zum Herunterladen verschiedener csv/xls/xlsx-Dateien und ich möchte nicht, dass die Seite aktualisiert wird. Alles, was ich getan habe, war, einen Link zu einer Aktion zu verbinden, die Folgendes zurückgab ...
öffentliche Funktion getSpreadsheet() {
$items = Item::all();
Excel::create('items', function($excel) use($items) {
$excel->sheet('ExportFile', function($sheet) use($items) {
$sheet->fromArray($items);
});
})->export('xls');
}
Wunder voll!!!!
Danke @randomhoodie!
Für das 3.x-Paket würde ich Ihr PHP mit etwas wie diesem aktualisieren , gemäß der
$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);
Danke @kynetiv , ich verwende Version 3.x, aber ich musste eine Erweiterung wie:
Wenn Sie dieses Problem im Jahr 2020 immer noch haben. Beachten Sie, dass sich die Version 3.x von Laravel Excel geändert hat. Hier ist die Lösung
Beispiel:
$exports = new ReportsExporter($data, $columns);
Excel::store($exports , 'filename.xlsx', 'custom_disk_location');
Definieren Sie Ihren benutzerdefinierten Festplattenspeicherort im Konfigurationsdateisystem wie folgt
'custom_disk_location' => [
'driver' => 'local',
'root' => public_path('files'),
],
...
Dadurch wird sichergestellt, dass die Excel-Datei nicht im Speicher / in der App gespeichert wird
speichert es aber im öffentlichen/Dateipfad auf Ihrem Server
zurück zu deinem Javascript, lade die Datei wie folgt herunter
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);
}
Rufen Sie die Download-Funktion auf, indem Sie den Dateinamen und den Pfad übergeben
download("Dateiname.xlsx", Standort.Ursprung+"Dateien/Dateiname.xlsx");
Denken Sie nach dem Download daran, zum Server zurückzukehren und den auf dem Server gespeicherten zu entfernen
unlink("files/filename.xlsx");
Ich hoffe, dies hilft jedem, der es schwer hat, Laravel-Excel über Ajax oder Javascript herunterzuladen.
Dies ist eine bessere Option, da Sie Ihre Benutzererfahrung flexibler anpassen können und
Geben Sie ihnen Feedback zum Status des Downloads und benennen Sie Ihre Datei nach Ihren Wünschen.
Ich musste eine xlsx von ajax zurückgeben, also habe ich noch einmal ein wenig optimiert und das habe ich am Ende:
PHP
$data ist eine in Array konvertierte Eloquent-Abfrage.$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); } });
Ich musste eine xlsx von ajax zurückgeben, also habe ich noch einmal ein wenig optimiert und das habe ich am Ende:
PHP
$data ist eine in Array konvertierte Eloquent-Abfrage.$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); } });
so gut
Hilfreichster Kommentar
Ich musste eine xlsx von ajax zurückgeben, also habe ich noch einmal ein wenig optimiert und das habe ich am Ende:
PHP
$data ist eine in Array konvertierte Eloquent-Abfrage.
js