2011-05-06 5 views
17

J'utilise reportlab pour générer automatiquement un rapport pdf à partir de données dynamiques. Comme le contenu est parfois trop volumineux pour être affiché en portrait, j'essaie de passer en mode paysage pour les contenus volumineux.Reportlab: Comment basculer entre portrait et paysage?

Voici comment ma génération de rapports fonctionne:

Fonction principale:

doc = DocTemplate(...)   //Doctemplate is a customed BaseDocTemplate class 
array = [] 
some_data= "Here is some data displayed in portrait" 

array.append(Paragraph(some_data)) 

large_data = "this data is too large to be displayed in portrait" 
array.append(Paragraph(large_data)) 

... // Some more data is added after this 

doc.build(array, canvasmaker=NumberedCanvas) 

Ce que je cherche est un moyen d'être en mesure de passer du mode portrait au paysage, à chaque étape, comme je don Je ne connais pas le nombre de pages qui seront nécessaires pour l'afficher. Je suis encore nouveau sur reportlab et même un peu avec python, donc je ne vois pas comment je peux utiliser correctement les solutions fournies par reportlab (PageTemplates, flowables) car je construis tout le document à la fin.

Voici mes autres classes utiles pour ce cas:

class DocTemplate(BaseDocTemplate,): 
def __init__(self, filename, **kw): 
    apply(BaseDocTemplate.__init__, (self, filename), kw) 
    f = Frame(2.6*cm, 2.8*cm, 16*cm, 22.7*cm, id='f') 
    pt = PageTemplate('RectPage', [f], onPage=beforeDrawPage, onPageEnd=afterDrawPage) 
    //beforeDrawPage and afterDrawPage fill the headers of the page (that also need to be in landscape) 
    self.addPageTemplates(pt) 

Je pense que je vais ajouter un autre modèle ou cadre page, mais je ne vois pas comment je peux passer d'un à l'autre pendant les données phase annexe.

class NumberedCanvas(canvas.Canvas): 
def __init__(self, *args, **kwargs): 
    canvas.Canvas.__init__(self, *args, **kwargs) 

    self._saved_page_states = [] 

def showPage(self): 
    self._saved_page_states.append(dict(self.__dict__)) 
    self._startPage() 

def save(self): 
    """add page info to each page (page x of y)""" 
    num_pages = len(self._saved_page_states) 
    for state in self._saved_page_states: 
     self.__dict__.update(state) 
     self.draw_page_number(num_pages) 
     canvas.Canvas.showPage(self) 
    self.setTitle("Title") 
    canvas.Canvas.save(self) 
    self._doc.SaveToFile(self._filename, self) 

def draw_page_number(self, page_count): 
    self.setFont("Helvetica", 11) 
    self.drawRightString(18.5*cm, 26.8*cm, 
     "PAGE %d/%d" % (self._pageNumber, page_count)) 

J'espère que je n'ai rien oublié pour être clair.

Merci beaucoup à l'avance.

Répondre

13

J'ai finalement compris la meilleure façon de le faire par moi-même:

J'ai ajouté un PageTemplate dans mon DocTemplate avec les paramètres du paysage, puis simplement utilisé NextPageTemplate du paquet reportlab.platypus:

array.append(NextPageTemplate('landscape'))

Pour revenir en mode portrait, j'utilise:

array.append(NextPageTemplate('portrait'))

Cela permet une flexibilité assez agréable.

+1

'array' est le' story' – TNT

6

Voici comment je passe entre les modes portrait et paysage, mais je déterminer quelle orientation préalable:

from reportlab.lib.pagesizes import letter, A4 

lWidth, lHeight = letter 

if orientation == 'landscape': 
    canvas.setPageSize((lHeight, lWidth)) 
else: 
    canvas.setPageSize((lWidth, lHeight)) 
29

Utilisez les fonctions paysage et portrait déjà présentes dans le module pagesizes.

from reportlab.lib.pagesizes import letter, landscape 
c = canvas.Canvas(file, pagesize=landscape(letter)) 
Questions connexes