Changes between Initial Version and Version 1 of PDFWithJasperReports


Ignore:
Timestamp:
Oct 19, 2008, 9:42:55 AM (16 years ago)
Author:
soroosh
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • PDFWithJasperReports

    v1 v1  
     1If you need to create high-quality PDF reports, you can use JasperReports with django. JasperReports is writen in Java, so I wrote a TCP client to connect to a JasperReports server.
     2This is TCP client code which connects to a jasper server listening on port 5000 and is part of your django application:
     3{{{
     4
     5import settings
     6import socket, pickle
     7
     8class BridgeClient:
     9    def __init__(self, f):
     10        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     11        self._sock.connect(("127.0.0.1",5000))
     12        packet = pickle.dumps(f)
     13        self._sock.send(str(len(packet))+"\n"+packet)
     14        size = int(self._readline())
     15        self.raw = self._readbytes(size)
     16        self._sock.close()
     17
     18    def get_result(self):
     19        return (self.raw)
     20
     21    def _readline(self):
     22        chars = []
     23        while 1:
     24            try:
     25                char = self._sock.recv(1)
     26            except:
     27                char = ''
     28            if char == '\n':
     29                break
     30            chars.append(char)
     31        return "".join(chars)
     32   
     33    def _readbytes(self, n):
     34        chunks = []
     35   
     36        while n > 0:
     37            try:
     38                chunk = self._sock.recv(n)
     39            except:
     40                chunk = None
     41            if not chunk:
     42                raise ServerError("Failed to read response from server")
     43            chunks.append(chunk)
     44            n -= len(chunk)
     45        return "".join(chunks)
     46
     47def get_report(report, params):
     48    return report_client.BridgeClient({"report": settings.REPORT_DIR + report,
     49                                       "params": params,
     50                                       }).get_result()
     51
     52}}}
     53
     54You also need jython to run JasperReport TCP server. Here is the code in Jython:
     55{{{
     56import SocketServer
     57import pickle
     58import org.postgresql.Driver
     59from java.sql.DriverManager import *
     60import sys
     61import os.path
     62import traceback
     63
     64PATH = (os.path.abspath(os.path.dirname(os.path.realpath(__file__))))
     65sys.path.append(PATH+"/../")
     66import settings
     67
     68from java.util import HashMap;
     69from net.sf.jasperreports.engine import JasperFillManager,JasperExportManager
     70from java.lang import System
     71import java.io.ByteArrayOutputStream
     72import java.io.FileOutputStream
     73from net.sf.jasperreports.engine import JRParameter
     74import java.util.Locale
     75
     76class BridgeRequestHandler(SocketServer.BaseRequestHandler):
     77    def handle(self):
     78        try:
     79            size = int(self._readline())
     80            data = self._readbytes(size)
     81            params = pickle.loads(data)
     82            host = ""
     83            if settings.DATABASE_HOST:
     84                if settings.DATABASE_PORT:
     85                    host = "//%s:%s/" % (settings.DATABASE_HOST,
     86                                         str(settings.DATABASE_PORT))
     87                else:
     88                    host = "//%s/" % settings.DATABASE_HOST
     89
     90            connection = getConnection("jdbc:postgresql:"+ host +
     91                                       settings.DATABASE_NAME,
     92                                       settings.DATABASE_USER,
     93                                       settings.DATABASE_PASSWORD)
     94            h = HashMap()
     95            for k, v in params["params"].items():
     96                h.put(k,v)
     97            h.put(JRParameter.REPORT_LOCALE, java.util.Locale("fa"))
     98            report = JasperFillManager.fillReport(params["report"], h, connection)
     99            output = java.io.ByteArrayOutputStream()
     100            JasperExportManager.exportReportToPdfStream(report, output)
     101            output.close()
     102            data =output.toByteArray()
     103        except:
     104            self.request.send("0\n")
     105            print traceback.print_exc()
     106        else:
     107            self.request.send(str(len(data))+"\n")
     108            self.request.send(data)
     109
     110    def _readline(self):
     111        chars = []
     112        while 1:
     113            try:
     114                char = self.request.recv(1)
     115            except:
     116                char = ''
     117            if not char:
     118                self._logException(4, "failed to read response line")
     119                raise ServerError("Failed to read server reply header")
     120            if char == '\n':
     121                break
     122            chars.append(char)
     123        return "".join(chars)
     124   
     125    def _readbytes(self, n):
     126        chunks = []
     127   
     128        while n > 0:
     129            try:
     130                chunk = self.request.recv(1)
     131            except:
     132                chunk = None
     133            if not chunk:
     134                raise ServerError("Failed to read response from server")
     135            chunks.append(chunk)
     136            n -= len(chunk)
     137        return "".join(chunks)
     138
     139#server host is a tuple ('host', port)
     140server = SocketServer.TCPServer(('localhost', 5000), BridgeRequestHandler)
     141server.serve_forever()
     142}}}
     143You need to have these jar files in your classpath: ["itext-1.4.5.jar", "log4j-1.2.jar", "commons-logging.jar", "icu4j.jar", "commons-collections.jar", "commons-digester.jar", "commons-beanutils.jar", "jasperreports-3.0.0.jar"] + JDBC driver to connect to database
     144
     145And this is a sample view {{{
     146
     147def hello_pdf(request):
     148    response = HttpResponse(mimetype='application/pdf')
     149    response['Content-Disposition'] = 'attachment; filename="hello_world.pdf"'
     150    response.write(get_report("hello.jasper", {
     151                "title": (u"hello world"),
     152                }))
     153    return response
     154}}}
Back to Top