Home / Blogs

How to Export Django Model Data to an Excel Sheet Using Pandas

Django
·

July 2, 2024

how-to-export-django-model-data-to-an-excel-sheet-using-pandas

Django, a high-level Python web framework, is widely used to build web applications quickly and with clean and pragmatic design. One of the common requirements in web applications is to export data from the database to an Excel file. This can be easily achieved using Django and Pandas, a powerful data manipulation library in Python.

This blog post will walk you through the steps to export Django model data to an Excel sheet using Django functional views.

Prerequisites

Before beginning, please confirm that you have installed the following items:


Python
Django
Pandas
Openpyxl (optional, but recommended for handling Excel files)

You can install these packages using pip:


pip install django pandas openpyxl

Step 1: Set Up Your Django Project & App

First, create a Django project and app if you haven’t already:


django-admin startproject myproject
cd myproject
django-admin startapp myapp

Include your app in the INSTALLED_APPS list within the settings.py file:


# myproject/settings.py

INSTALLED_APPS = [
    ...
    'myapp',
]

Step 2: Create a Django Model

Let’s create a simple model in models.py:


# myapp/models.py

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField()

    def __str__(self):
        return f"{self.first_name} {self.last_name}"

These commands will apply the migrations to the database:


python manage.py makemigrations
python manage.py migrate

Step 3: Create a View to Export Data

Now, let’s create a view to export the data from the Person model to an Excel file using Pandas.


# myapp/views.py

import pandas as pd
from django.http import HttpResponse
from .models import Person

def export_persons_to_excel(request):
    # Query the Person model to get all records
    persons = Person.objects.all().values()
    
    # Convert the QuerySet to a DataFrame
    df = pd.DataFrame(list(persons))

    # Define the Excel file response
    response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename=persons.xlsx'

    # Use Pandas to write the DataFrame to an Excel file
    df.to_excel(response, index=False, engine='openpyxl')

    return response

Step 4: Add a URL Pattern

Add a URL pattern to map to the view we just created:



urlpatterns = [
    path('export-persons/', export_persons_to_excel, name='export_persons'),
]

Include the app’s URLs in the project’s main URL configuration:


# myproject/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('myapp/', include('myapp.urls')),
]

Step 5: Test the Export Functionality

To test the export functionality, ensure your development server is running:


python manage.py runserver

Visit http://127.0.0.1:8000/myapp/export-persons/ in your browser. If everything is set up correctly, your browser should prompt you to download an Excel file named persons.xlsx containing the data from the Person model.

Conclusion

In this blog post, we have demonstrated how to export data from a Django model to an Excel file using Pandas. This approach is not only efficient, but it also leverages the powerful data manipulation capabilities of Pandas. With this setup, you can easily extend the functionality to export more complex datasets or apply custom formatting to the Excel files.

Feel free to enhance this basic example by adding more features, such as filtering data before exporting, styling the Excel file, or even creating different export formats (CSV, JSON, etc.).

Additional Enhancements

Filtering Data Before Exporting

You can enhance the export functionality by allowing users to filter the data before exporting. For example, you might want to export only the data for people with a specific last name. Here’s how you can modify the view to include filtering:


# myapp/views.py

def export_persons_to_excel(request):
    last_name_filter = request.GET.get('last_name', None)
    if last_name_filter:
        persons = Person.objects.filter(last_name=last_name_filter).values()
    else:
        persons = Person.objects.all().values()
    
    df = pd.DataFrame(list(persons))
    response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename=persons.xlsx'
    df.to_excel(response, index=False, engine='openpyxl')

    return response

Now, you can filter the data by appending a query parameter to the URL, such as http://127.0.0.1:8000/myapp/export-persons/?last_name=Smith.

Styling the Excel File

Using Pandas, you can also apply styling to your Excel files. For example, you can set the header background color or adjust the column widths. Here’s an example of how to implement basic styling:


# myapp/views.py

from pandas.io.formats.style import Styler

def export_persons_to_excel(request):
    persons = Person.objects.all().values()
    df = pd.DataFrame(list(persons))

    response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename=persons.xlsx'

    # Applying basic styling
    def style_specific_cell(x):
        color = 'background-color: yellow'
        return [color if x.name == 'first_name' else '' for _ in x]

    df.style.apply(style_specific_cell, axis=1).to_excel(response, index=False, engine='openpyxl')

    return response

With this setup, the cells in the first_name column will have a yellow background.

Exporting to Different Formats

Besides Excel, you might want to provide options for exporting data in different formats, such as CSV or JSON. You can extend the view to handle multiple formats:


# myapp/views.py

def export_data(request, file_format):
    persons = Person.objects.all().values()
    df = pd.DataFrame(list(persons))

    if file_format == 'excel':
        response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=persons.xlsx'
        df.to_excel(response, index=False, engine='openpyxl')
    elif file_format == 'csv':
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename=persons.csv'
        df.to_csv(response, index=False)
    elif file_format == 'json':
        response = HttpResponse(content_type='application/json')
        response['Content-Disposition'] = 'attachment; filename=persons.json'
        response.write(df.to_json(orient='records'))
    else:
        response = HttpResponse("Unsupported format", status=400)

    return response

Update the URL patterns to include the file format parameter:


# myapp/urls.py

from django.urls import path
from .views import export_data

urlpatterns = [
    path('export-persons//', export_data, name='export_data'),
]

Now, you can export data in different formats by specifying the desired format in the URL, such as http://127.0.0.1:8000/myapp/export-persons/excel/, http://127.0.0.1:8000/myapp/export-persons/csv/, or http://127.0.0.1:8000/myapp/export-persons/json/.

Implementing these enhancements can provide a more robust and flexible data export feature in your Django application.

Horilla Editorial Team Author

Horilla Editorial Team is a group of experienced writers and editors who are passionate about HR software. We have a deep understanding of the HR landscape and are committed to providing our readers with the most up-to-date and informative content. We have written extensively on a variety of HR software topics, including applicant tracking systems, performance management software, and payroll software etc. We are always looking for new ways to share our knowledge with the HR community. If you have a question about HR software, please don't hesitate to contact us.