web-dev-qa-db-fra.com

Télécharger le contenu BLOB en utilisant le jeu de caractères spécifié

Est-il possible de changer le jeu de caractères Blob vraiment? J'essaye pendant des heures mais ça ne marche pas. Regarde ça .

jQuery("#download").click(function() {
    var csv_content = jQuery("#csv").val(),
        download = document.createElement("a"),
        blob = new Blob([csv_content], { type: "text/csv;charset=ISO-8859-1" });

    download.href = window.URL.createObjectURL(blob);
    download.download = "test.csv";

    var event = document.createEvent("MouseEvents");
    event.initMouseEvent(
        "click", true, false, window, 0, 0, 0, 0, 0
        , false, false, false, false, 0, null
    );
    download.dispatchEvent(event);    
});

J'ai besoin d'exporter un fichier CSV pour l'ouvrir sur Excel, mais il est toujours enregistré avec UTF-8 et Excel ne peut pas le gérer.

22
David Rodrigues

J'ai trouvé la solution avant de poster.

Le changement de charset n'a pas été résolu, en fait. Cependant, j'ai envoyé l'en-tête UTF-8 pour le processus de téléchargement et Excel a pu comprendre correctement le format de fichier. Merci à cette réponse de Erik Töyrä .

blob = new Blob(["\ufeff", csv_content]);
87
David Rodrigues

Dans mon cas, j’utilisais Angular JS pour recevoir un fichier CSV codé du serveur en réponse à une requête HTTP POST. Le problème était que les fichiers CSV renvoyés par XMLHttpRequests sont représentés par des chaînes Unicode (je veux dire UTF-8, mais selon this il s’agit de UTF-16), et non par des données binaires pré-encodées. Il semble que cela soit également vrai dans votre exemple: il lit le CSV à partir d'un élément DOM? Dans ce cas, il finit par être représenté en tant que Unicode en mémoire, donc peu importe la valeur à laquelle vous définissez les métadonnées d'encodage, les données sont toujours Unicode.

Mon code Angular faisait quelque chose comme ceci:

$http.post('/url', postData, {}).then(handleResponse);

Dans handleResponse, les données étaient déjà représentées dans Unicode. Selon le service $ http de Angular, le fait de ne pas fournir la propriété responseType sur l'objet config entraîne le paramétrage par défaut de string. Qui selon Mozilla finit par être représenté par un DOMString en UTF-16, alors que nous voulons en fait que ce soit un Blob . Définir responseType sur blob sur l'objet config a empêché le contenu de se décoder. Sans cela, les données de réponse étaient décodées par inadvertance avant d'être placées dans le blob.

$http.post('/url', postData, {responseType: 'blob'}).then(handleResponse);

J'ai ensuite utilisé saveAs () pour que le navigateur fournisse le contenu du fichier à l'utilisateur.

function handleResponse(response) {
    let headers = response.headers();
    let blob = new Blob([response.data], {type: headers['content-type']});
    saveAs(blob, headers['x-filename']);
}

J'ai eu l’idée de définir responseType depuis https://stackoverflow.com/a/16791296/1225617

6
Adam Millerchip

si vous avez des symboles dans CSV et que la solution acceptée ne résout pas le problème.

blob = new Blob(["\ufeff", csv_content]);
for csv_content you can try like below.
function b64DecodeUnicode(str: any) {        
        return decodeURIComponent(atob(str).split('').map((c: any) => {
            return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
        }).join(''));
    }
0
Diwakar