Escribir en una plantilla XLSX y luego enviarla como respuesta en una función diferente, siempre devuelve indefinido.
Lo que intento hacer:
Las solicitudes llegan a mi servidor para descargar un archivo que contiene datos. La parte de descarga está en el front-end y funciona. Recojo los datos en el backend y luego quiero escribirlos en una plantilla existente y devolver los datos.
Este es el controlador para la solicitud:
async handle(request: Request, response: Response) {
try {
const fileName = 'test.xlsx'
const binary = objectsToTemplateWorkBook()
response.setHeader(
'Content-Disposition',
'attachment; filename=' + fileName
)
response.setHeader('Content-Type', 'application/vnd.openxmlformats')
response.end(binary, 'binary')
} catch (error) {
console.log(error)
response.send(error)
}
}
Esta es la función que se supone que debe escribir los datos en la plantilla.
js
export const objectsToTemplateWorkBook = ():
Promise<any> => {
var XlsxTemplate = require('xlsx-template')
var dataBlob
// Load an XLSX file into memory
const blob = fs.readFile(
path.join(dirname, 'test_template.xlsx'),
function (err, data) {
console.log(dirname)
// Create a template
var template = new XlsxTemplate(data)
// Replacements take place on first sheet
var sheetNumber = 1
// Set up some placeholder values matching the placeholders in the template
var values = {
people: [
{ name: 'John Smith', age: 20 },
{ name: 'Bob Johnson', age: 22 },
],
}
// Perform substitution
template.substitute(sheetNumber, values)
// Get binary data
dataBlob = template.generate()
// ...
}
)
return dataBlob
}
La función parece escribir los datos en la plantilla porque si registro el dataBlob dentro del método fs.readFile, me muestra el archivo. Sin embargo, el return dataBlob siempre devuelve indefinido. Sé que esto se debe a la naturaleza asíncrona, pero sinceramente no tengo idea de cómo arreglarlo. Entonces, mi pregunta para ti es: ¿cómo puedo llevar el dataBlob a mi controlador para enviarlo como respuesta?
davy.ai
Puedes usar la API de
Promise
para asegurarte de que la funciónobjectsToTemplateWorkBook
devuelva eldataBlob
antes de que la funciónhandle
envíe la respuesta.Primero, necesitas asegurarte de que la función
fs.readFile
devuelva unaPromise
en lugar de usar un callback. Puedes hacer esto utilizando el métodoutil.promisify
.js
const util = require('util');
const fs = require('fs');
const readFile = util.promisify(fs.readFile);
Luego, puedes usar la palabra clave
await
para esperar a que se resuelva la promesa dereadFile
antes de continuar con el resto de la funciónobjectsToTemplateWorkBook
.Por último, puedes utilizar la palabra clave
await
en la funciónhandle
para esperar a que se resuelva la promesa deobjectsToTemplateWorkBook
antes de enviar la respuesta.“`js
async handle(request: Request, response: Response) {
try {
} catch (error) {
console.log(error)
response.send(error)
}
}
“`