[reportlab] mettre un log sur chaque page d'un pdf
Le
Francois Lafont

Bonjour à tous,
J'utilise reportlab pour faire du publipostage et je souhaite insérer un
logo (une image png) sur chaque page. Mais j'ai un problème avec l'ECM
ci-dessous. Attention reportlab doit être installé sur le système et il
ne fait pas partie de la bibliothèque standard. Sur ma Debian, j'ai dû
faire un petit « apt-get install python-reportlab » :
#
from reportlab.platypus import SimpleDocTemplate, Paragraph, PageBreak
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.pagesizes import A4
style = ParagraphStyle(name='default')
story = []
contenu = """<para align="left"><img src="./logo.png"/></para>"""
for i in range(1022): ## < Marche si on met 1021 au lieu de 1022 ?!?
#print i
story.append(Paragraph(contenu, style))
story.append(PageBreak())
pdf = SimpleDocTemplate('doc.pdf', pagesize¤, title='Titre', author='Moi')
pdf.build(story)
#
J'ai ce message d'erreur :
--8<-8<-8<-8<-8<-8<-8<-8<-8<--
Traceback (most recent call last):
File "test.py", line 15, in <module>
File
"/usr/lib/python2.6/dist-packages/reportlab/platypus/paragraph.py", line
805, in __init__
File
"/usr/lib/python2.6/dist-packages/reportlab/platypus/paragraph.py", line
820, in _setup
File
"/usr/lib/python2.6/dist-packages/reportlab/platypus/paraparser.py",
line 1047, in parse
File "/usr/lib/python2.6/dist-packages/reportlab/lib/xmllib.py", line
589, in finish_endtag
File "/usr/lib/python2.6/dist-packages/reportlab/lib/xmllib.py", line
600, in handle_endtag
File
"/usr/lib/python2.6/dist-packages/reportlab/platypus/paraparser.py",
line 658, in end_img
File "/usr/lib/python2.6/dist-packages/reportlab/lib/utils.py", line
550, in __init__
File "/usr/lib/python2.6/dist-packages/reportlab/lib/utils.py", line
447, in open_for_read
IOError: Cannot open resource "./logo.png" fileName='./logo.png'
--8<-8<-8<-8<-8<-8<-8<-8<-8<--
Mais c'est étrange car si je remplace 1022 par 1021 dans mon ECM alors
tout fonctionne et j'ai bien un pdf avec 1021 pages sur lesquelles
apparaissent mon logo. Mais impossible de faire la même chose avec un
pdf de 1022 pages. Cette bizarrerie m'incite à penser que ce n'est
peut-être pas un problème venant de Python. Je suis sous Debian Squeeze
et j'utilise Python version 2.6.6.
Voici donc mes questions :
Q1. Quelle est la raison de mon problème exactement ?
Q2. Comment dois-je m'y prendre pour éviter ce problème tout en insérant
quand même mon logo dans chaque page de mon document pdf ? Tant qu'à
faire, j'aimerais bien une solution/contournement 100% Python plutôt
qu'un réglage du système d'exploitation, même si toute solution m'intéresse.
Merci d'avance pour votre aide.
--
François Lafont
J'utilise reportlab pour faire du publipostage et je souhaite insérer un
logo (une image png) sur chaque page. Mais j'ai un problème avec l'ECM
ci-dessous. Attention reportlab doit être installé sur le système et il
ne fait pas partie de la bibliothèque standard. Sur ma Debian, j'ai dû
faire un petit « apt-get install python-reportlab » :
#
from reportlab.platypus import SimpleDocTemplate, Paragraph, PageBreak
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.pagesizes import A4
style = ParagraphStyle(name='default')
story = []
contenu = """<para align="left"><img src="./logo.png"/></para>"""
for i in range(1022): ## < Marche si on met 1021 au lieu de 1022 ?!?
#print i
story.append(Paragraph(contenu, style))
story.append(PageBreak())
pdf = SimpleDocTemplate('doc.pdf', pagesize¤, title='Titre', author='Moi')
pdf.build(story)
#
J'ai ce message d'erreur :
--8<-8<-8<-8<-8<-8<-8<-8<-8<--
Traceback (most recent call last):
File "test.py", line 15, in <module>
File
"/usr/lib/python2.6/dist-packages/reportlab/platypus/paragraph.py", line
805, in __init__
File
"/usr/lib/python2.6/dist-packages/reportlab/platypus/paragraph.py", line
820, in _setup
File
"/usr/lib/python2.6/dist-packages/reportlab/platypus/paraparser.py",
line 1047, in parse
File "/usr/lib/python2.6/dist-packages/reportlab/lib/xmllib.py", line
589, in finish_endtag
File "/usr/lib/python2.6/dist-packages/reportlab/lib/xmllib.py", line
600, in handle_endtag
File
"/usr/lib/python2.6/dist-packages/reportlab/platypus/paraparser.py",
line 658, in end_img
File "/usr/lib/python2.6/dist-packages/reportlab/lib/utils.py", line
550, in __init__
File "/usr/lib/python2.6/dist-packages/reportlab/lib/utils.py", line
447, in open_for_read
IOError: Cannot open resource "./logo.png" fileName='./logo.png'
--8<-8<-8<-8<-8<-8<-8<-8<-8<--
Mais c'est étrange car si je remplace 1022 par 1021 dans mon ECM alors
tout fonctionne et j'ai bien un pdf avec 1021 pages sur lesquelles
apparaissent mon logo. Mais impossible de faire la même chose avec un
pdf de 1022 pages. Cette bizarrerie m'incite à penser que ce n'est
peut-être pas un problème venant de Python. Je suis sous Debian Squeeze
et j'utilise Python version 2.6.6.
Voici donc mes questions :
Q1. Quelle est la raison de mon problème exactement ?
Q2. Comment dois-je m'y prendre pour éviter ce problème tout en insérant
quand même mon logo dans chaque page de mon document pdf ? Tant qu'à
faire, j'aimerais bien une solution/contournement 100% Python plutôt
qu'un réglage du système d'exploitation, même si toute solution m'intéresse.
Merci d'avance pour votre aide.
--
François Lafont
[..]
Je ne connais rien à reportlab, mais effectivement la limite de 1021 e st
à mon avis transparente : un processus a en général une limi te de 1024
fichiers ouverts simultanément. Comme il y en a 3 "standards" (in, out,
err), ça en laisse 1021.
D'une façon ou d'une autre les fichiers ne sont pas fermés quand il le
devraient. Vraisemblablement un bug.
Selon le système que tu utilises, tu peux augmenter cette limite (sous
linux, c'est avec ulimit -n 4096 par exemple). Bien sûr, ça ne r ésout
rien.
-- Alain.
Ah, je me doutais bien que c'était un truc dans le genre.
Peut-être devrais-je poster sur comp.lang.python ou un truc dans le genre ?
Je pense que je ne vais pas m'amuser à bidouiller mon système sur ce
genre de choses.
Merci bien pour ces précisions Alain.
--
François Lafont
A mon très humble avis ça vient de la façon dont range() fonctionne.
Pour un probléme similaire je dois faire
for i in range(1,5)
....
Pour avoir (1,2,3,4)
D'ailleurs la doc est d'accord avec moi:
Help on built-in function range in module __builtin__:
range(...)
range([start,] stop[, step]) -> list of integers
Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!
These are exactly the valid indices for a list of 4 elements.
Voili voilou...
--
PiLS
Je serais extrêmement surpris que reportlab n'offre pas un moyen de
définir un "template" comprenant le logo. Faire ça page par page me
paraît très laborieux (en plus, la boucle doit prendre un temps fou).
Typiquement, ce genre de systême permet justement de définir un modèle
(qui contient tout le contenu "statique", réutilisable; par exemple,
un logo sur chaque page) que l'on remplit avec le contenu "dynamique"
(qui change d'une page à l'autre ou d'un document à l'autre.
Trouver le moyen de faire ça me paraît la meilleure solution.
Une rapide recherche me suggère que ça se fait avec un pageTemplate.
(ou alors, pour les cas simples, en utilisant onLaterPages avec
SimpleDocTemplate).
http://www.reportlab.com/docs/reportlab-reference.pdf
Pages 17 et suivantes.
--
PiLS
Merci pour les indications. J'avoue que j'ai vraiment du mal avec cette
doc et ce que j'arrive à faire avec reportlab je l'ai trouvé dans le Web
ou sur un article de Linux-mag.
Mais je vais essayer de creuser tout ça quand même. :-)
--
François Lafont
Comme ça m'intéresse aussi j'ai fait une petite recherche et je suis
tombé sur ça:
http://www.java2s.com/Open-Source/Python/PDF/ReportLab/ReportLab_2_4/demos/gadflypaper/gfe.py.htm
C'est une démo utilisant SimpleDocTemplate (un peu complexe mais bien
structuré).
A noter:
def myLaterPages(canvas, doc):
canvas.drawImage("snkanim.gif", 36, 36)
J'ai d'ailleurs sauvegardéla page dans un coin, il y a plein de trucs
à réutiliser là-dedans!
--
PiLS
Il ne passera jamais
Lundi,
Mardi,
Mercredi
...
--
PiLS
1) ne pas répondre avant d'avoir lu la question: FAIL
2) Se souvenir que tous les serveurs ne passent pas les messages
de controle: FAIL