diff --git a/cms/pdf.py b/cms/pdf.py index a489e29..d1d8ee7 100644 --- a/cms/pdf.py +++ b/cms/pdf.py @@ -1,13 +1,13 @@ +import os from django.http.response import HttpResponse from django.conf import settings -from collections import OrderedDict from reportlab.platypus import (SimpleDocTemplate, Spacer, Frame, Paragraph, Preformatted, - BaseDocTemplate, PageTemplate, NextPageTemplate) + PageTemplate, NextPageTemplate, FrameBreak) from reportlab.platypus import Table, TableStyle, Image from reportlab.lib.pagesizes import A4, landscape from reportlab.lib.units import cm -from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT +from reportlab.lib.enums import TA_LEFT, TA_CENTER from reportlab.lib import colors from reportlab.lib.colors import HexColor from reportlab.lib.styles import ParagraphStyle as ps @@ -22,23 +22,58 @@ style_title = ps(name='CORPS', fontName='Helvetica', fontSize=12, alignment=TA_L style_adress = ps(name='CORPS', fontName='Helvetica', fontSize=10, alignment=TA_LEFT, leftIndent=300) -class MyESDocTemplate(BaseDocTemplate): - def __init__(self, filename, titles=['',''], pageSize=A4): - super().__init__(filename, pagesize=pageSize, _pageBreakQuick=0) - - self.bottomMargin = 1*cm - self.letfMargin = 1.5*cm +class EpcBaseDocTemplate(SimpleDocTemplate): + def __init__(self, filename, titles=['',''], pagesize=A4): + super().__init__(filename, pagesize=pagesize, _pageBreakQuick=0, lefMargin=1.5 * cm, bottomMargin=1.5 * cm, + topMargin=1.5 * cm, rightMargin=1.5 * cm) + self.logo_epc = os.path.join(settings.MEDIA_ROOT, 'logo_EPC.png') + self.logo_esne = os.path.join(settings.MEDIA_ROOT, 'logo_ESNE.png') + self.story = [] self.titles = titles - 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+1*cm, self.height - 2*cm, - id='small_table', showBoundary=0) - later_pages_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width+1*cm, self.height, id='large_table', showBoundary=0) + first_page_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width + 1 * cm, self.height - 4 * cm, + id='small_table', showBoundary=0, leftPadding=0 * cm) + later_pages_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width + 1 * cm, self.height - 2 * cm, + id='large_table', showBoundary=0, leftPadding=0 * cm) + + # Creating the page templates + first_page = PageTemplate(id='FirstPage', frames=[first_page_table_frame], onPage=self.header) + later_pages = PageTemplate(id='LaterPages', frames=[later_pages_table_frame]) + 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. + self.flowable = [NextPageTemplate(['*', 'LaterPages'])] + + def header(self, canvas, doc): + canvas.saveState() + canvas.drawImage(self.logo_epc, doc.leftMargin, doc.height - 0.5 * cm, 5 * cm, 3 * cm, preserveAspectRatio=True) + canvas.drawImage(self.logo_esne, doc.width - 2 * cm, doc.height - 0.5 * cm, 5 * cm, 3 * cm, + preserveAspectRatio=True) + canvas.line(doc.leftMargin, doc.height - 0.5 * cm, doc.width+doc.leftMargin, doc.height - 0.5 * cm) + canvas.drawString(doc.leftMargin, doc.height - 1.1* cm, self.titles[0]) + canvas.drawRightString(doc.width+doc.leftMargin, doc.height - 1.1* cm, self.titles[1]) + canvas.line(doc.leftMargin, doc.height - 1.3 * cm, doc.width+doc.leftMargin, doc.height -1.3 * cm) + canvas.restoreState() + + + + +class MyESDocTemplate(SimpleDocTemplate): + + def __init__(self, filename, titles=['',''], pageSize=A4): + super().__init__(filename, pagesize=pageSize, _pageBreakQuick=0, lefMargin=1.5*cm, bottomMargin=1.5*cm, + topMargin=1.5*cm, rightMargin=1.5*cm) + self.titles = titles + self.page_width = (self.width + self.leftMargin * 2) + self.page_height = (self.height - self.bottomMargin * 2) + + # 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+1*cm, self.height - 4*cm, + id='small_table', showBoundary=0, leftPadding=0*cm) + later_pages_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width+1*cm, self.height-2*cm, + id='large_table', showBoundary=0, leftPadding=0*cm) # Creating the page templates first_page = PageTemplate(id='FirstPage', frames=[first_page_table_frame], onPage=self.on_first_page) @@ -48,20 +83,19 @@ class MyESDocTemplate(BaseDocTemplate): # by the default the first template that was added is used for the first page. self.flowable =[NextPageTemplate(['*', 'LaterPages'])] - def on_first_page(self, canvas, doc): canvas.saveState() - canvas.drawImage(settings.MEDIA_ROOT + 'logo_EPC.png', self.leftMargin, self.height - 1*cm, 5 * cm, 5 * cm, + canvas.drawImage(settings.MEDIA_ROOT + 'logo_EPC.png', self.leftMargin, self.height-0.5*cm, 5 * cm, 3 * cm, preserveAspectRatio=True) - canvas.drawImage(settings.MEDIA_ROOT + 'logo_ESNE.png', self.width-2*cm, self.height - 1*cm, 5 * cm, 5 * cm, + canvas.drawImage(settings.MEDIA_ROOT + 'logo_ESNE.png', self.width-2*cm, self.height-0.5*cm, 5 * cm, 3 * cm, preserveAspectRatio=True) - self._draw_title(canvas, self.page_height - 1.5 * cm) + self._draw_title(canvas, self.height - 1*cm ) # self.add_default_info(canvas, doc) canvas.restoreState() def add_default_info(self, canvas, doc): canvas.saveState() - self._draw_title(canvas, self.page_height+1*cm) + self._draw_title(canvas, self.height+1*cm) canvas.restoreState() def _draw_title(self, canvas, height): @@ -78,15 +112,16 @@ class MyESDocTemplate(BaseDocTemplate): class MyDocTemplateES(SimpleDocTemplate): - def __init__(self, filename, title_left, title_right, portrait=True): - if portrait is True: + def __init__(self, filename, title_left, title_right, pageSize=A4): + super().__init__(filename, pagesize=pageSize, _pageBreakQuick=0, lefMargin=1.5*cm, bottomMargin=1.5*cm, + topMargin=1.5*cm, rightMargin=1.5*cm) + + if pageSize == A4: page_size = A4 - column_width = 8 * cm - my_frame = Frame(2*cm, 24*cm, 17*cm, 5*cm, showBoundary=1) + my_frame = Frame(2 * cm, 24 * cm, 17 * cm, 5 * cm, showBoundary=1) else: page_size = landscape(A4) - my_frame = Frame(2*cm, 16*cm, 25*cm, 5*cm, showBoundary=1) - column_width = 13 * cm + my_frame = Frame(2 * cm, 16 * cm, 25 * cm, 5 * cm, showBoundary=1) self.flowable = list() SimpleDocTemplate.__init__(self, filename, pagesize=page_size, topMargin=0 * cm, @@ -97,9 +132,9 @@ class MyDocTemplateES(SimpleDocTemplate): self.fileName = filename width, height = page_size - self.textWidth = width - 2*cm + self.textWidth = width - 2 * cm self.canv = canvas.Canvas(filename, pagesize=page_size) - self.canv.drawImage(settings.MEDIA_ROOT + 'logo_EPC.png', 2 * cm, 17* cm, 5 * cm, 5 * cm, + self.canv.drawImage(settings.MEDIA_ROOT + 'logo_EPC.png', 2 * cm, 17 * cm, 5 * cm, 5 * cm, preserveAspectRatio=True) self.canv.drawImage(settings.MEDIA_ROOT + 'logo_ESNE.png', 14 * cm, 25.5 * cm, 5 * cm, 5 * cm, preserveAspectRatio=True) @@ -194,8 +229,23 @@ class ModulePdf(MyESDocTemplate): str_con += '{0}\n'.format(l) # self.flowable.append(Spacer(0, 0.5 * cm)) - self.flowable.append(Paragraph(module.__str__(), style_bold, )) - self.flowable.append(Spacer(0, 0.5 * cm)) + self.story.append(Paragraph(module.__str__(), style_bold, )) + self.story.append(Spacer(0, 0.5 * cm)) + + d = [['Domaine', module.processus.domaine.__str__()], + ['Processus', module.processus.__str__()], + ['Situation emblématique', module.situation], + ['Compétences visées', str_comp], + ['Plus-value sur le CFC ASE', str_scom], + ['Objectifs', str_obj], + ['Didactique', module.didactique], + ['Evaluation', module.evaluation], + ['Type', '{0}, obligatoire'.format(module.type)], + ['Semestre', 'Sem. {0}'.format(module.semestre)], + ['Présentiel', '{0} heures'.format(module.periode_presentiel)], + ['Travail personnel', '{0} heures'.format(module.travail_perso)], + ['Responsable', module.processus.domaine.responsable.descr_pdf()] + ] data = [ [self.preformatted_left('Domaine'), self.preformatted_right(module.processus.domaine.__str__())], @@ -218,6 +268,10 @@ class ModulePdf(MyESDocTemplate): self.preformatted_right(module.processus.domaine.responsable.descr_pdf())], ] + data = [] + for foo in d: + data.append([self.preformatted_left(foo[0]), self.preformatted_right(foo[1])]) + t = Table(data, colWidths=[3*cm, 13*cm]) t.hAlign = TA_CENTER t.setStyle( @@ -228,11 +282,11 @@ class ModulePdf(MyESDocTemplate): ('LEFTPADDING', (0, 0), (-1, -1), 0), ] ) ) - self.flowable.append(t) - self.build(self.flowable) + self.story.append(t) + self.build(self.story, onFirstPage=self.header) -class PlanFormationPdf(MyESDocTemplate): +class PlanFormationPdf(EpcBaseDocTemplate): def __init__(self, filename): super().__init__(filename, ['Formation EDS', 'Plan de formation'], landscape(A4)) @@ -314,9 +368,9 @@ class PlanFormationPdf(MyESDocTemplate): ('BACKGROUND', (0, 14), (-1, 14), colors.lightgrey), ])) - t.hAlign = TA_LEFT - self.flowable.append(t) - self.build(self.flowable) + t.hAlign = TA_CENTER + self.story.append(t) + self.build(self.story, onFirstPage=self.header) class PDFResponse(HttpResponse): @@ -345,58 +399,78 @@ class PDFResponse(HttpResponse): self.story.append(t) -class PeriodeFormationPdf(MyESDocTemplate): +class PeriodeFormationPdf(SimpleDocTemplate): """Imprime les heures de cours par semestre""" def __init__(self, filename): - super().__init__(filename, ['Filière EDS', 'Heures de formation']) + super().__init__(filename, pagesize=A4, + lefMargin=1.5 * cm, bottomMargin=1.5 * cm, + topMargin=1.5 * cm, rightMargin=1.5 * cm, showBoundary=1) + width = 8 * cm + height = 6.5 * cm + self.flowable = [] - def run(self): - table_grid = [["Product", "Quantity"]] - # Add the objects - self.objects = ['col1', 'col2'] * 50 - for shipped_object in self.objects: - table_grid.append([shipped_object, "42"]) - t = Table(table_grid, colWidths=[0.5 * self.width, 0.5 * self.width]) - t.setStyle(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.flowable.append(t) - print(self.flowable) - """ - self.flowable.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), - ]))) + x = [self.leftMargin, 11.5*cm] * 3 + y = [17,17, 10, 10, 3,3] + frames = [Frame(x[f], y[f]*cm, width=width, height=height, showBoundary=1, leftPadding=0, rightPadding=0) for f in range(6)] - """ - self.build(self.flowable) + # Page template + first_page = PageTemplate(id='FirstPage', frames=frames, onPage=self.on_first_page) + self.addPageTemplates(first_page) - def produce_half_year(self, half_year_id, modules, total): + self.titles = ['Filière EDS', 'Périodes de formation'] + self.page_width = (self.width + self.leftMargin * 2) + self.page_height = (self.height - self.bottomMargin * 2) + + + def on_first_page(self, canvas, doc): + canvas.saveState() + logoEPC = os.path.join(settings.MEDIA_ROOT, 'logo_EPC.png') + canvas.drawImage(settings.MEDIA_ROOT + 'logo_EPC.png', doc.leftMargin, doc.height-0.5*cm, 5 * cm, 3 * cm, + preserveAspectRatio=True) + canvas.drawImage(settings.MEDIA_ROOT + 'logo_ESNE.png', doc.width-2*cm, doc.height-0.5*cm, 5 * cm, 3 * cm, + preserveAspectRatio=True) + height = doc.height - 1*cm + width = doc.leftMargin + doc.width + x = doc.leftMargin + y = height + canvas.line(x, y, width, y) + y -= 15 + canvas.drawString(x, y, self.titles[0]) + canvas.drawRightString(width, y, self.titles[1]) + y -= 8 + canvas.line(x, y, width, y) + canvas.restoreState() + + + def produce(self, context): initial_pos_x = [2, 11.5] initial_pos_y = [17, 17, 10, 10, 3, 3] width = 7.5*cm height = 6.5*cm - x = initial_pos_x[(half_year_id-1) % 2]*cm - y = initial_pos_y[half_year_id-1]*cm + for sem in range(1,7): + x = initial_pos_x[(sem-1) % 2]*cm + y = initial_pos_y[sem-1]*cm - my_frame = Frame(x, y, width, height, showBoundary=1) - data = [['Semestre {0}'.format(half_year_id), '{0} h.'.format(total)]] - for line in modules: - value = getattr(line, 'sem{0}'.format(half_year_id)) - data.append([line.nom, '{0} h.'.format(value)]) + modules = context['sem{0}'.format(str(sem))] + total = context['tot{0}'.format(str(sem))] - t = Table(data, colWidths=[7*cm, 1*cm], spaceBefore=0.5*cm, spaceAfter=1*cm, hAlign=TA_LEFT) - t.setStyle(TableStyle([('ALIGN', (0, 0), (0, 0), 'LEFT'), - ('ALIGN', (1, 0), (-1, -1), 'RIGHT'), - ('LINEBELOW', (0, 0), (1, 0), 1, colors.black), - ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ])) + # my_frame = Frame(x, y, width, height, showBoundary=1) + data = [['Semestre {0}'.format(sem), '{0} h.'.format(total)]] + for line in modules: + value = getattr(line, 'sem{0}'.format(sem)) + data.append([line.nom, '{0} h.'.format(value)]) + print(data) + t = Table(data, colWidths=[6*cm, 1*cm], spaceBefore=0.5*cm, spaceAfter=1*cm, hAlign=TA_LEFT) + t.setStyle(TableStyle([('ALIGN', (0, 0), (0, 0), 'LEFT'), + ('ALIGN', (1, 0), (-1, -1), 'RIGHT'), + ('LINEBELOW', (0, 0), (1, 0), 1, colors.black), + ('SIZE', (0, 0), (-1, -1), 9), + ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ])) - self.flowable.append(t) - my_frame.addFromList(self.flowable, self.canv) - self.canv.save() + self.flowable.append(t) + self.flowable.append(FrameBreak()) + self.build(self.flowable) def print_total(self, total): self.canv.drawString(2*cm, 2*cm, 'Total de la formation: {0} heures'.format(total)) diff --git a/cms/views.py b/cms/views.py index b640496..10a2564 100644 --- a/cms/views.py +++ b/cms/views.py @@ -126,14 +126,16 @@ def print_plan_formation(request): def print_periode_formation(request): filename = 'periode_formation.pdf' path = os.path.join(tempfile.gettempdir(), filename) - - pdf = PeriodeFormationPdf(path) context = {} context = get_context(context) + pdf = PeriodeFormationPdf(path) + pdf.produce(context) + """ for semestre_id in range(1, 7): modules = context['sem{0}'.format(str(semestre_id))] total = context['tot{0}'.format(str(semestre_id))] pdf.produce_half_year(semestre_id, modules, total) + """ #pdf.print_total(context['tot']) with open(path, mode='rb') as fh: