/ python

Integrar JasperReports con django

Jasper Server nos brinda dos servicios web que nos permiten interactuar con los reportes

  • SOAP
  • REST

Ahora veremos como consumir un reporte de Jasper Server desde nuestra aplicación en django via REST.

Primero debemos configurar ciertos parámetros en nuestro archivo settings.py

JASPER_URL = 'http://192.168.1.100'  # url donde esté corriendo jasper server
JASPER_USER = 'jasperadmin'
JASPER_PASSWORD = 'jasperadmin'

Para consumir el servicio REST de Jasper usaremos la librería requests la cual instalamos con el comando pip install requests

Ahora vamos a crear una clase base que interactue con el servicio REST y la cual pueda ser heredada para consumir nuestros propios reportes.

import requests
from django.conf import settings
from django.http import HttpResponse


class BaseJasperReport(object):

    report_name = ''
    filename = ''

    def __init__(self):
        self.auth = (settings.JASPER_USER, settings.JASPER_PASSWORD)
        super(BaseJasperReport, self).__init__()

    def get_report(self):
        url = '{url}/rest_v2/reports/{report_name}.pdf'.format(url=settings.JASPER_URL, report_name=self.report_name)
        req = requests.get(url, params=self.get_params(), auth=self.auth)
        return req.content

    def get_params(self):
    	"""
        Este metodo sera implementado por cada uno de nuestros reportes
        """
        raise NotImplementedError

    def render_to_response(self):
        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename="{}.pdf"'.format(self.filename)
        response.write(self.get_report())
        return response

/rest_v2/reports/ es el endpoint que nos brinda Jasper Server para consumir los reportes para mas información acerca de la API de Jasper Server se puede consultar en la wiki de Jasper Server.

Ahora podemos crear un reporte que herede de esta clase base, para el ejemplo supondremos que tenemos un reporte llamado "reporte de notas" para el cual necesitamos el id del aula para hacer el filtro correspondiente.

Estamos asumiendo que tenemos un modelo Classroom a partir del cual vamos a filtrar nuestro registro de notas en el reporte jasper.

class ScoresReport(BaseJasperReport):

    report_name = 'scores_reports'

    def __init__(self, classroom):
        self.classroom = classroom
        self.filename = 'scores_report_for_{}'.format(self.classroom.name)
        super(ScoresReport, self).__init__()

    def get_params(self):
        return {
            'classroom_id': self.classroom.id
        }

report_name es el id que le asignamos a nuestro reporte al momento de publicarlo en Jasper Server

Listo, ya tenemos un reporte hecho solo nos queda usarlo en un view para poder descargarlo desde nuestra aplicación.

Usando una vista basada en función
def download_scores_report(request):
	# debemos obtener nuestro objeto classroom haciendo la consulta a la base de datos
	report = ScoresReport(classroom)
    return report.render_to_response()
Usando una vista basada en clase
from django.views.generic import View

class DownloadScoresReport(View):
	
    def get(self, request, *args, **kwargs):
    	# debemos obtener nuestro objeto classroom haciendo la consulta a la base de datos
        report = ScoresReport(classroom)
        return report.render_to_response()

Con esto ya tenemos nuestras vistas listas para ser usadas en nuestra aplicación en django.