Índice de contenido
- Introducción: generar archivos Excel desde Django con Python
- ⚙️ Instalación y configuración del entorno
- Crear y escribir un archivo Excel en Django
- Descargar el archivo Excel directamente desde el navegador
- Ejemplo completo: exportar un queryset de Django a Excel
- Alternativas a XlsxWriter para Django
- ✅ Conclusión
- ❓ Preguntas frecuentes
Exportar datos a Excel es una necesidad muy común cuando trabajamos con aplicaciones Django que manejan información dinámica: reportes, listados de usuarios, resultados de consultas, etc. La buena noticia es que generar un archivo .xlsx de forma automática desde una vista en Django es más sencillo de lo que parece, y el paquete XlsxWriter, aunque no es específico de Django, funciona perfectamente dentro de cualquier proyecto Python.
Antes vimos cómo crear un mapa de sitio o sitemap en Django.
Introducción: generar archivos Excel desde Django con Python
Django no incluye soporte nativo para la generación de hojas de cálculo, pero gracias al ecosistema de Python contamos con librerías muy potentes como XlsxWriter, OpenPyXL o Pandas, cada una con sus propias fortalezas según el caso de uso.
La principal ventaja de XlsxWriter es su sencillez y rendimiento: permite crear y escribir archivos .xlsx en muy pocos pasos, sin depender del entorno de Office ni de ninguna librería externa adicional. Es especialmente útil cuando necesitas generar archivos Excel desde cero de forma programática.
En esta guía te mostraré cómo integrarla paso a paso para crear, escribir y descargar archivos Excel directamente desde una vista de tu aplicación Django.
⚙️ Instalación y configuración del entorno
Para comenzar, instala el paquete con pip. Si trabajas con entornos virtuales (lo cual es altamente recomendable), asegúrate de tenerlo activado antes de ejecutar el comando:
$ pip install XlsxWriterTen en cuenta que XlsxWriter es una librería de Python pura y no depende de Django, por lo que también puedes usarla en scripts independientes o en otros frameworks. Si el paquete no se encuentra al importarlo, es probable que veas el error ModuleNotFoundError: No module named 'xlsxwriter', lo que indica que la instalación no se realizó en el entorno correcto.
Una buena práctica es crear una carpeta dedicada dentro del proyecto para las aplicaciones relacionadas con la generación de documentos y otra para almacenar los archivos generados. Por ejemplo:
myproject/
├─ excel/
│ ├─ views.py
├─ documents/
│ └─ (aquí se guardarán los .xlsx)
Crear y escribir un archivo Excel en Django
Para crear el archivo, basta con definir una vista en views.py que construya el libro de trabajo (workbook) y escriba los datos celda por celda. La lógica es bastante directa: defines tus datos, creas el archivo, iteras sobre la información y la escribes en la hoja.
A continuación, el código completo de la función vista:
excel/views.py
from django.shortcuts import render
import xlsxwriter
def excel_writer(request):
filename = "documents/LibroExcel.xlsx"
data = [
["Nombre", "Apellido", "Edad"],
["Jon", "Snow", 33],
["Daenerys", "Targaryen", 25],
["Tyrion", "Lannister", 40],
["Jaime", "Lannister", 35],
["Cersei", "Lannister", 36]
]
workbook = xlsxwriter.Workbook(filename)
worksheet = workbook.add_worksheet("Hoja 1")
for row in range(len(data)):
for col in range(len(data[row])):
worksheet.write(row, col, data[row][col])
workbook.close()
return render(request, 'csv.html')Explicación del código
Para generar un Excel, lo primero es indicar la ruta del archivo (filename) y preparar los datos (data). En este caso, los datos se representan como una matriz (lista de listas), porque la función write() de XlsxWriter recibe tres argumentos: índice de fila, índice de columna y el valor a escribir. Representarlos en una matriz facilita recorrerlos con un doble bucle for.
Para trabajar con Excel, el primer paso es crear el libro de trabajo o workbook:
workbook = xlsxwriter.Workbook(filename)Luego, añadimos una hoja de trabajo (worksheet):
worksheet = workbook.add_worksheet("Hoja 1")El método add_worksheet() acepta de forma opcional el nombre que quieras asignarle a la hoja; si no pasas ningún argumento, XlsxWriter usará el nombre por defecto (Sheet1, Sheet2, etc.).
Por último, recorremos la matriz con el doble bucle, escribimos cada valor con worksheet.write(row, col, value) y cerramos el libro con workbook.close() para que los cambios queden guardados en disco.
Descargar el archivo Excel directamente desde el navegador
El ejemplo anterior guarda el archivo en el servidor. Sin embargo, lo más habitual en aplicaciones Django es que el usuario pueda descargarlo directamente desde el navegador sin necesidad de almacenarlo en disco. Para ello, generamos el archivo en memoria usando io.BytesIO y lo enviamos como respuesta HTTP con las cabeceras adecuadas:
from django.http import HttpResponse
import io
import xlsxwriter
def download_excel(request):
output = io.BytesIO()
workbook = xlsxwriter.Workbook(output)
worksheet = workbook.add_worksheet("Usuarios")
data = [
["Nombre", "Apellido", "Edad"],
["Arya", "Stark", 19],
["Bran", "Stark", 18],
]
for row in range(len(data)):
for col in range(len(data[row])):
worksheet.write(row, col, data[row][col])
workbook.close()
output.seek(0)
response = HttpResponse(
output.read(),
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
response['Content-Disposition'] = 'attachment; filename=Usuarios.xlsx'
return response Consejo práctico: si el archivo descargado aparece vacío o corrupto, lo más probable es que hayas olvidado la línea output.seek(0) antes de leer el buffer. Es un error muy fácil de pasar por alto que da lugar a archivos con 0 bytes. Además, asegúrate de llamar a workbook.close() antes de hacer el seek(0), ya que es en ese momento cuando XlsxWriter escribe los datos finales en el buffer.
Ejemplo completo: exportar un queryset de Django a Excel
En proyectos reales raramente tendrás los datos hardcodeados en una lista. Lo más habitual es que vengan de un queryset de tu base de datos. Puedes combinar ambos enfoques (guardar en disco o descargar directamente) según tus necesidades; en mi caso, terminé optando por la descarga automática porque mejoraba notablemente la experiencia del usuario, especialmente en reportes administrativos.
Para exportar un queryset directamente a Excel, usa values_list() para obtener los datos en formato de tuplas y recórrelos con enumerate(), reservando la fila 0 para las cabeceras y comenzando a escribir los datos desde la fila 1:
usuarios = User.objects.values_list('first_name', 'last_name', 'age')
for i, row in enumerate(usuarios, start=1):
for j, value in enumerate(row):
worksheet.write(i, j, value)Nota: si tu queryset retorna un resultado vacío y ves el error cannot convert <QuerySet []> to Excel, asegúrate de estar iterando el queryset con values_list() o convirtiéndolo a lista antes de pasarlo a XlsxWriter, ya que la librería no sabe cómo manejar objetos QuerySet directamente.
Alternativas a XlsxWriter para Django
Aunque XlsxWriter es ideal para escribir archivos Excel desde cero, existen otras opciones según el caso de uso. Aquí un resumen comparativo:
| Librería | Ventaja principal | Caso ideal |
|---|---|---|
openpyxl | Permite leer, escribir y modificar archivos Excel existentes | Cuando ya tienes plantillas .xlsx o necesitas ajustar el ancho de columnas |
pandas | Exporta DataFrames directamente a Excel con to_excel() | Reportes analíticos o grandes volúmenes de datos |
django-import-export | Integra import/export como plugin del panel de administración Django | Cuando necesitas que el admin gestione la importación y exportación sin código extra |
En mi experiencia, mantengo XlsxWriter para scripts ligeros donde solo necesito escribir datos, y cambio a openpyxl cuando el requisito implica modificar formatos, aplicar estilos, ajustar el ancho de columnas o trabajar con fórmulas en plantillas preexistentes.
✅ Conclusión
Generar y escribir un archivo Excel en Django es más sencillo de lo que parece. Con unas pocas líneas de código puedes crear reportes personalizados, listados de usuarios o cualquier conjunto de datos en formato .xlsx, ya sea guardando el archivo en el servidor o enviándolo directamente al navegador como descarga. En mi experiencia, integrar XlsxWriter dentro de las vistas de Django resultó una solución rápida y fiable, ideal para proyectos pequeños y medianos donde no necesitas la complejidad de pandas ni las funcionalidades de edición de openpyxl.
❓ Preguntas frecuentes
- ¿Qué librería usar para crear un archivo Excel en Django?
XlsxWriteres la opción más sencilla para escribir archivos nuevos desde cero. Si necesitas leer o editar archivos Excel existentes, usaopenpyxl. Para reportes basados en datos tabulares complejos,pandases la mejor alternativa.
- ¿Cómo exportar un queryset de Django a Excel?
- Usa
Model.objects.values_list()para obtener los datos en formato de tuplas y recorre el resultado conenumerate(), escribiendo cada valor conworksheet.write(). Evita pasar un objetoQuerySetdirectamente a XlsxWriter, ya que generará el errorcannot convert <QuerySet []> to Excel.
- Usa
- ¿Cómo descargar automáticamente el archivo Excel desde Django?
- Genera el archivo en memoria con
io.BytesIO(), cierra el workbook conworkbook.close(), hazoutput.seek(0)y devuelve unaHttpResponsecon elContent-Typecorrecto y la cabeceraContent-Disposition: attachment.
- Genera el archivo en memoria con
- ¿Puedo usar varias hojas en un mismo archivo Excel con XlsxWriter?
- Sí, puedes crear tantas hojas como necesites llamando a
workbook.add_worksheet("nombre")varias veces antes de cerrar el libro. Cada llamada retorna un objetoworksheetindependiente sobre el que puedes escribir datos distintos.
- Sí, puedes crear tantas hojas como necesites llamando a
- ¿Qué diferencia hay entre guardar el Excel en disco y enviarlo como descarga?
- Guardar en disco con
xlsxwriter.Workbook(filename)escribe el archivo en el sistema de ficheros del servidor. Enviarlo como descarga usandoio.BytesIOlo genera en memoria y lo sirve directamente al navegador, sin dejar rastro en el servidor. Para la mayoría de los casos de exportación en Django, la descarga en memoria es la opción más limpia y segura.
- Guardar en disco con
Ahora escribe CSV con Django