Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

191
Vistas
¿Es posible generar PDF con StreamingHttpResponse como es posible hacerlo con CSV para conjuntos de datos grandes?

Tengo un gran conjunto de datos para el que tengo que generar CSV y PDF. Con CSV, uso esta guía: https://docs.djangoproject.com/en/3.1/howto/outputting-csv/

 import csv from django.http import StreamingHttpResponse class Echo: """An object that implements just the write method of the file-like interface. """ def write(self, value): """Write the value by returning it, instead of storing in a buffer.""" return value def some_streaming_csv_view(request): """A view that streams a large CSV file.""" # Generate a sequence of rows. The range is based on the maximum number of # rows that can be handled by a single sheet in most spreadsheet # applications. rows = (["Row {}".format(idx), str(idx)] for idx in range(65536)) pseudo_buffer = Echo() writer = csv.writer(pseudo_buffer) response = StreamingHttpResponse((writer.writerow(row) for row in rows), content_type="text/csv") response['Content-Disposition'] = 'attachment; filename="somefilename.csv"' return response

Funciona muy bien. Sin embargo, no puedo encontrar nada que se pueda hacer para PDF. ¿Puede? Yo uso render_to_pdf así como también uso una plantilla para PDF.

over 4 years ago · Santiago Trujillo
4 Respuestas
Responde la pregunta

0

Piense en CSV como una ensalada de frutas. Puedes rebanar plátanos en una olla grande, agregar algunas toronjas, un poco de piña, ... y luego dividir el conjunto en porciones individuales que llevas a la mesa (esto es: generas tu archivo CSV y luego lo envías a el cliente). Pero también podrías hacer porciones individuales directamente: Corta unas rodajas de plátano en un bol pequeño, añade unos pomelos, un poco de piña,... trae este bol pequeño a la mesa, y repite el proceso para otras porciones individuales (esto es: genera su archivo CSV y lo envía parte por parte al cliente a medida que lo genera).

Bueno, si CSV es una ensalada de frutas, entonces PDF es un pastel. Tienes que mezclar todos sus ingredientes y ponerlo en el horno. Esto significa que no puedes traer una porción del pastel a la mesa hasta que hayas horneado todo el pastel. Del mismo modo, no puede comenzar a enviar su archivo PDF al cliente hasta que se haya generado por completo.

Entonces, para responder a su pregunta, esto ( response = StreamingHttpResponse((writer.writerow(row) for row in rows), content_type="text/csv") ) no se puede hacer para PDF.

Sin embargo, una vez que se genera su archivo , puede transmitirlo al cliente usando FileResponse como se menciona en otras respuestas.

Si su problema es que la generación del PDF lleva demasiado tiempo (y podría desencadenar un error de tiempo de espera, por ejemplo), aquí hay algunas cosas que debe considerar:

  1. Intenta optimizar la velocidad de tu algoritmo de generación
  2. Genere el archivo en segundo plano antes de que el cliente lo solicite y guárdelo en su sistema de almacenamiento. Es posible que desee utilizar un cronjob o celery para activar la generación del PDF sin bloquear la solicitud HTTP.
  3. Use websockets para enviar el archivo al cliente tan pronto como esté listo para ser descargado (ver django-channels )
over 4 years ago · Santiago Trujillo Denunciar

0

Mirando el enlace que proporcionó, proporciona un enlace a una página sobre cómo crear y enviar archivos pdf dinámicamente usando reportlab .

 import io from django.http import FileResponse from reportlab.pdfgen import canvas def some_view(request): # Create a file-like buffer to receive PDF data. buffer = io.BytesIO() # Create the PDF object, using the buffer as its "file." p = canvas.Canvas(buffer) # Draw things on the PDF. Here's where the PDF generation happens. # See the ReportLab documentation for the full list of functionality. p.drawString(100, 100, "Hello world.") # Close the PDF object cleanly, and we're done. p.showPage() p.save() # FileResponse sets the Content-Disposition header so that browsers # present the option to save the file. buffer.seek(0) return FileResponse(buffer, as_attachment=True, filename='hello.pdf')

Aquí hay un enlace a la documentación de la API de reportlab . Es un poco largo y está almacenado en un pdf de una sola página molesto para navegar, pero debería ponerlo en funcionamiento y poder formatear bien los PDF como desee.

over 4 years ago · Santiago Trujillo Denunciar

0

Tuve una situación similar en la que puedo "generar y transmitir archivos de descarga" de tipos csv , json y xml y quiero hacer lo mismo con Excel - archivo xlsx .

Desafortunadamente, no pude hacer eso. Pero, durante ese tiempo encontré algunas cosas.

  1. Los archivos, CSV, JSON y XML son archivos de texto con una representación adecuada . Pero, cuando se trata de PDF o Excel (o archivos similares), estos archivos se crean con un formato adecuado y metadatos adecuados .

  2. Los datos binarios de PDF y documentos similares se escriben en el búfer io solo cuando llamamos a algunos métodos específicos. [ showPage() y save() de reportlab . (fuente- Django Doc )]

  3. Si inspeccionamos el flujo de archivos, PDF y Excel requieren aplicaciones especiales sofisticadas (p. ej., lector de PDF, Bowsers, etc.) para ver/leer los datos, mientras que, con CSV y JSON, solo necesitamos un editor de texto simple.

Por lo tanto, concluyo que el proceso de "generación de archivos sobre la marcha con descarga continua" (no estoy seguro de cuál es el término técnico correcto que debo usar) no es posible para todos los tipos de archivos, pero solo es posible para algunos archivos orientados a texto.

Nota: Esta es mi experiencia limitada, que puede estar equivocada.

over 4 years ago · Santiago Trujillo Denunciar

0

¿Has probado FileResponse ?

Algo como esto debería funcionar, es básicamente lo que puedes encontrar en el documento de Django :

 import io from django.http import FileResponse from reportlab.pdfgen import canvas def stream_pdf(request): buffer = io.BytesIO() p = canvas.Canvas(buffer) p.drawString(10, 10, "Hello world.") p.showPage() p.save() buffer.seek(io.SEEK_SET) return FileResponse(buffer, as_attachment=True, filename='helloworld.pdf')
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda