diff --git a/cms/pdf.py b/cms/pdf.py index d1d8ee7..3ec6b2e 100644 --- a/cms/pdf.py +++ b/cms/pdf.py @@ -17,182 +17,83 @@ from reportlab.lib.styles import getSampleStyleSheet style_8_c = ps(name='CORPS', fontName='Helvetica', fontSize=6, alignment=TA_CENTER) style_normal = ps(name='CORPS', fontName='Helvetica', fontSize=9, alignment=TA_LEFT) -style_bold = ps(name='CORPS', fontName='Helvetica-Bold', fontSize=10, alignment=TA_LEFT, leftIndent=0.3*cm) +style_bold = ps(name='CORPS', fontName='Helvetica-Bold', fontSize=10, alignment=TA_LEFT) style_title = ps(name='CORPS', fontName='Helvetica', fontSize=12, alignment=TA_LEFT) style_adress = ps(name='CORPS', fontName='Helvetica', fontSize=10, alignment=TA_LEFT, leftIndent=300) +LOGO_EPC = os.path.join(settings.MEDIA_ROOT, 'logo_EPC.png') +LOGO_ESNE = os.path.join(settings.MEDIA_ROOT, 'logo_ESNE.png') + +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) + canvas.Canvas.save(self) + + def draw_page_number(self, page_count): + self.setFont("Helvetica", 7) + self.drawRightString(20*cm, 2*cm, "Page %d de %d" % (self._pageNumber, page_count)) class EpcBaseDocTemplate(SimpleDocTemplate): - def __init__(self, filename, titles=['',''], pagesize=A4): + 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 - # Setting up the frames, frames are use for dynamic content not fixed page elements + def header(self, canvas, doc): + canvas.saveState() + canvas.drawImage(LOGO_EPC, doc.leftMargin, doc.height - 0.5 * cm, 5 * cm, 3 * cm, preserveAspectRatio=True) + canvas.drawImage(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() + + def setNormalTemplatePage(self): 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'])] + self.story = [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() + def setSixSemestreTemplatePage(self): + width = 8 * cm + height = 6.5 * cm + + x = [self.leftMargin, 12 * cm] * 3 + y = [17*cm, 17*cm, 10*cm, 10*cm, 3*cm, 3*cm] + frames = [Frame(x[f], y[f], width=width, height=height, showBoundary=0, leftPadding=0) for + f in range(6)] + frames.append(Frame(self.leftMargin, self.bottomMargin, self.width, 1.5*cm, leftPadding=0)) + # Page template + frame_page = PageTemplate(id='FirstPage', frames=frames, onPage=self.header) + self.addPageTemplates(frame_page) - - -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) - 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. - 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-0.5*cm, 5 * cm, 3 * cm, - preserveAspectRatio=True) - 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.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.height+1*cm) - canvas.restoreState() - - def _draw_title(self, canvas, height): - width = self.leftMargin + self.width - x = self.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) - - - -class MyDocTemplateES(SimpleDocTemplate): - 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 - 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) - self.flowable = list() - SimpleDocTemplate.__init__(self, filename, pagesize=page_size, - topMargin=0 * cm, - leftMargin=2 * cm, - rightMargin=2 * cm, - bottomMargin=0.5 * cm, - ) - - self.fileName = filename - width, height = page_size - 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, - preserveAspectRatio=True) - self.canv.drawImage(settings.MEDIA_ROOT + 'logo_ESNE.png', 14 * cm, 25.5 * cm, 5 * cm, 5 * cm, - preserveAspectRatio=True) - - string_width = stringWidth(title_right, 'Helvetica-Bold', 12) - self.canv.setFont('Helvetica-Bold', 12) - self.canv.line(2 * cm, 25.5 * cm, 19 * cm, 25.5 * cm) - self.canv.drawString(2 * cm, 25 * cm, title_left) - self.canv.drawString(self.textWidth-string_width, 25*cm, title_right) - self.canv.line(2 * cm, 24.6 * cm, 19 * cm, 24.6 * cm) - self.canv.setFont('Helvetica', 10) - - my_frame.addFromList(self.flowable, self.canv) - - """ - self.fileName = filename - self.canv = canvas.Canvas(filename, pagesize=A4) - im1 = Image(settings.MEDIA_ROOT + 'logo_EPC.png', width=170, height=80) - im2 = Image(settings.MEDIA_ROOT + 'logo_ESNE.png', width=170, height=80) - data = list() - data.append([im1, im2]) - data.append([Spacer(0, 0.5 * cm)]) - data.append([title_left, title_right]) - t = Table(data, colWidths=[column_width] * 2, hAlign=TA_LEFT) - t.setStyle( - TableStyle( - [ - ('SIZE', (0, 0), (-1, -1), 9), - ('FONT', (0, 0), (-1, -1), 'Helvetica-Bold'), - ('ALIGN', (0, 0), (0, 0), 'LEFT'), - ('ALIGN', (1, 0), (-1, -1), 'RIGHT'), - ('LINEABOVE', (0, 2), (-1, 2), 0.5, colors.black), - ('LINEBELOW', (0, -1), (-1, -1), 0.5, colors.black), - ] - ) - ) - self.flowable.append(t) - """ - - - def beforePage(self): - # page number - self.canv.saveState() - self.canv.setFontSize(8) - self.canv.drawCentredString(self.pagesize[0] / 2, 0.5 * cm, "Page : " + str(self.canv.getPageNumber())) - self.canv.restoreState() - - -class ModulePdf(MyESDocTemplate): +class ModulePdf(EpcBaseDocTemplate): def __init__(self, filename): - super().__init__(filename, ['Formation EDS', 'Module de formation']) - - def preformatted_left(self, txt): - return Preformatted(txt, style_normal, maxLineLength=15) - - def preformatted_right(self, txt): - return Preformatted(txt, style_normal, maxLineLength=97) + super().__init__(filename, ['Formation EDS', 'Module de formation'], A4) + self.setNormalTemplatePage() def produce(self, module): str_comp = '' @@ -218,62 +119,35 @@ class ModulePdf(MyESDocTemplate): for c in module.objectif_set.all(): str_obj += '- {0}\n'.format(c.nom) - lines = module.contenu.split('\n') - str_con = '' - for l in lines: - str_con += '{0}\n'.format(l) - - lines = module.evaluation.split('\n') - str_con = '' - for l in lines: - str_con += '{0}\n'.format(l) - - # self.flowable.append(Spacer(0, 0.5 * cm)) - self.story.append(Paragraph(module.__str__(), style_bold, )) + 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__())], - [self.preformatted_left('Processus'), self.preformatted_right(module.processus.__str__())], - [self.preformatted_left('Situation emblématique'), self.preformatted_right(module.situation)], - [self.preformatted_left('Compétences visées'), self.preformatted_right(str_comp)], - [self.preformatted_left('Plus-value sur le CFC ASE'), self.preformatted_right(str_scom)], - # [Preformatted_left('Ressources à acquérir'), Preformatted_right(str_res)], - [self.preformatted_left('Objectifs à atteindre'), self.preformatted_right(str_obj)], - [self.preformatted_left('Didactique'), self.preformatted_right(module.didactique)], - # [Preformatted_left('Contenu'), Preformatted_right(str_con)], - [self.preformatted_left('Evaluation'), self.preformatted_right(module.evaluation)], - [self.preformatted_left('Type'), self.preformatted_right('{0}, obligatoire'.format(module.type))], - [self.preformatted_left('Semestre'), self.preformatted_right('Sem. {0}'.format(module.semestre))], - [self.preformatted_left('Présentiel'), - self.preformatted_right('{0} heures'.format(module.periode_presentiel))], - [self.preformatted_left('Travail personnel'), - self.preformatted_right('{0} heures'.format(module.travail_perso))], - [self.preformatted_left('Responsable'), - self.preformatted_right(module.processus.domaine.responsable.descr_pdf())], + ['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 = [] - for foo in d: - data.append([self.preformatted_left(foo[0]), self.preformatted_right(foo[1])]) + formated_data = [] + for foo in data: + formated_data.append( + [Preformatted(foo[0], style_normal, maxLineLength=15), + Preformatted(foo[1], style_normal, maxLineLength=97), + ] + ) - t = Table(data, colWidths=[3*cm, 13*cm]) - t.hAlign = TA_CENTER + t = Table(formated_data, colWidths=[4*cm, 13*cm]) + t.hAlign = TA_LEFT t.setStyle( TableStyle([ ('SIZE', (0, 0), (-1, -1), 7), @@ -283,13 +157,14 @@ class ModulePdf(MyESDocTemplate): ) ) self.story.append(t) - self.build(self.story, onFirstPage=self.header) + self.build(self.story, canvasmaker=NumberedCanvas) class PlanFormationPdf(EpcBaseDocTemplate): def __init__(self, filename): super().__init__(filename, ['Formation EDS', 'Plan de formation'], landscape(A4)) + self.setNormalTemplatePage() def formating(self, el1='', length=40): el1 = '' if el1 == '' else el1.__str__() @@ -366,112 +241,39 @@ class PlanFormationPdf(EpcBaseDocTemplate): # Domaine 8 ('SPAN', (2, 14), (-1, 14)), ('BACKGROUND', (0, 14), (-1, 14), colors.lightgrey), - - ])) - t.hAlign = TA_CENTER - self.story.append(t) - self.build(self.story, onFirstPage=self.header) - - -class PDFResponse(HttpResponse): - - def __init__(self, filename, title='', portrait=True): - HttpResponse.__init__(self, content_type='application/pdf') - self['Content-Disposition'] = 'attachment; filename={0}'.format(filename) - self['Content-Type'] = 'charset=utf-8' - self.story = [] - image = Image(settings.MEDIA_ROOT + '/media/header.png', width=400, height=80) - image.hAlign = TA_LEFT - - self.story.append(image) - data = [['Filières EDS', title]] - if portrait: - t = Table(data, colWidths=[8*cm, 8*cm]) - else: - t = Table(data, colWidths=[11*cm, 11*cm]) - t.setStyle(TableStyle([ - ('ALIGN', (0, 0), (0, 0), 'LEFT'), - ('ALIGN', (1, 0), (-1, -1), 'RIGHT'), - ('LINEABOVE', (0, 0), (-1, -1), 0.5, colors.black), - ('LINEBELOW', (0, -1), (-1, -1), 0.5, colors.black), ])) t.hAlign = TA_LEFT self.story.append(t) - + self.build(self.story) -class PeriodeFormationPdf(SimpleDocTemplate): + +class PeriodeFormationPdf(EpcBaseDocTemplate): """Imprime les heures de cours par semestre""" def __init__(self, filename): - 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 = [] - - 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)] - - # Page template - first_page = PageTemplate(id='FirstPage', frames=frames, onPage=self.on_first_page) - self.addPageTemplates(first_page) - - 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() - + super().__init__(filename, ['Filière EDS', 'Périodes de formation'], A4) + self.setSixSemestreTemplatePage() 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 - - for sem in range(1,7): - x = initial_pos_x[(sem-1) % 2]*cm - y = initial_pos_y[sem-1]*cm - + for sem in range(1, 7): modules = context['sem{0}'.format(str(sem))] total = context['tot{0}'.format(str(sem))] - - # 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) - 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)) + t = Table(data, colWidths=[6.5*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.story.append(t) + self.story.append(FrameBreak()) + self.story.append(Paragraph('Total de la formation: {0} heures'.format(context['tot']), style_bold)) + self.build(self.story)