Cómo devolver archivo PDF desde el controlador

votos
1

Trato de devolver un archivo PDF desde un punto final controlador utilizando NestJs. Si no se define la Content-typecabecera, los datos devueltos por getDocumentFileconsigue devueltos al usuario bien. Al agregar el encabezado Sin embargo, el regreso consigo parece ser una extraña forma de un GUID, la respuesta siempre es el siguiente: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxcuando xes un carácter hexadecimal minúsculas. También parece ser totalmente sin relación con el valor de retorno real de la función de controlador, ya que incluso sale este extraño GUID-cosa cuando no devolver nada en absoluto.

Si no se define Content-type: application/pdf, la función devuelve los datos de la memoria intermedia muy bien, sin embargo necesito para establecer la cabecera con el fin de conseguir que el navegador reconozca la respuesta como un archivo PDF que es importante para mi caso de uso.

El controlador es el siguiente:

@Controller('documents')
export class DocumentsController {
  constructor(private documentsService: DocumentsService) {}

  @Get(':id/file')
  @Header('Content-type', 'application/pdf')
  async getDocumentFile(@Param('id') id: string): Promise<Buffer> {
    const document = await this.documentsService.byId(id)
    const pdf = await this.documentsService.getFile(document)

    // using ReadableStreamBuffer as suggested by contributor
    const stream = new ReadableStreamBuffer({
      frequency: 10,
      chunkSize: 2048,
    })
    stream.put(pdf)
    return stream
  }
}

y mi DocumentsService como esto:

@Injectable()
export class DocumentsService {
  async getAll(): Promise<Array<DocumentDocument>> {
    return DocumentModel.find({})
  }

  async byId(id: string): Promise<DocumentDocument> {
    return DocumentModel.findOne({ _id: id })
  }

  async getFile(document: DocumentDocument): Promise<Buffer> {
    const filename = document.filename
    const filepath = path.join(__dirname, '..', '..', '..', '..', '..', 'pdf-generator', 'dist', filename)

    const pdf = await new Promise<Buffer>((resolve, reject) => {
      fs.readFile(filepath, {}, (err, data) => {
        if (err) reject(err)
        else resolve(data)
      })
    })
    return pdf
  }
}

Originalmente acabo de regresar el buffer ( return pdf), pero que trajo el mismo resultado que el intento anterior. En el repositorio de NestJs un usuario sugiere utilizar el método anterior, lo que obviamente no funciona para mí tampoco. Ver el hilo de GitHub aquí .

Publicado el 27/11/2018 a las 17:00
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
0

Esto funciona para mi.

@Get('pdf')
@HttpCode(HttpStatus.OK)
@Header('Content-Type', 'application/pdf')
@Header('Content-Disposition', 'attachment; filename=test.pdf')
pdf() {
    return createReadStream('./nodejs.pdf');
}

Por cierto, creo que debería ser mejor usar Streamen lugar de readFile. Porque se carga todo el contenido del archivo en la memoria RAM.

Respondida el 30/11/2018 a las 12:11
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more