IT-Swarm.Net

Rufen Sie die Excel-Datei (.xlsx) aus der Serverantwort in ajax ab

Ich habe ein Problem mit dem Abrufen der Excel-Datei und dem Öffnen des Download-Fensters im Browser, nachdem eine Antwort (in success ajax method) mit dieser Datei erhalten wurde. Ich habe den passenden Content-Type and Content-Disposition headers, ich habe versucht, Blob in js zu verwenden, und konnte nicht das erreichen, was ich will - einfaches Herunterladen von Dateien.
Ich habe einige Versionen meines Ajax fertiggestellt, eine davon ist unten. Ich entwickelte ajax, das eine Excel-Datei zurückgibt, die ich nicht richtig öffnen konnte, da sie beschädigt ist (trotz der Erweiterung .xlsx). 

Möglicherweise liegt das Problem bei einem ungeeigneten Datentyp, der im Blob-Konstruktor verwendet wird. 

Ich habe versucht, "xhr.response" anstelle von "data" aus Argumenten der Erfolgsmethode zu verwenden, aber es funktioniert auch nicht. Ich habe die Antwortheader in den Entwicklertools in Chrome überprüft und sie sind ordnungsgemäß festgelegt.
Das Wichtigste - alle auf dem Server erstellten Excel-Arbeitsmappen sind korrekt, da sie in der vorherigen Version funktionierten, wenn Daten in URL gesendet wurden, nicht in Ajax-Post.

Controller-Methode in der Java/Spring-Serverseite unten:

response.reset();
response.setContentType("application/vnd.ms-Excel");
response.addHeader("Content-Disposition","attachment;filename=\"" + className + " " +  title + ".xlsx\"");
    try (ServletOutputStream output = response.getOutputStream()){
        workbook.write(output);
        output.flush();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

Mein Ajax zum Herunterladen der Datei und Öffnen des Downloadfensters:

$.ajax({
    url: myUrl,
    type: 'POST',
    data: myData,
    success: function(data, status, xhr) {
        var contentType = 'application/vnd.ms-Excel';

        var filename = "";
        var disposition = xhr.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, '');
        }
        console.log("FILENAME: " + filename);

        try {
            var blob = new Blob([data], { type: contentType });

            var downloadUrl = URL.createObjectURL(blob);
            var a = document.createElement("a");
            a.href = downloadUrl;
            a.download = filename;
            document.body.appendChild(a);
            a.click();

        } catch (exc) {
            console.log("Save Blob method failed with the following exception.");
            console.log(exc);
        }
4
KamilosD

Es sieht so aus, als hätten JQuery Probleme mit den binären Daten aus der Antwort. Ich habe einfach XMLHttpRequest verwendet und füge alle Daten zur URL hinzu.

var request = new XMLHttpRequest();
request.open('POST', url, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.responseType = 'blob';

request.onload = function(e) {
    if (this.status === 200) {
        var blob = this.response;
        if(window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveBlob(blob, fileName);
        }
        else{
            var downloadLink = window.document.createElement('a');
            var contentTypeHeader = request.getResponseHeader("Content-Type");
            downloadLink.href = window.URL.createObjectURL(new Blob([blob], { type: contentTypeHeader }));
            downloadLink.download = fileName;
            document.body.appendChild(downloadLink);
            downloadLink.click();
            document.body.removeChild(downloadLink);
           }
       }
   };
   request.send();
6
KamilosD

Wir hatten in letzter Zeit absolut dieselben Probleme. Für uns fing es an zu arbeiten, als wir responseType: 'arraybuffer' zu den ajax-Parametern hinzufügten. Es ist besser, lib https://github.com/eligrey/FileSaver.js/ zu verwenden, anstatt manuell auf den Link zu klicken, da dieses Tool auch den Speicher aufhebt.

0