PDF con JasperServer desde Django, Node.js y Go

PDF con JasperServer desde Django, Node.js y Go

JasperServer es un servicio web de informes (reportes) creado en Java. Su tarea es servir documentos en formato electrónico pdf para su impresión o visualización.


Comunicación con JasperServer

Lo que necesitamos para obtener un documento electrónico es lanzar una petición hacia el servidor jasper. El servidor recibe una serie de parametros tipo querystring a través de una url donde se concatena la carpeta en la que se encuentra, posteriormente se le pasa el usuario y contraseña y por último una configuración output=pdf para que el servidor tome en cuenta el tipo de formato del documento.

Aunque el objetivo de éste post no es de crear un pdf con jasper, lo que si veremos es cómo lo podemos visualizar en diferentes lenguajes de programación.


Node.js

En éste ejemplo usamos express para crear un servidor web y axios para lanzar una petición hacia el servidor jasper.


// jasper_config.js
const JASPER_URLBASE = 'http://localhost:8080/jasperserver/flow.html'
const JASPER_QUERYSTRINGS = '?_flowId=viewReportFlow&_flowId=viewReportFlow&ParentFolderUri=%2F'
const J_FOLDER = 'reports%2Fac_dev&reportUnit=%2Freports%2Fac_dev%2Focupacion&standAlone=true&'
const J_AUTH = 'j_username=jasperadmin&j_password=jasperadmin'
const J_OUTPUT = '&output=pdf'
const JASPERSERVER = J_URLBASE + J_QUERYSTRINGS + J_FOLDER + J_AUTH + J_OUTPUT
module.exports = JASPERSERVER


// index.js
var express = require('express')
var app = express()
var JASPER_SERVER = require('./jasper_config')
var axios = require('axios')

app.get('/reporte', function (req, res) {
  return axios.get(JASPER_SERVER, {headers: { 'Accept': 'application/pdf'},
    responseType: 'arraybuffer'}).then(function(response){      
      res.set({
          'Content-Type': 'application/pdf'
      })
      
      return res.send(response.data)
  })
})

app.listen(3000, function(){
    console.log('listening at 3000')
})

Django

ReporteView es una clase que hereda de la clase View (de vistas basadas en clases) que, mediante el método http get obtiene el documento pdf con la librería requests. El contenido se pasa a la clase BytesIO y posteriormente se escribe la respuesta al método.

# settings.py
JASPER_URLBASE = 'http://localhost:8080/jasperserver/flow.html'
JASPER_QUERYSTRINGS = '?_flowId=viewReportFlow&_flowId=viewReportFlow&ParentFolderUri=%2F'
J_FOLDER = 'reports%2Fac_dev&reportUnit=%2Freports%2Fac_dev%2Focupacion&standAlone=true&'
J_AUTH = 'j_username=jasperadmin&j_password=jasperadmin'
J_OUTPUT = '&output=pdf'
JASPERSERVER = J_URLBASE + J_QUERYSTRINGS + J_FOLDER + J_AUTH + J_OUTPUT


# views.py
from django.views.generic import View
from django.http import HttpResponse
from django.conf import settings
from io import BytesIO
import requests

class ReporteView(View):

    def get(self, *args, **kwargs):
        _url = settings.JASPERSERVER + '&output=pdf'
        _req = requests.get(url=_url)
        _response = HttpResponse(content_type='application/pdf')
        _buffer = BytesIO(_req.content)
        _pdf = _buffer.getvalue()
        _buffer.close()
        _response.write(_pdf)
        return _response

# urls.py
from django.conf.urls import url
from apps.reporte.views import *

urlpatterns = [
        url(r'^reporte/$', Reporte.as_view(), name='reporte'),
]

Go

Usamos ioutil para obtener el contenido de la petición hecha con http.NewRequest. Con respecto a negroni, es un logger para que veamos en la pantalla lo que sucede en cada petición http que hagamos.

package main

import (
	"io"
	"io/ioutil"
	"net/http"

	"github.com/gorilla/mux"
	"github.com/urfave/negroni"
)

func Report(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/pdf")

	client := &http.Client{}
	req, _ := http.NewRequest("GET", URL, nil)
	//req.Header.Set("Accept", "application/pdf")
	res, _ := client.Do(req)
	body, _ := ioutil.ReadAll(res.Body)
	w.Write(body)
}

func main() {

	rtr := mux.NewRouter()
	rtr.HandleFunc("/reporte", Report)
	
	http.Handle("/", rtr)

	n := negroni.New()
	n.Use(negroni.NewLogger())

	n.UseHandler(rtr)

	http.ListenAndServe(PORT, n)
}


Conclusión

En el post cubrimos como podemos consumir un pdf desde Jasper, quedo a la espera de sus comentarios.

Saludos!