2016-09-01 2 views
1

Я попытался создать список доставки с в Python. Я пытался поместить все части (например, адрес отправителей, адрес получателей, таблицу), используя Platypus Frames.Динамический фрейм в Python Reportlab

Первая проблема, что я побежал в том, что мне нужно было много Frames позиционировать все правильно, есть лучший способ использования Утконос? Поскольку я хочу, чтобы адрес отправителя и мой адрес были на одинаковой высоте, и если я просто добавлю их в свой story = [], они выравниваются один под другим.

Следующая проблема является то, что таблица Я рисую динамична в размерах и, когда я добираюсь до конца Frame (пространства Я хочу, чтобы таблица идти) он просто делает FrameBreak и непрерывный в следующем кадре , Итак, как я могу сделать динамическое Frame (пространство для моей таблицы)?

+0

Как вы новый пользователь, просто немного задумайтесь над вопросами и ответами. Если ответ разрешил вашу проблему, нажмите зеленую галочку под числом голосов. Таким образом, каждый знает, что на вопрос был дан ответ, и в качестве бонуса ответчик получает определенную репутацию за свои усилия. :) – B8vrede

ответ

2

Ваш прецедент является действительно распространенным, поэтому Reportlab имеет систему, которая поможет вам.

Если вы читаете инструкцию о platypus она познакомит вас 4 основных понятий:

DocTemplates внешний контейнер для документа;

PageTemplates технические характеристики для макетов страниц различного вида;

Frames характеристики областей на страницах, которые могут содержать плавный текст или графику.

Flowables Используя PageTemplates, вы можете комбинировать «статический» контент с динамическим на странице разумным способом, например, логотипы, адреса и т. Д.

Вы уже открыли Flowables и Frames но Propably вы не начать фантазии PageTemplates или DocTemplates еще. Это имеет смысл, потому что это не обязательно для большинства простых документов. К сожалению, отгрузочный список - это не простой документ, он содержит адрес, логотипы и важную информацию, которая должна быть на каждой странице. Это место, где PageTemplates входите.

Итак, вы используете эти шаблоны? Концепция проста: каждая страница имеет определенную структуру, которая может отличаться между страницами, например, на первой странице, которую вы хотите поместить в адреса, а затем запустите таблицу, а на второй странице вы хотите только таблицу.Это было бы что-то вроде этого:

Page 1: enter image description here

Page 2: enter image description here

пример будет выглядеть следующим образом:

(Это было бы идеально для документации SO, если она была для Reportlab)

from reportlab.lib.pagesizes import A4 
from reportlab.lib.styles import getSampleStyleSheet 
from reportlab.lib.units import cm 
from reportlab.lib import colors 
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, NextPageTemplate, Paragraph, PageBreak, Table, \ 
    TableStyle 


class ShippingListReport(BaseDocTemplate): 
    def __init__(self, filename, their_adress, objects, **kwargs): 
     super().__init__(filename, page_size=A4, _pageBreakQuick=0, **kwargs) 
     self.their_adress = their_adress 
     self.objects = objects 

     self.page_width = (self.width + self.leftMargin * 2) 
     self.page_height = (self.height + self.bottomMargin * 2) 


     styles = getSampleStyleSheet() 

     # Setting up the frames, frames are use for dynamic content not fixed page elements 
     first_page_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width, self.height - 6 * cm, id='small_table') 
     later_pages_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width, self.height, id='large_table') 

     # Creating the page templates 
     first_page = PageTemplate(id='FirstPage', frames=[first_page_table_frame], onPage=self.on_first_page) 
     later_pages = PageTemplate(id='LaterPages', frames=[later_pages_table_frame], onPage=self.add_default_info) 
     self.addPageTemplates([first_page, later_pages]) 

     # Tell Reportlab to use the other template on the later pages, 
     # by the default the first template that was added is used for the first page. 
     story = [NextPageTemplate(['*', 'LaterPages'])] 

     table_grid = [["Product", "Quantity"]] 
     # Add the objects 
     for shipped_object in self.objects: 
      table_grid.append([shipped_object, "42"]) 

     story.append(Table(table_grid, repeatRows=1, colWidths=[0.5 * self.width, 0.5 * self.width], 
          style=TableStyle([('GRID',(0,1),(-1,-1),0.25,colors.gray), 
              ('BOX', (0,0), (-1,-1), 1.0, colors.black), 
              ('BOX', (0,0), (1,0), 1.0, colors.black), 
              ]))) 

     self.build(story) 

    def on_first_page(self, canvas, doc): 
     canvas.saveState() 
     # Add the logo and other default stuff 
     self.add_default_info(canvas, doc) 

     canvas.drawString(doc.leftMargin, doc.height, "My address") 
     canvas.drawString(0.5 * doc.page_width, doc.height, self.their_adress) 

     canvas.restoreState() 

    def add_default_info(self, canvas, doc): 
     canvas.saveState() 
     canvas.drawCentredString(0.5 * (doc.page_width), doc.page_height - 2.5 * cm, "Company Name") 

     canvas.restoreState() 


if __name__ == '__main__': 
    ShippingListReport('example.pdf', "Their address", ["Product", "Product"] * 50) 
Смежные вопросы