How to export orders in Saleor.io to XLSX file

Get a better knowledge of your shop performace by exporting and analizing orders in excel.

Michał Dziadowicz
Michał Dziadowicz
Aug. 4, 20209 min read
How to export orders in Saleor.io to XLSX file

Running a successful e-commerce site requires constantly monitoring sales performance. The ability to export data for analyzing and visualization in popular formats that can be shared is crucial. The simplest way is to export data in CSV format that can be read by plethora of tools. However if there is a need to control how data is presented, using format that embeds formating alongside is better. Exporting data in Excel XLSX format allows changing font family, font colors, columns size, compute values using formulas and so on. While the Saleor.io team is working on adding the ability to export various elements in CSV, we can build our own XLS exporter.

 

The Saleor.io dashboard uses GraphQL, which means you cannot return data in another format than JSON. Instead of returning the XLS file, we can save the file on disk and return the link for download. Another way is to skip the GraphQL part and add a new view that returns the generated file.

 

There two main packages to choose from: openpyxl and xlsxwriter (and xlwt if there is a need for an older binary format xls). Each package has its pros and cons but general usage is the same. Create a workbook, add a worksheet to it and populate worksheet with data. Then save the file on disk or return it in HTTP response.

 

First, install a package that adds XLSX support to python.

pip install XlsxWriter

Then create a view that prepares data and writes it to the XLS file

import io

import xlsxwriter

from django.http import HttpResponse
from saleor.order.models import Order


def export_orders(request):
    file = io.BytesIO()

    # automatically remove timezone 
    workbook = xlsxwriter.Workbook(file, {'remove_timezone': True})
    worksheet = workbook.add_worksheet('Orders')

    headers = ['Email', 'Quantity', 'Order status']

    # add default formatting for dates
    date_format = workbook.add_format({'num_format': 'mm/dd/yyyy', 'align': 'left'})

    # set custom width for columns
    worksheet.set_column(0, 0, 30)
    worksheet.set_column(1, 1, 20)
    worksheet.set_column(2, 2, 20)

    for col, header in enumerate(headers):
        worksheet.write(0, col, header)

    for row, order in enumerate(Order.objects.all()):
        row += 1

        worksheet.write(row, 0, order.user_email)
        worksheet.write(row, 1, order.get_total_quantity())
        worksheet.write(row, 2, order.status)

    workbook.close()

    file.seek(0)

    filename = 'orders.xlsx'

    response = HttpResponse(
        file,
        content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    )
    response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename)

    return response

After that, create a route for this view.

 

from django.urls import path

from . import view

urlpatterns = [
    path(“export/orders/” views.export_orders, name=”export-orders”)
]

and register the newly created app in settings.py. Visiting /export/orders/ url should respond with xlsx file. However anyone that knows this url can download a file. The next step is to add permissions checking. Start by checking if request contains proper JWT token, if so decode it and compare user with theirs permissions.

from graphql_jwt.utils import jwt_decode

from saleor.account.models import User
from saleor.core.permissions import OrderPermissions

JWT_AUTH_HEADER = 'HTTP_AUTHORIZATION'
JWT_AUTH_HEADER_PREFIX = 'JWT'


def get_token_from_request(request):
    auth = request.META.get(JWT_AUTH_HEADER, "").split(maxsplit=1)
    prefix = JWT_AUTH_HEADER_PREFIX

    if len(auth) != 2 or auth[0].upper() != prefix:
        return None
    return auth[1]


def has_user_permission(request, permission):
    token = get_token_from_request(request)
    payload = jwt_decode(token)
    user = User.objects.filter(email=payload["email"], is_active=True).first()
    return user.has_perm(permission)

Validate user before generating the file:

def export_orders(request):
    if not has_user_permission(request, OrderPermissions.MANAGE_ORDERS):
            return HttpResponse('Unauthorized', status=401)
    …

 

Exporting data in excel format is a straightforward task. All libraries for manipulating xlsx files have similar conversions, and APIs for creating workbooks and familiarity with one makes switching to another easy. The presented method can be used to export all sorts of data from the saleor database.

Michał Dziadowicz
written by
Michał Dziadowicz

The high-skilled software engineer who is constantly developing his skills and competency within the challenging projects.

Let’s get the cooperation started!

See how we can help your business become more efficient

Get started!

Find us on