| Version 1 (modified by , 17 years ago) ( diff ) |
|---|
If 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. This is TCP client code which connects to a jasper server listening on port 5000 and is part of your django application:
import settings
import socket, pickle
class BridgeClient:
def __init__(self, f):
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._sock.connect(("127.0.0.1",5000))
packet = pickle.dumps(f)
self._sock.send(str(len(packet))+"\n"+packet)
size = int(self._readline())
self.raw = self._readbytes(size)
self._sock.close()
def get_result(self):
return (self.raw)
def _readline(self):
chars = []
while 1:
try:
char = self._sock.recv(1)
except:
char = ''
if char == '\n':
break
chars.append(char)
return "".join(chars)
def _readbytes(self, n):
chunks = []
while n > 0:
try:
chunk = self._sock.recv(n)
except:
chunk = None
if not chunk:
raise ServerError("Failed to read response from server")
chunks.append(chunk)
n -= len(chunk)
return "".join(chunks)
def get_report(report, params):
return report_client.BridgeClient({"report": settings.REPORT_DIR + report,
"params": params,
}).get_result()
You also need jython to run JasperReport TCP server. Here is the code in Jython:
import SocketServer
import pickle
import org.postgresql.Driver
from java.sql.DriverManager import *
import sys
import os.path
import traceback
PATH = (os.path.abspath(os.path.dirname(os.path.realpath(__file__))))
sys.path.append(PATH+"/../")
import settings
from java.util import HashMap;
from net.sf.jasperreports.engine import JasperFillManager,JasperExportManager
from java.lang import System
import java.io.ByteArrayOutputStream
import java.io.FileOutputStream
from net.sf.jasperreports.engine import JRParameter
import java.util.Locale
class BridgeRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
try:
size = int(self._readline())
data = self._readbytes(size)
params = pickle.loads(data)
host = ""
if settings.DATABASE_HOST:
if settings.DATABASE_PORT:
host = "//%s:%s/" % (settings.DATABASE_HOST,
str(settings.DATABASE_PORT))
else:
host = "//%s/" % settings.DATABASE_HOST
connection = getConnection("jdbc:postgresql:"+ host +
settings.DATABASE_NAME,
settings.DATABASE_USER,
settings.DATABASE_PASSWORD)
h = HashMap()
for k, v in params["params"].items():
h.put(k,v)
h.put(JRParameter.REPORT_LOCALE, java.util.Locale("fa"))
report = JasperFillManager.fillReport(params["report"], h, connection)
output = java.io.ByteArrayOutputStream()
JasperExportManager.exportReportToPdfStream(report, output)
output.close()
data =output.toByteArray()
except:
self.request.send("0\n")
print traceback.print_exc()
else:
self.request.send(str(len(data))+"\n")
self.request.send(data)
def _readline(self):
chars = []
while 1:
try:
char = self.request.recv(1)
except:
char = ''
if not char:
self._logException(4, "failed to read response line")
raise ServerError("Failed to read server reply header")
if char == '\n':
break
chars.append(char)
return "".join(chars)
def _readbytes(self, n):
chunks = []
while n > 0:
try:
chunk = self.request.recv(1)
except:
chunk = None
if not chunk:
raise ServerError("Failed to read response from server")
chunks.append(chunk)
n -= len(chunk)
return "".join(chunks)
#server host is a tuple ('host', port)
server = SocketServer.TCPServer(('localhost', 5000), BridgeRequestHandler)
server.serve_forever()
You 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
And this is a sample view {{{
def hello_pdf(request):
response = HttpResponse(mimetype='application/pdf') responseContent-Disposition = 'attachment; filename="hello_world.pdf"' response.write(get_report("hello.jasper", {
"title": (u"hello world"), }))
return response
}}}