[reportlab-users] Bug in SimpleDocTemplate? --> Automated PDF printing

Henning von Bargen H.vonBargen at t-p.com
Fri Feb 2 09:07:41 EST 2007


Topic should be: automated PDF printing

If you want to have automatic (no user-interaction)
printing of PDF files ON WINDOWS, things get complicated.

And BTW this is off-topic here, perhaps you should post
to the ghostscript mailing list.

Anyway:

GhostScript has its own problems here.
This is, the mswinpr2 device and other special devices
(for PS or PCL printers) work quite differently according
to landscape printing.

If you want professional PDF batch PDF printing, then you
might want to try the PDF Printer API from the Swiss company
http://www.pdf-tools.ch .
For our commercial application, I used this API and created
a small wrapper around it with SWIG.
You can also use the command-line version, they have a trial
download available at http://www.pdf-tools.com/asp/products.asp?name=prns

In our application, we also used Ghostscript first,
but we had to use some complicated code to select the correct
device first, and the mswinpr2 device is terrible slow.

For automatically detecting and "correcting" landscape PDFs, we used
the following code fragments:

def isLandscape (filename):
"""
Prüft, ob es sich um eine Datei im Querformat handelt.
"""
landscape = False
fin = open(filename, "rb", 32768)
inPage = False
try:
for zeile in fin:
if zeile.split() == ["/Type", "/Page"]:
inPage = True
elif zeile.split() == [">>"]:
inPage = False
elif zeile.startswith("/MediaBox") and inPage:
arr = zeile[11:zeile.find("]")].split()
if int(arr[2]) > int(arr[3]):
landscape = True
break
inPage = False
finally:
fin.close()
return landscape


def rotatePDF (filename, newFilename):
"""
Rotiert eine PDF-Datei um 90 Grad, so dass sie korrekt ausgedruckt werden kann.
Voraussetzung dafür ist, dass die Datei keine /Rotate Einträge enthält
und eigentlich Querformat haben sollte (zu erkennen an /MediaBox [0 0 AAA BBB]
mit AAA BBB üblicherweise = 842 595

Da die Datei Zeilenweise gelesen wird, dauert diese Operation evtl. etwas länger.
"""

INSERT_STRING = "/Rotate 90\n"

fin = open(filename, "rb", 32768)
fout = open(newFilename, "wb", 32768)
xref = {}
xref["0"] = {}
maxObj = 0
olen = 0
rotateFound = False
inXREF = False
modus = None
try:
for zeile in fin:
#print zeile,
if zeile.endswith(" obj\n") or zeile.endswith(" obj\r\n"):
# OBJ erkannt
modus = "obj"
objType = None
# Position (neu) merken
(objnum, updnum, _) = zeile.split()
try:
xref[updnum][objnum] = olen
except KeyError:
xref[updnum] = { objnum: olen }
elif zeile.startswith("/Type "):
objType = zeile.split()[1]
if objType == "/Page":
rotateFound = False
landscape = False
elif zeile.startswith("/Rotate ") and objType == "/Page":
rotateFound = True
elif zeile.startswith("/MediaBox") and objType == "/Page":
arr = zeile[11:zeile.find("]")].split()
if int(arr[2]) > int(arr[3]):
landscape = True
elif zeile == ">>\n" or zeile == ">>\r\n":
# Objekt-Ende
if objType == "/Page" and (landscape and not rotateFound):
# Seitendefinition: /Rotate 90 Zeile hinzufügen
fout.write (INSERT_STRING)
olen += len(INSERT_STRING)
modus = None
elif zeile == "xref\n" or zeile =="xref\r\n":
print xref
modus = "xref"
firstObj = None
xrefOffset = olen
xrefObjNum = None
elif zeile == "startxref\n" or zeile == "startxref\r\n":
modus = "startxref"
# Zeile ausgeben
if modus == "xref":
#print "in xref, %r" % zeile
if len(zeile) == 20:
if zeile.split()[-1] == "f":
# Free object
fout.write (zeile)
olen += len(zeile)
else:
#print "object in use"
generation = int(zeile.split()[1])
fout.write ("%010d %05d n \n" % (xref[str(generation)][str(xrefObjNum)], generation))
olen += 20
xrefObjNum += 1
else:
if len(zeile.split()) == 2:
# Neue subsection
xrefObjNum = int(zeile.split()[0])
else:
if xrefObjNum is not None:
modus = None
fout.write (zeile)
olen += len(zeile)
elif modus == "startxref" and not zeile.startswith(modus):
fout.write ("%d\n" % xrefOffset)
modus = None
else:
fout.write (zeile)
olen += len(zeile)
finally:
fin.close()
fout.close()

------
But be aware that this code has been tested only for Landscape PDFs
generated with Oracle Reports (which has nothing to do with ReportLab).

HTH
Henning


More information about the reportlab-users mailing list