Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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

7 réponses
Avatar
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=A4, 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

7 réponses

Avatar
Alain Ketterlin
Francois Lafont writes:

[..]
Mais c'est étrange car si je remplace 1022 par 1021 dans mon ECM alo rs
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 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.
Avatar
Francois Lafont
Le 31/10/2011 10:47, Alain Ketterlin a écrit :

Je ne connais rien à reportlab, mais effectivement la limite de 1021 est
à mon avis transparente : un processus a en général une limite de 1024
fichiers ouverts simultanément. Comme il y en a 3 "standards" (in, out,
err), ça en laisse 1021.



Ah, je me doutais bien que c'était un truc dans le genre.

D'une façon ou d'une autre les fichiers ne sont pas fermés quand il le
devraient. Vraisemblablement un bug.



Peut-être devrais-je poster sur comp.lang.python ou un truc dans le genre ?

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.



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
Avatar
PiLS
Le lun, 31 oct 2011 05:47:39, Alain Ketterlin a ploppé:
Francois Lafont writes:

[..]
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 ne connais rien à reportlab, mais effectivement la limite de 1021 est
à mon avis transparente : un processus a en général une limite 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.



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
Avatar
PiLS
Le dim, 30 oct 2011 21:12:31, Francois Lafont a ploppé:

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.



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
Avatar
Francois Lafont
Le 31/10/2011 21:22, PiLS a écrit :

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.



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
Avatar
PiLS
Le mar, 01 nov 2011 09:37:34, Francois Lafont a ploppé:
Le 31/10/2011 21:22, PiLS a écrit :
(ou alors, pour les cas simples, en utilisant onLaterPages avec
SimpleDocTemplate).
http://www.reportlab.com/docs/reportlab-reference.pdf
Pages 17 et suivantes.



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. :-)





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
Avatar
PiLS
Le Cancel n'est pas passé
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