Le frontend de l'application ayant une option de téléchargement de fichier (qui peut être au format suivant: xlsx, csv, dat). Pour cela, j'utilise fileSaver.js
Tout fonctionne bien pour le format .dat/.csv
mais pour le .xlsx
ça ne marche pas les fichiers sont corrompus.
J'ai testé la conversion avec les formats suivants:
utf8
base64
binary
Voici comment je fais:
// /* BACK */ //
// data is
fs.readFile(filePath, (err, data) {...})
// the api give this answer the important part is "filename" & "data"
{"status":"ok","context":"writing the intermediate file","target":"/temp/","fileName":"name.xlsx","data":{"type":"Buffer","data":[72,82,65,67,67,69,83,83,32,10]}}
// /* FRONT */ //
let json = JSON.stringify(data)
let buffer = Buffer.from(JSON.parse(json).data)
let read = buffer.toString('utf8')
let blob = new Blob([read])
FileSaver.saveAs(blob, fileName)
3 réponses
Ok pour tous ceux qui passent dans ce sujet, ma solution:
(gardez à l'esprit la meilleure solution pour dl un fichier: envoyer un fichier en réponse api avec en-tête "Content-disposition" ou utiliser express pour cela comme ceci)
Le dos (Node) fonctionne comme ceci:
fs.readFile(filePath, (err, data) => {
if (err) {
console.log(`-------- oups error - read --------`)
console.log(err)
res.send({ status: `erreur`, context: `read the source file`, id: err.errno, code: err.code, message: err.message.replace(/\\/g, '/') })
} else {
res.send({ status: `ok`, context: `send data file`, target: target, fileName: fileName, data: data })
}
})
Ici :
- la cible est le chemin d'accès à l'avant avec le nom du fichier et son extension (
/path/name.ext
) - fileName est juste le nom et l'extension (
name.ext
) - données sont les données envoyées par le readFile (
{"type":"Buffer","data":[72,82,65,67,67,69,83,83,32,10]}
)
Le front (React) fonctionne comme ceci:
fetch(targetUrl)
.then(res => res.json())
.then(res => {
if (res.status !== `ok`) {
this.setState({
errorDlFile: true,
errorDlFile_context: res.context,
errorDlFile_id: res.id,
errorDlFile_code: res.code,
errorDlFile_message: res.message
})
} else {
const target = res.target
const fileName = res.fileName
const data = res.data
const splitName = res.fileName.split('.')
const format = splitName[splitName.length-1]
// file saver blob solution
let json = JSON.stringify(data)
let buffer = Buffer.from(JSON.parse(json).data)
let readUTF8 = buffer.toString('utf8')
let blob = ''
if (format === 'xlsx') {
blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
} else if (format === 'csv') {
blob = new Blob([readUTF8], { type: 'application/vnd.ms-excel' })
} else {
blob = new Blob([readUTF8])
}
FileSaver.saveAs(blob, fileName)
}
})
@Hadock si vous souhaitez télécharger un fichier avec l'extension .csv, vous devez passer le type de fichier comme
let blob = new Blob([csv], { type: 'application/vnd.ms-excel' });
Au lieu de
let blob = new Blob([read])
Et n'oubliez pas d'envoyer le nom de fichier avec l'extension (test.csv).
Pour le fichier Excel, j'ai utilisé différents plugins exceljs démo.
Vous ne pouvez pas enregistrer les données json directement dans un fichier .xlsx, vous pouvez convertir les données json au format excel en utilisant une bibliothèque comme 'sheetjs' (https : //sheetjs.com/)
var ws_name = filename;//"SheetJS";
var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'binary' });
saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), filename + ".xlsx")
Questions connexes
Questions liées
De nouvelles questions
javascript
Pour des questions concernant la programmation dans ECMAScript (JavaScript / JS) et ses divers dialectes / implémentations (hors ActionScript). Veuillez inclure toutes les balises pertinentes dans votre question; par exemple, [node.js], [jquery], [json], etc.