PDF documents

This commit is contained in:
alazo 2017-11-02 14:56:11 +01:00
parent b4191a30f9
commit 511f21eb4d
2 changed files with 86 additions and 80 deletions

View file

@ -1,10 +1,8 @@
import os import os
from django.http.response import HttpResponse
from django.conf import settings from django.conf import settings
from reportlab.platypus import (SimpleDocTemplate, Spacer, Frame, Paragraph, Preformatted, from reportlab.platypus import (SimpleDocTemplate, Spacer, Frame, Paragraph, Preformatted,
PageTemplate, NextPageTemplate, FrameBreak) PageTemplate, NextPageTemplate, FrameBreak, Table, TableStyle)
from reportlab.platypus import Table, TableStyle, Image
from reportlab.lib.pagesizes import A4, landscape from reportlab.lib.pagesizes import A4, landscape
from reportlab.lib.units import cm from reportlab.lib.units import cm
from reportlab.lib.enums import TA_LEFT, TA_CENTER from reportlab.lib.enums import TA_LEFT, TA_CENTER
@ -12,19 +10,19 @@ from reportlab.lib import colors
from reportlab.lib.colors import HexColor from reportlab.lib.colors import HexColor
from reportlab.lib.styles import ParagraphStyle as ps from reportlab.lib.styles import ParagraphStyle as ps
from reportlab.pdfgen import canvas from reportlab.pdfgen import canvas
from reportlab.pdfbase.pdfmetrics import stringWidth
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_normal = ps(name='CORPS', fontName='Helvetica', fontSize=9, alignment=TA_LEFT)
style_bold = ps(name='CORPS', fontName='Helvetica-Bold', fontSize=10, alignment=TA_LEFT) 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_EPC = os.path.join(settings.MEDIA_ROOT, 'logo_EPC.png')
LOGO_ESNE = os.path.join(settings.MEDIA_ROOT, 'logo_ESNE.png') LOGO_ESNE = os.path.join(settings.MEDIA_ROOT, 'logo_ESNE.png')
FILIERE = 'Formation EDS'
class NumberedCanvas(canvas.Canvas): class NumberedCanvas(canvas.Canvas):
"""
Page number and page count
"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
canvas.Canvas.__init__(self, *args, **kwargs) canvas.Canvas.__init__(self, *args, **kwargs)
self._saved_page_states = [] self._saved_page_states = []
@ -44,15 +42,15 @@ class NumberedCanvas(canvas.Canvas):
def draw_page_number(self, page_count): def draw_page_number(self, page_count):
self.setFont("Helvetica", 7) self.setFont("Helvetica", 7)
self.drawRightString(20*cm, 2*cm, "Page %d de %d" % (self._pageNumber, page_count)) self.drawString(self._pagesize[0] / 2, 1 * cm, "Page {0} de {1}".format(self._pageNumber, page_count))
class EpcBaseDocTemplate(SimpleDocTemplate): class EpcBaseDocTemplate(SimpleDocTemplate):
def __init__(self, filename, titles=['', ''], pagesize=A4): def __init__(self, filename, title='', pagesize=A4):
super().__init__(filename, pagesize=pagesize, _pageBreakQuick=0, lefMargin=1.5 * cm, bottomMargin=1.5 * cm, super().__init__(filename, pagesize=pagesize, _pageBreakQuick=0, lefMargin=1.5 * cm, bottomMargin=1.5 * cm,
topMargin=1.5 * cm, rightMargin=1.5 * cm) topMargin=1.5 * cm, rightMargin=1.5 * cm)
self.story = [] self.story = []
self.titles = titles self.title = title
def header(self, canvas, doc): def header(self, canvas, doc):
canvas.saveState() canvas.saveState()
@ -60,64 +58,75 @@ class EpcBaseDocTemplate(SimpleDocTemplate):
canvas.drawImage(LOGO_ESNE, doc.width - 2 * cm, doc.height - 0.5 * cm, 5 * cm, 3 * cm, canvas.drawImage(LOGO_ESNE, doc.width - 2 * cm, doc.height - 0.5 * cm, 5 * cm, 3 * cm,
preserveAspectRatio=True) preserveAspectRatio=True)
canvas.line(doc.leftMargin, doc.height - 0.5 * cm, doc.width + doc.leftMargin, doc.height - 0.5 * cm) 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.drawString(doc.leftMargin, doc.height - 1.1 * cm, FILIERE)
canvas.drawRightString(doc.width+doc.leftMargin, doc.height - 1.1 * cm, self.titles[1]) canvas.drawRightString(doc.width + doc.leftMargin, doc.height - 1.1 * cm, self.title)
canvas.line(doc.leftMargin, doc.height - 1.3 * cm, doc.width + doc.leftMargin, doc.height - 1.3 * cm) canvas.line(doc.leftMargin, doc.height - 1.3 * cm, doc.width + doc.leftMargin, doc.height - 1.3 * cm)
canvas.restoreState() canvas.restoreState()
def later_header(self, canvas, doc):
canvas.saveState()
canvas.line(doc.leftMargin, doc.height + 1 * cm, doc.width + doc.leftMargin, doc.height + 1 * cm)
canvas.drawString(doc.leftMargin, doc.height + 0.5 * cm, FILIERE)
canvas.drawRightString(doc.width + doc.leftMargin, doc.height + 0.5 * cm, self.title)
canvas.line(doc.leftMargin, doc.height + 0.2 * cm, doc.width + doc.leftMargin, doc.height + 0.2 * cm)
canvas.restoreState()
def setNormalTemplatePage(self): def setNormalTemplatePage(self):
first_page_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width + 1 * cm, self.height - 4 * cm, 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) id='first_table', showBoundary=0, leftPadding=0 * cm)
later_pages_table_frame = Frame(self.leftMargin, self.bottomMargin, self.width + 1 * cm, self.height - 2 * 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) id='later_table', showBoundary=0, leftPadding=0 * cm)
# Page template
first_page = PageTemplate(id='FirstPage', frames=[first_page_table_frame], onPage=self.header) first_page = PageTemplate(id='FirstPage', frames=[first_page_table_frame], onPage=self.header)
later_pages = PageTemplate(id='LaterPages', frames=[later_pages_table_frame]) later_pages = PageTemplate(id='LaterPages', frames=[later_pages_table_frame], onPage=self.later_header)
self.addPageTemplates([first_page, later_pages]) self.addPageTemplates([first_page, later_pages])
self.story = [NextPageTemplate(['*', 'LaterPages'])] self.story = [NextPageTemplate(['*', 'LaterPages'])]
def setSixSemestreTemplatePage(self): def setSixSemestreTemplatePage(self):
width = 8 * cm frame_size = (8 * cm, 6.5 * cm,)
height = 6.5 * cm w, h = frame_size
x = [self.leftMargin, 12 * cm] * 3 x = [self.leftMargin, 12 * cm] * 3
y = [17 * cm, 17 * cm, 10 * cm, 10 * cm, 3 * cm, 3 * cm] 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 frames = [Frame(x[f], y[f], width=w, height=h, showBoundary=0, leftPadding=0) for f in range(6)]
f in range(6)] # Frame for total periods
frames.append(Frame(self.leftMargin, self.bottomMargin, self.width, 1.5 * cm, leftPadding=0)) frames.append(Frame(self.leftMargin, self.bottomMargin, self.width, 1.5 * cm, leftPadding=0))
# Page template # Page template
frame_page = PageTemplate(id='FirstPage', frames=frames, onPage=self.header) frame_page = PageTemplate(id='FirstPage', frames=frames, onPage=self.header)
self.addPageTemplates(frame_page) self.addPageTemplates(frame_page)
class ModulePdf(EpcBaseDocTemplate): class ModuleDescriptionPdf(EpcBaseDocTemplate):
"""
PDF for module description
"""
def __init__(self, filename): def __init__(self, filename):
super().__init__(filename, ['Formation EDS', 'Module de formation'], A4) super().__init__(filename, 'Module de formation', A4)
self.setNormalTemplatePage() self.setNormalTemplatePage()
def produce(self, module): def produce(self, module):
str_comp = '' str_competence = ''
for c in module.competence_set.all(): for c in module.competence_set.all():
str_comp += '- {0} ({1})\n'.format(c.nom, c.code) str_competence += '- {0} ({1})\n'.format(c.nom, c.code)
""" """
if self.request.user.is_authenticated: if self.request.user.is_authenticated:
for sc in c.souscompetence_set.all(): for sc in c.souscompetence_set.all():
str_comp += ' -- {0}\n'.format(sc.nom) str_comp += ' -- {0}\n'.format(sc.nom)
""" """
str_sous_competence = ''
str_scom = ''
for c in module.competence_set.all(): for c in module.competence_set.all():
for sc in c.souscompetence_set.all(): for sc in c.souscompetence_set.all():
str_scom += '- {0} (voir {1})\n'.format(sc.nom, c.code) str_sous_competence += '- {0} (voir {1})\n'.format(sc.nom, c.code)
str_res = '' str_res = ''
for c in module.ressource_set.all(): for c in module.ressource_set.all():
str_res += '- {0}\n'.format(c.nom) str_res += '- {0}\n'.format(c.nom)
str_obj = '' str_objectif = ''
for c in module.objectif_set.all(): for c in module.objectif_set.all():
str_obj += '- {0}\n'.format(c.nom) str_objectif += '- {0}\n'.format(c.nom)
self.story.append(Paragraph(module.__str__(), style_bold)) self.story.append(Paragraph(module.__str__(), style_bold))
self.story.append(Spacer(0, 0.5 * cm)) self.story.append(Spacer(0, 0.5 * cm))
@ -126,9 +135,9 @@ class ModulePdf(EpcBaseDocTemplate):
['Domaine', module.processus.domaine.__str__()], ['Domaine', module.processus.domaine.__str__()],
['Processus', module.processus.__str__()], ['Processus', module.processus.__str__()],
['Situation emblématique', module.situation], ['Situation emblématique', module.situation],
['Compétences visées', str_comp], ['Compétences visées', str_competence],
['Plus-value sur le CFC ASE', str_scom], ['Plus-value sur le CFC ASE', str_sous_competence],
['Objectifs', str_obj], ['Objectifs', str_objectif],
['Didactique', module.didactique], ['Didactique', module.didactique],
['Evaluation', module.evaluation], ['Evaluation', module.evaluation],
['Type', '{0}, obligatoire'.format(module.type)], ['Type', '{0}, obligatoire'.format(module.type)],
@ -149,21 +158,26 @@ class ModulePdf(EpcBaseDocTemplate):
t = Table(formated_data, colWidths=[4 * cm, 13 * cm]) t = Table(formated_data, colWidths=[4 * cm, 13 * cm])
t.hAlign = TA_LEFT t.hAlign = TA_LEFT
t.setStyle( t.setStyle(
TableStyle([ TableStyle(
[
('SIZE', (0, 0), (-1, -1), 7), ('SIZE', (0, 0), (-1, -1), 7),
('ALIGN', (0, 0), (-1, -1), 'LEFT'), ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
('VALIGN', (0, 0), (-1, -1), 'TOP'), ('VALIGN', (0, 0), (-1, -1), 'TOP'),
('LEFTPADDING', (0, 0), (-1, -1), 0), ] ('LEFTPADDING', (0, 0), (-1, -1), 0),
]
) )
) )
self.story.append(t) self.story.append(t)
self.build(self.story, canvasmaker=NumberedCanvas) self.build(self.story, canvasmaker=NumberedCanvas)
class PlanFormationPdf(EpcBaseDocTemplate): class FormationPlanPdf(EpcBaseDocTemplate):
"""
PDF for formation plan
"""
def __init__(self, filename): def __init__(self, filename):
super().__init__(filename, ['Formation EDS', 'Plan de formation'], landscape(A4)) super().__init__(filename, 'Plan de formation', landscape(A4))
self.setNormalTemplatePage() self.setNormalTemplatePage()
def formating(self, el1='', length=40): def formating(self, el1='', length=40):
@ -171,7 +185,6 @@ class PlanFormationPdf(EpcBaseDocTemplate):
return Preformatted(el1, style_normal, maxLineLength=length) return Preformatted(el1, style_normal, maxLineLength=length)
def produce(self, domain, process): def produce(self, domain, process):
# my_frame = Frame(2*cm, 1*cm, 26*cm, 15*cm, showBoundary=1)
data = [ data = [
['Domaines', 'Processus', 'Sem1', 'Sem2', 'Sem3', 'Sem4', 'Sem5', 'Sem6'], ['Domaines', 'Processus', 'Sem1', 'Sem2', 'Sem3', 'Sem4', 'Sem5', 'Sem6'],
[self.formating(domain[0]), self.formating(process[0], 60), 'M01', '', '', '', '', ''], [self.formating(domain[0]), self.formating(process[0], 60), 'M01', '', '', '', '', ''],
@ -190,7 +203,8 @@ class PlanFormationPdf(EpcBaseDocTemplate):
[self.formating(domain[7]), self.formating(process[10], 60), 'Macc', '', '', '', '', ''], [self.formating(domain[7]), self.formating(process[10], 60), 'Macc', '', '', '', '', ''],
] ]
t = Table(data, colWidths=[7 * cm, 9 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm], t = Table(data, colWidths=[7 * cm, 9 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm, 1.5 * cm],
spaceBefore=0.5*cm, spaceAfter=1*cm) spaceBefore=0.5 * cm, spaceAfter=1 * cm
)
t.setStyle(TableStyle([ t.setStyle(TableStyle([
('SIZE', (0, 0), (-1, -1), 8), ('SIZE', (0, 0), (-1, -1), 8),
('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'),
@ -244,13 +258,16 @@ class PlanFormationPdf(EpcBaseDocTemplate):
])) ]))
t.hAlign = TA_LEFT t.hAlign = TA_LEFT
self.story.append(t) self.story.append(t)
self.build(self.story) self.build(self.story, canvasmaker=NumberedCanvas)
class PeriodeFormationPdf(EpcBaseDocTemplate): class PeriodSemesterPdf(EpcBaseDocTemplate):
"""Imprime les heures de cours par semestre""" """
PDF for periods during semesters
"""
def __init__(self, filename): def __init__(self, filename):
super().__init__(filename, ['Filière EDS', 'Périodes de formation'], A4) super().__init__(filename, 'Périodes de formation', A4)
self.setSixSemestreTemplatePage() self.setSixSemestreTemplatePage()
def produce(self, context): def produce(self, context):
@ -261,9 +278,8 @@ class PeriodeFormationPdf(EpcBaseDocTemplate):
for line in modules: for line in modules:
value = getattr(line, 'sem{0}'.format(sem)) value = getattr(line, 'sem{0}'.format(sem))
data.append([line.nom, '{0} h.'.format(value)]) data.append([line.nom, '{0} h.'.format(value)])
t = Table(data, colWidths=[6.5*cm, 1*cm], spaceBefore=0.5*cm, spaceAfter=1*cm, hAlign=TA_LEFT) t = Table(data, colWidths=[6.5 * cm, 1 * cm], spaceBefore=0.5 * cm, spaceAfter=1 * cm, hAlign=TA_LEFT,
t.setStyle(TableStyle( style=[
[
('ALIGN', (0, 0), (0, 0), 'LEFT'), ('ALIGN', (0, 0), (0, 0), 'LEFT'),
('ALIGN', (1, 0), (-1, -1), 'RIGHT'), ('ALIGN', (1, 0), (-1, -1), 'RIGHT'),
('LINEBELOW', (0, 0), (1, 0), 1, colors.black), ('LINEBELOW', (0, 0), (1, 0), 1, colors.black),
@ -271,9 +287,8 @@ class PeriodeFormationPdf(EpcBaseDocTemplate):
('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'), ('FONT', (0, 0), (-1, 0), 'Helvetica-Bold'),
] ]
) )
)
self.story.append(t) self.story.append(t)
self.story.append(FrameBreak()) self.story.append(FrameBreak())
self.story.append(Paragraph('Total de la formation: {0} heures'.format(context['tot']), style_bold)) self.story.append(Paragraph('Total de la formation: {0} heures'.format(context['tot']), style_bold))
self.build(self.story) self.build(self.story, canvasmaker=NumberedCanvas)

View file

@ -9,9 +9,8 @@ import tempfile
from django.views.generic import ListView, TemplateView, DetailView from django.views.generic import ListView, TemplateView, DetailView
from django.db.models import F, Sum from django.db.models import F, Sum
from django.http import HttpResponse from django.http import HttpResponse
from reportlab.pdfgen import canvas
from cms.pdf import PeriodeFormationPdf, ModulePdf, PlanFormationPdf from cms.pdf import PeriodSemesterPdf, ModuleDescriptionPdf, FormationPlanPdf
from cms.models import (Domaine, Processus, Module, Competence, Document, UploadDoc,) from cms.models import (Domaine, Processus, Module, Competence, Document, UploadDoc,)
@ -85,8 +84,7 @@ class DocumentDetailView(DetailView):
class UploadDetailView(DetailView): class UploadDetailView(DetailView):
""" """
Affiche les documents uploadés à la suite des doc. Display first recorded documents and next uploaded documents
DocumentsInline
""" """
template_name = 'cms/upload_detail.html' template_name = 'cms/upload_detail.html'
model = UploadDoc model = UploadDoc
@ -100,7 +98,7 @@ class UploadDetailView(DetailView):
def print_module_pdf(request, pk): def print_module_pdf(request, pk):
filename = 'module.pdf' filename = 'module.pdf'
path = os.path.join(tempfile.gettempdir(), filename) path = os.path.join(tempfile.gettempdir(), filename)
pdf = ModulePdf(path) pdf = ModuleDescriptionPdf(path)
module = Module.objects.get(pk=pk) module = Module.objects.get(pk=pk)
pdf.produce(module) pdf.produce(module)
with open(path, mode='rb') as fh: with open(path, mode='rb') as fh:
@ -112,7 +110,7 @@ def print_module_pdf(request, pk):
def print_plan_formation(request): def print_plan_formation(request):
filename = 'plan_formation.pdf' filename = 'plan_formation.pdf'
path = os.path.join(tempfile.gettempdir(), filename) path = os.path.join(tempfile.gettempdir(), filename)
pdf = PlanFormationPdf(path) pdf = FormationPlanPdf(path)
domain = Domaine.objects.all().order_by('code') domain = Domaine.objects.all().order_by('code')
process = Processus.objects.all().order_by('code') process = Processus.objects.all().order_by('code')
pdf.produce(domain, process) pdf.produce(domain, process)
@ -128,15 +126,8 @@ def print_periode_formation(request):
path = os.path.join(tempfile.gettempdir(), filename) path = os.path.join(tempfile.gettempdir(), filename)
context = {} context = {}
context = get_context(context) context = get_context(context)
pdf = PeriodeFormationPdf(path) pdf = PeriodSemesterPdf(path)
pdf.produce(context) 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: with open(path, mode='rb') as fh:
response = HttpResponse(fh.read(), content_type='application/pdf') response = HttpResponse(fh.read(), content_type='application/pdf')
@ -146,7 +137,7 @@ def print_periode_formation(request):
def get_context(context): def get_context(context):
""" """
Calcul du nombre de périodes de formation Retrive periods
""" """
liste = Module.objects.exclude(periode_presentiel=0) liste = Module.objects.exclude(periode_presentiel=0)
# context['tot'] = liste.aggregate(Sum(F('periode_presentiel'))) # context['tot'] = liste.aggregate(Sum(F('periode_presentiel')))