refs:
https://blogs.opentext.com/integrating-birt-with-django/
https://communities.opentext.com/forums/discussion/55503/birt-python-api
I was asked about integrating BIRT with Django in the forums. I used a library called Py4j which allows you to call a Java class from python. The Java gets executed and the results are returned to the code that called the class.
To do this you will need to install
Django is unique because it uses functions called views that are used to display each website. The following is the view I wrote for this project.
views.py
from django.template.loader import get_template from django.templateimportContextfrom django.http importHttp404,HttpResponsefrom django.shortcuts import render from py4j.java_gateway importJavaGatewaydef generate_birt(request):if'q'in request.GET: gateway =JavaGateway() stack = gateway.entry_point.getStack(request.GET['q']) reportHTML = stack.getReport()return render(request,'birt_parameters.html',{'report_html': reportHTML})else: error ='You entered an empty request!'return render(request,'birt_parameters.html',{'report_html':'You entered an empty request'})def birt_report(request):return render(request,'birt_parameters.html')
After the views are placed in views.py you need to map the urls to each one so they can be executed from the web browser.
urls.py
from mysite.views import birt_report, generate_birt urlpatterns = patterns('', url(r'^birt/$', birt_report),(r'^generate/$', generate_birt),)
Now that the views and urls are in place you can go to the website but you’ll get an error. This is because generate_report() is trying to output the report HTML to a template called birt_parameters.html. Now you’ll need to create a folder called templates. I like to keep it in the same directory as my Django project. Then save this html in your templates folder.
birt_parameters.html
<html><head><title>BIRT + Django</title></head><body><formaction="/generate/"method="get"> Enter country:<br><inputtype="text"name="q"><br><inputtype="submit"value="Run report"></form></body></html> {{ report_html|safe }}
The HTML is pretty straight forward except for the last part {{ report_html|safe }} is a variable. This is how we’re passing the report HTML back into the same page, safe tells Python that it’s HTML. If you don’t add safe then you will still get a report, you’ll just be reading HTML along with it.
The Java that I use is similar to what I used in my JSF 2.0 Blog.
Birt4Py.java
package org.birtexchange.django;import org.apache.commons.io.output.ByteArrayOutputStream;import org.eclipse.birt.core.exception.BirtException;import org.eclipse.birt.core.framework.Platform;import org.eclipse.birt.report.engine.api.EngineConfig;import org.eclipse.birt.report.engine.api.EngineException;import org.eclipse.birt.report.engine.api.HTMLRenderOption;import org.eclipse.birt.report.engine.api.HTMLServerImageHandler;import org.eclipse.birt.report.engine.api.IReportEngine;import org.eclipse.birt.report.engine.api.IReportEngineFactory;import org.eclipse.birt.report.engine.api.IReportRunnable;import org.eclipse.birt.report.engine.api.IRunAndRenderTask;publicclassBirt4Py{privatestaticString report;privatestaticIReportEngine engine =null;privatestaticEngineConfig config =null;publicstaticString getReport(){return report;}publicBirt4Py()throwsBirtException{// start up Platform config =newEngineConfig(); config.setLogConfig("./logs", java.util.logging.Level.FINEST);Platform.startup( config );// create new Report EngineIReportEngineFactory factory =(IReportEngineFactory)Platform.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY ); engine = factory.createReportEngine( config );}publicvoid executeReport(String param)throwsEngineException{try{// open the report designIReportRunnable design =null; design = engine.openReportDesign("/home/kclark/test.rptdesign");// create RunandRender TaskIRunAndRenderTask task = engine.createRunAndRenderTask(design);// pass necessary parameters task.setParameterValue("Country", param); task.validateParameters();// set render options including output typeHTMLRenderOption options =newHTMLRenderOption();ByteArrayOutputStream outs =newByteArrayOutputStream(); options.setOutputStream(outs); options.setImageHandler(newHTMLServerImageHandler()); options.setBaseImageURL("http://localhost/images"); options.setImageDirectory("/var/www/images"); options.setEmbeddable(true); options.setOutputFormat("html"); task.setRenderOption(options);// run taskString output; task.run(); output = outs.toString(); task.close(); report = output;}catch(Exception ex){ ex.printStackTrace();}}}
Now we have a class that can generate a report, a view that shows a parameter input, and our template. The only thing we have left to do is make Java and Python talk to each other.
EntryPoint.java
package org.birtexchange.django;import org.eclipse.birt.core.exception.BirtException;import org.eclipse.birt.report.engine.api.EngineException;import py4j.GatewayServer;publicclassEntryPoint{privateBirt4Py birt;publicEntryPoint(){try{ birt =newBirt4Py();}catch(BirtException e){ e.printStackTrace();}}publicBirt4Py getStack(String param){try{ birt.executeReport(param);}catch(EngineException e){ e.printStackTrace();}return birt;}publicstaticvoid main(String[] args){GatewayServer gatewayServer =newGatewayServer(newEntryPoint()); gatewayServer.start();System.out.println("Birt4Py listener started!");}}
This will create the gateway for Java and Python and listen to calls. For this to work you will need to run EntryPoint. Once it’s started it will sit and listen for commands until it’s stopped. There are a number of ways you can autostart this on boot depending on your system.
Once Python calls getStack(String) it will call our Java class, passing it the parameter, and return the HTML as a string to Python. Once Python has it Django generates the template the the report HTML.