示例#1
0
def export_customer_tags(query):
    pdf = FPDF(orientation ='P', unit = 'mm', format='Letter')
    pdf.set_margins(left=4, top=8, right=5)
    pdf.set_auto_page_break(auto = True, margin = 10)
    pdf.add_page()
    pdf.set_font('Arial', '', 10)

    x_ref = pdf.get_x()
    width_tag = 69.6
    count = 0
    y_ref = pdf.get_y()
    count_tag = 0
    for customer in query:
        if count_tag % 30 == 0 and count_tag > 0:
            pdf.add_page()
        #text = 'Prezado Alisson Barbosa\nRua das Orquídeas, 57\nJardim das Plantas\nCampina Grande - PB\n58415-000'
        text = '{}\n{}, {}\n{}\n{}\n{}'.format(customer.name, customer.street, customer.number, customer.neighborhood, customer.city, customer.cep)
        if count == 0:
            x_ref = pdf.get_x()
            y_ref = pdf.get_y()
            count += 1
        elif count == 1:
            x_ref += width_tag
            count += 1
        elif count == 2:
            x_ref += width_tag
            count = 0
        pdf.set_xy(x = x_ref, y = y_ref)
        pdf.multi_cell(width_tag, 5.195, text, 0, 'L')
        count_tag += 1
            

    response = HttpResponse(pdf.output(dest='S').encode('latin-1'))
    response['Content-Disposition'] = 'attachment;filename="Etiquetas.pdf"'
    return response
示例#2
0
def generateDicePDF():
    # save FPDF() class into
    # a variable pdf
    pdf = FPDF()
    pdf.add_page()
    pdf.add_font('Braille', '', 'static/Swell-Braille.ttf', uni=True)

    # set style and size of font
    # that you want in the pdf

    pdf.set_font("Arial", size=30)
    pdf.multi_cell(200,
                   5,
                   txt='Braille Labels for Dice/Spinner\n\n',
                   align='C')
    pdf.set_font("Arial", size=10)
    pdf.multi_cell(
        200,
        5,
        txt='Cut out Braille labels and paste them onto the dice/spinner.\n\n',
        align='C')

    index = 0
    theText = ['0', '0']
    f = open("static/userData/brailleForDice.txt", "r")
    # insert the texts in pdf
    theX = pdf.get_x()
    theY = pdf.get_y()
    for x in f:
        if theX >= 170:
            theX = 5
            theY += 15
            if theY >= 260:
                pdf.add_page()
                theY = 15
        if index == 0:
            pdf.set_xy(theX - 5, theY)
        if index > 0:
            pdf.set_xy(theX + 17, theY)
        if index % 6 == 0:
            if int(theText[0]) > 9:
                theY += 15
            theX = 5
            pdf.set_xy(theX, theY)
        theX = pdf.get_x()
        theY = pdf.get_y()
        theText = x.split(':')
        pdf.set_font("Arial", size=8)
        pdf.multi_cell(15, 10, txt=theText[0], align='R')
        pdf.set_font('Braille', '', size=24)
        pdf.set_xy(theX + 15, theY)
        theX = pdf.get_x()
        theY = pdf.get_y()
        pdf.multi_cell(27, 10, txt=theText[1], align='L', border=1)
        index += 1

    # save the pdf with name .pdf
    pdf.output("static/userData/theDiceSpinner.pdf")
示例#3
0
def test_graphics_context(tmp_path):
    pdf = FPDF()
    pdf.add_page()
    pdf.set_font("helvetica", "", 12)
    pdf.set_text_color(0x00, 0xFF, 0x00)
    pdf.set_fill_color(0xFF, 0x88, 0xFF)
    pdf.set_y(20)
    pdf.cell(txt="outer 01", new_x=XPos.LMARGIN, new_y=YPos.NEXT, fill=True)
    with pdf.local_context():
        pdf.set_font("courier", "BIU", 30)
        pdf.set_text_color(0xFF, 0x00, 0x00)
        pdf.set_fill_color(0xFF, 0xFF, 0x00)
        pdf.cell(txt="inner 01",
                 new_x=XPos.LMARGIN,
                 new_y=YPos.NEXT,
                 fill=True)
        pdf.set_x(70)
        with pdf.rotation(30, pdf.get_x(), pdf.get_y()):
            pdf.set_fill_color(0x00, 0xFF, 0x00)
            pdf.cell(txt="inner 02",
                     new_x=XPos.LMARGIN,
                     new_y=YPos.NEXT,
                     fill=True)
        pdf.set_stretching(150)
        pdf.cell(txt="inner 03",
                 new_x=XPos.LMARGIN,
                 new_y=YPos.NEXT,
                 fill=True)
    pdf.cell(txt="outer 02", new_x=XPos.LMARGIN, new_y=YPos.NEXT, fill=True)
    assert_pdf_equal(pdf, HERE / "graphics_context.pdf", tmp_path)
def pokepdf(pokemon):
    # FPDF Object
    pdf = FPDF("L", "mm", "A5")
    # Add page
    pdf.add_page()

    # Paint the background
    pdf.set_fill_color(*color.get(pokemon["type"][0], (255, )))
    pdf.rect(0, 0, 210, 297, "F")

    # Set font
    pdf.set_font(*fonts["title"])
    pdf.set_xy(20, 10)

    # Add Pokeball
    ball = {False: "pokeball", True: "masterball"}[pokemon["legendary"]]
    pdf.image(f"images/balls/{ball}.png", pdf.get_x(), pdf.get_y() + 25, w=20)

    # Add Pokemon Name
    pdf.cell(w=0,
             txt=f"{pokemon['id']} - {pokemon['name']}".title(),
             align="C",
             ln=1)

    # Add Pokemon Sprite
    pdf.image(pokemon["sprite_url"], 80, pdf.get_y() + 10, w=50)

    # Set new font
    font = fonts["flavor"]
    pdf.set_font(*font)
    pdf.set_xy(10, 70)

    # Cut text if larger than page
    flavor = chunks(pokemon["flavor"], font)

    # Add flavor text
    for i in flavor:
        pdf.cell(w=0, h=5, txt=i, align="C", ln=2)

    # Add type symbols
    for i, typ in enumerate(pokemon["type"]):
        if len(pokemon["type"]) == 1:
            pos = [90]
        else:
            pos = [50, 120]
        pdf.image(f"images/types/{typ}.png", pos[i], pdf.get_y() + 15, w=40)

    # Export pdf
    path = f"output/{pokemon['id']}_{pokemon['name']}.pdf"
    pdf.output(path)
    print(f"pdf saved to {path}")
示例#5
0
def createExercices(problems):
    exercises_per_column = 28
    columns = 5
    column_width = 50
    cell_height = 7
    number_width = 6
    spacer = 2

    pdf = FPDF(orientation="L")
    pdf.set_top_margin(5)
    pdf.set_auto_page_break(True, 1)
    pdf.add_page()
    pdf.set_font("Arial", size=12)

    start_x = pdf.get_x()
    start_y = pdf.get_y()

    for i in range(len(problems)):
        problem = problems[i]
        pdf.set_xy(start_x + int(i / exercises_per_column) * column_width,
                   start_y + (i % exercises_per_column) * cell_height)

        border = "R"
        if (int(i / exercises_per_column) == columns - 1):
            border = 0

        if (problem.unknown == UnknownElement.Z):
            pdf.cell(spacer, cell_height)
            pdf.cell(number_width, cell_height, txt=str(problem.x), align="C")
            pdf.cell(number_width,
                     cell_height,
                     txt=str(problem.operator),
                     align="C")
            pdf.cell(number_width, cell_height, txt=str(problem.y), align="C")
            pdf.cell(number_width, cell_height, "=", align="C")
            pdf.cell(column_width - 4 * number_width - spacer,
                     cell_height,
                     border=border)
        elif (problem.unknown == UnknownElement.X):
            pdf.cell(column_width - 4 * number_width - spacer, cell_height)
            pdf.cell(number_width,
                     cell_height,
                     txt=str(problem.operator),
                     align="C")
            pdf.cell(number_width, cell_height, txt=str(problem.y), align="C")
            pdf.cell(number_width, cell_height, "=", align="C")
            pdf.cell(number_width, cell_height, str(problem.z), align="C")
            pdf.cell(spacer, cell_height, border=border)

    pdf.output("simple_demo.pdf")
示例#6
0
        def pdf(list,length):
        
            desktop = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Desktop')
            pdf = FPDF()

            pdf.set_margins(4,5, 2)

            pdf.add_page()

            pdf.set_font("Times",'B', size=30)

            pdf.cell(200, 10, txt="Test Paper", ln=15, align="C")

 

            pdf.ln(5)

            pdf.set_font('Times', 'B', 20)

            pdf.cell(200, 10, txt="Short Answers", ln=15, align="C")

            pdf.ln(8)

            pdf.set_font('Times', 'I', 10)

            pdf.multi_cell(200, 10, txt="This test has been generated using the Questionnaire software.No answers are provided to the questions and it is upto the discretion of the candidate to decide upon the right answers.A short answer is of 3-4 sentences,so the answers should be brief",align ='J')

            pdf.ln(10)

            pdf.set_font('Times', 'B', 15)
        
        

            for i in range(length):

                pdf.multi_cell(200, 10, txt=str(i+1) + "." + "     " + list[i])

                pdf.ln(10)

                x = pdf.get_x()

                y = pdf.get_y()

                pdf.dashed_line(x,y,x+175,y,6)

                pdf.ln(10)
                
                
            pdf.output(desktop + "/" + "Questions" + ".pdf") 
示例#7
0
文件: fpdf_test.py 项目: rrnntt/pdf
 def test_pdf_cell(self):
     pdf=FPDF()
     pdf.c_margin = 0.0
     pdf.add_font('symbol','','font/DejaVuSans.ttf',uni=True)
     pdf.add_page()
     f = 0.81
     font_name = 'times'
     
     text = 'small text'
     pdf.set_font(font_name,'',12)
     x,y = pdf.get_x(), pdf.get_y()
     w = pdf.get_string_width(text)
     h = pdf.font_size_pt / pdf.k
     pdf.cell(w, h, text)
     pdf.rect(x, y, w, h, '')
     pdf.line(x, y + f * h, x + w, y + f * h)
     
     text = 'Large text'
     pdf.set_font(font_name,'',24)
     x,y = pdf.get_x(), pdf.get_y()
     w = pdf.get_string_width(text)
     h = pdf.font_size_pt / pdf.k
     pdf.cell(w,h, text)
     pdf.rect(x, y, w, h, '')
     pdf.line(x, y + f * h, x + w, y + f * h)
     
     text = 'Larger text'
     pdf.set_font(font_name,'',48)
     x,y = pdf.get_x(), pdf.get_y()
     w = pdf.get_string_width(text)
     h = pdf.font_size_pt / pdf.k
     pdf.cell(w,h, text)
     pdf.rect(x, y, w, h, '')
     pdf.line(x, y + f * h, x + w, y + f * h)
     
     pdf.output('out/fpdf/test_pdf_cell.pdf', 'F')
示例#8
0
    def makePDF(cls, PDFName):
        pdf = FPDF('P', 'mm', (220, 110))
        for supporter in cls.Supporters:
            print(supporter.preference)
            envelope = [1, 2, 3, 4, 6, 7, 8, 9]
            if supporter.preference in envelope:
                pdf.add_page()
                font_size = 20
                line_spacing = 8
                pdf.set_font('Arial', 'B', font_size)
                pdf.set_xy(20, 20)
                x_orig = pdf.get_x()
                y_orig = pdf.get_y()
                print(x_orig)
                print(y_orig)
                pdf.cell(40, 0, supporter.fullname)
                addrLines = supporter.address.split("\n")
                for i in range(0, len(addrLines)):
                    print(addrLines[i])
                    pdf.set_xy(x_orig, y_orig + line_spacing * (i + 1))
                    pdf.set_font('Arial', 'B', font_size)
                    pdf.cell(40, 0, addrLines[i])
                pdf.image('logo.jpg', 120, 35, 60, 60)
                pdf.set_font('Arial', '', 6)
                stamptext = ""
                if supporter.preference in [3, 4, 8, 9]:
                    stamptext = "Hand"
                elif supporter.preference in [1, 6]:
                    stamptext = "UK"
                elif supporter.preference in [2, 7]:
                    stamptext = "Int"
                pdf.set_xy(180, 12)
                pdf.cell(15, 20, stamptext, border=1, align='C')
                pdf.set_xy(180, 14)
                pdf.cell(15,
                         20,
                         "{}T {}P {}F".format(supporter.letters[0],
                                              supporter.letters[1],
                                              supporter.letters[2]),
                         border=0,
                         align='C')

        pdf.output(PDFName, 'F')
示例#9
0
    def __row(self, pdf: FPDF, row: DayGroupedEntry):
        default_height = self.__pdf_height(pdf)

        splits = split_string(row[4], 90)
        height = default_height * len(splits)

        pdf.cell(pdf.w * 0.08, height, txt=row[0], border=1)
        pdf.cell(pdf.w * 0.07, height, txt=row[1].__str__(), border=1)
        pdf.cell(pdf.w * 0.07, height, txt=row[2].__str__(), border=1)
        pdf.cell(pdf.w * 0.06, height, txt=row[3].__str__(), border=1)
        desc_w = pdf.w * 0.57
        if len(splits) > 1:
            current_x = pdf.get_x()
            current_y = pdf.get_y()
            pdf.multi_cell(desc_w, default_height, txt=row[4], border=1)
            pdf.set_xy(current_x + desc_w, current_y)
        else:
            pdf.cell(desc_w, height, txt=row[4], border=1)
        pdf.cell(pdf.w * 0.06, height, txt=row[5].__str__(), border=1)

        pdf.ln(height)
示例#10
0
class PDFHandler(expand.Expand):
    def __init__(self, gui):
        super().__init__()
        self.gui = gui
        self.styles = {}
        self.terminselections = {}
        self.tourselections = {}
        self.touren = []
        self.termine = []
        self.url = None
        self.margins = None
        self.linespacing = None
        self.linkType = None
        self.ausgabedatei = None
        self.pdf = None
        global debug
        try:
            _ = os.environ["DEBUG"]
            debug = True
        except:
            debug = False
        # testing
        self.gui.pdfTemplateName = "C:/Users/Michael/PycharmProjects/ADFC1/venv/src/template152.json"
        self.pdfExtension = PDFExtension()
        self.md = markdown.Markdown(extensions=[self.pdfExtension])
        if self.gui.pdfTemplateName is None or self.gui.pdfTemplateName == "":
            self.gui.pdfTemplate()
        if self.gui.pdfTemplateName is None or self.gui.pdfTemplateName == "":
            raise ValueError("must specify path to PDF template!")
        try:
            with open(self.gui.pdfTemplateName, "r", encoding="utf-8-sig") as jsonFile:
                self.pdfJS = json.load(jsonFile)
        except Exception as e:
            print(
                "Wenn Sie einen decoding-Fehler bekommen, öffnen Sie " + self.gui.pdfTemplateName + " mit notepad, dann 'Speichern unter' mit Codierung UTF-8")
            raise e
        self.parseTemplate()
        self.selFunctions = selektion.getSelFunctions()

    @staticmethod
    def nothingFound():
        logger.info("Nichts gefunden")
        print("Nichts gefunden")

    def parseTemplate(self):
        for key in ["pagesettings", "fonts", "styles", "selection", "text"]:
            if self.pdfJS.get(key) is None:
                raise ValueError("pdf template " + self.gui.pdfTemplateName + " must have a section " + key)
        pagesettings = self.pdfJS.get("pagesettings")
        leftMargin = pagesettings.get("leftmargin")
        rightMargin = pagesettings.get("rightmargin")
        topMargin = pagesettings.get("topmargin")
        bottomMargin = pagesettings.get("bottommargin")
        self.margins = (leftMargin, topMargin, rightMargin)
        self.linespacing = pagesettings.get("linespacing")  # float
        self.linkType = pagesettings.get("linktype")
        self.ausgabedatei = pagesettings.get("ausgabedatei")
        orientation = pagesettings.get("orientation")[0].upper()  # P or L
        pformat = pagesettings.get("format")
        self.pdf = FPDF(orientation, "mm", pformat)
        self.pageWidth = FPDF.get_page_format(pformat, 1.0)[0] / (72.0 / 25.4)
        self.pdf.add_page()
        self.pdf.set_margins(left=leftMargin, top=topMargin, right=rightMargin)
        self.pdf.set_auto_page_break(True, margin=bottomMargin)
        self.pdfExtension.pdfTreeHandler.setDeps(self)

        self.pdf.add_font("arialuc", "", expand.pyinst("_builtin_fonts/arial.ttf"), True)
        self.pdf.add_font("arialuc", "B", expand.pyinst("_builtin_fonts/arialbd.ttf"), True)
        self.pdf.add_font("arialuc", "BI", expand.pyinst("_builtin_fonts/arialbi.ttf"), True)
        self.pdf.add_font("arialuc", "I", expand.pyinst("_builtin_fonts/ariali.ttf"), True)

        fonts = self.pdfJS.get("fonts")
        for font in iter(fonts):
            family = font.get("family")
            if family is None or family == "":
                raise ValueError("font family not specified")
            file = font.get("file")
            if file is None or file == "":
                raise ValueError("font file not specified")
            fontStyle = font.get("fontstyle")
            if fontStyle is None:
                fontStyle = ""
            unicode = font.get("unicode")
            if unicode is None:
                unicode = True
            self.pdf.add_font(family, fontStyle, file, unicode)
        styles = self.pdfJS.get("styles")
        for style in iter(styles):
            name = style.get("name")
            if name is None or name == "":
                raise ValueError("style name not specified")
            typ = style.get("type")
            if typ is None:
                typ = "text"
            font = style.get("font")
            if font is None and typ != "image":
                raise ValueError("style font not specified")
            fontstyle = style.get("style")
            if fontstyle is None:
                fontstyle = ""
            size = style.get("size")
            if size is None and typ != "image":
                raise ValueError("style size not specified")
            color = style.get("color")
            if color is None:
                color = "0,0,0"  # black
            dimen = style.get("dimen")
            self.styles[name] = Style(name, typ, font, fontstyle, size, color, dimen)
        selection = self.pdfJS.get("selection")
        self.gliederung = selection.get("gliederung")
        if self.gliederung is None or self.gliederung == "":
            self.gliederung = self.gui.getGliederung()
        self.includeSub = selection.get("includesub")
        if self.includeSub is None:
            self.includeSub = self.gui.getIncludeSub()
        self.start = selection.get("start")
        if self.start is None or self.start == "":
            self.start = self.gui.getStart()
        self.end = selection.get("end")
        if self.end is None or self.end == "":
            self.end = self.gui.getEnd()
        sels = selection.get("terminselection")
        for sel in iter(sels):
            self.terminselections[sel.get("name")] = sel
            for key in sel.keys():
                if key != "name" and not isinstance(sel[key], list):
                    sel[key] = [sel[key]]
        sels = selection.get("tourselection")
        for sel in iter(sels):
            self.tourselections[sel.get("name")] = sel
            for key in sel.keys():
                if key != "name" and not isinstance(sel[key], list):
                    sel[key] = [sel[key]]

    def getIncludeSub(self):
        return self.includeSub

    def getEventType(self):
        if len(self.terminselections) != 0 and len(self.tourselections) != 0:
            return "Alles"
        if len(self.terminselections) != 0:
            return "Termin"
        if len(self.tourselections) != 0:
            return "Radtour"
        return self.gui.getEventType()

    def getRadTyp(self):
        rts = set()
        for sel in self.tourselections.values():
            l = sel.get("radtyp")
            if l is None or len(l) == 0:
                l = [self.gui.getRadTyp()]
            for elem in l:
                rts.add(elem)
        if "Alles" in rts:
            return "Alles"
        if len(rts) == 1:
            return rts[0]
        return "Alles"

    def getUnitKeys(self):
        return self.gliederung

    def getStart(self):
        return self.start

    def getEnd(self):
        return self.end

    def handleTour(self, tour):
        self.touren.append(tour)

    def handleTermin(self, termin):
        self.termine.append(termin)

    def handleEnd(self):
        print("Template", self.gui.pdfTemplateName, "wird abgearbeitet")
        if self.linkType is None or self.linkType == "":
            self.linkType = self.gui.getLinkType()
        lines = self.pdfJS.get("text")
        lineCnt = len(lines)
        lineNo = 0
        self.pdf.set_x(self.margins[0])  # left
        self.pdf.set_y(self.margins[1])  # top
        self.setStyle(self.styles.get("body"))
        self.pdf.cell(w=0, h=10, txt="", ln=1)
        while lineNo < lineCnt:
            line = lines[lineNo]
            if line.startswith("/comment"):
                lineNo += 1
                continue
            if line.startswith("/template"):
                t1 = lineNo
                lineNo += 1
                while not lines[lineNo].startswith("/endtemplate"):
                    lineNo += 1
                t2 = lineNo
                lineNo += 1
                tempLines = lines[t1:t2]  # /endtemplate not included
                self.evalTemplate(tempLines)
            else:
                self.evalLine(line, None)
                lineNo += 1
        if self.ausgabedatei is None or self.ausgabedatei == "":
            self.ausgabedatei = self.gui.pdfTemplateName.rsplit(".", 1)[0] + "_" + self.linkType[0] + ".pdf"
        self.pdf.output(dest='F', name=self.ausgabedatei)
        print("Ausgabedatei", self.ausgabedatei, "wurde erzeugt")
        try:
            opath = os.path.abspath(self.ausgabedatei)
            os.startfile(opath)
        except Exception:
            logger.exception("opening " + self.ausgabedatei)

    def simpleNl(self):
        x = self.pdf.get_x()
        if x > self.margins[0]:
            self.pdf.ln()

    def extraNl(self):
        self.simpleNl()
        self.pdf.ln()

    def evalLine(self, line, event):
        if line.strip() == "":
            self.extraNl()
            return
        global debug
        if debug:
            print("line", line)
        text = []
        self.align = "L"
        self.fontStyles = ""
        self.curStyle = self.styles.get("body")
        self.indentX = 0.0
        words = line.split()
        l = len(words)
        last = l - 1
        for i in range(l):
            word = words[i]
            if word.startswith("/"):
                cmd = word[1:]
                if cmd in self.styles.keys():
                    self.handleText("".join(text), event)
                    text = []
                    self.curStyle = self.styles.get(cmd)
                elif cmd in ["right", "left", "center", "block"]:
                    self.handleText("".join(text), event)
                    text = []
                    self.align = cmd[0].upper()
                    if self.align == 'B':
                        self.align = 'J'  # justification
                elif cmd in ["bold", "italic", "underline"]:
                    self.handleText("".join(text), event)
                    text = []
                    self.fontStyles += cmd[0].upper()
                else:
                    if i < last:
                        word = word + " "
                    text.append(word)
            else:
                word = word.replace("\uaffe", "\n")
                if i < last:
                    word = word + " "
                text.append(word)
        self.handleText("".join(text), event)
        self.simpleNl()

    def evalTemplate(self, lines):
        global debug
        if debug:
            print("template:")
        words = lines[0].split()
        typ = words[1]
        if typ != "/tour" and typ != "/termin":
            raise ValueError("second word after /template must be /tour or /termin")
        typ = typ[1:]
        sel = words[2]
        if not sel.startswith("/selection="):
            raise ValueError("third word after /template must start with /selection=")
        sel = sel[11:]
        sels = self.tourselections if typ == "tour" else self.terminselections
        if sel not in sels:
            raise ValueError("selection " + sel + " not in " + typ + "selections")
        sel = sels[sel]
        events = self.touren if typ == "tour" else self.termine
        self.evalEvents(sel, events, lines[1:])

    def evalEvents(self, sel, events, lines):
        selectedEvents = []
        for event in events:
            if selektion.selected(event, sel):
                selectedEvents.append(event)
        if len(selectedEvents) == 0:
            return
        lastEvent = selectedEvents[-1]
        for event in selectedEvents:
            for line in lines:
                if line.startswith("/comment"):
                    continue
                self.evalLine(line, event)
            if event != lastEvent:  # extra line between events, not after the last one
                self.evalLine("", None)

    def handleText(self, s: str, event):
        s = self.expand(s, event)
        if s is None or s == "":
            return
        # print("Text:", s)
        if self.curStyle.type == "image":
            self.drawImage(expand.pyinst(s))
            return
        style = self.curStyle.copy()
        for fs in self.fontStyles:
            if style.fontStyle.find(fs) == -1:
                style.fontStyle += fs
        # self.fontStyles = ""
        self.setStyle(style)
        h = (style.size * 0.35278 + self.linespacing)
        if self.align == 'J':
            self.pdf.multi_cell(w=0, h=h, txt=s, border=0, align=self.align, fill=0)
        elif self.align == 'R':
            self.pdf.cell(w=0, h=h, txt=s, border=0, ln=0, align=self.align, fill=0, link=self.url)
        else:
            try:
                w = self.pdf.get_string_width(s)
            except Exception:
                w = 0
            x = self.pdf.get_x()
            if (x + w) >= (self.pageWidth - self.margins[2]):  # i.e. exceeds right margin
                self.multiline(h, s)
            else:
                self.pdf.cell(w=w, h=h, txt=s, border=0, ln=0, align=self.align, fill=0, link=self.url)
            # x = self.pdf.get_x()
        self.url = None

    def multiline(self, h: float, s: str):
        """ line too long, see if I can split line after blank """
        x = self.pdf.get_x()
        l = len(s)
        # TODO limit l so that we do not    search too long for a near enough blank
        while l > 0:
            w = self.pdf.get_string_width(s)
            if (x + w) < (self.pageWidth - 1 - self.margins[2]):
                self.pdf.cell(w=w, h=h, txt=s, border=0, ln=0, align=self.align, fill=0, link=self.url)
                # x = self.pdf.get_x()
                return
            nlx = s.find("\n", 0, l)
            lb = s.rfind(' ', 0, l)  # last blank
            if 0 <= nlx < lb:
                lb = nlx + 1
            if lb == -1:  # can not split line
                if x > self.margins[0]:
                    self.pdf.ln()
                    if self.indentX > 0.0:
                        self.pdf.set_x(self.indentX)
                    x = self.pdf.get_x()
                    l = len(s)
                    continue
                else:  # emergency, can not split line
                    w = self.pdf.get_string_width(s)
                    self.pdf.cell(w=w, h=h, txt=s, border=0, ln=1, align=self.align, fill=0, link=self.url)
                    return
            sub = s[0:lb]
            w = self.pdf.get_string_width(sub)
            if (x + w) >= (self.pageWidth - 1 - self.margins[2]):
                l = lb
                continue
            self.pdf.cell(w=w, h=h, txt=sub, border=0, ln=0, align=self.align, fill=0, link=self.url)
            x = self.pdf.get_x()
            s = s[lb + 1:]
            w = self.pdf.get_string_width(s)
            if x > self.margins[0] and (x + w) >= (self.pageWidth - 1 - self.margins[2]):
                self.pdf.ln()
                if self.indentX > 0.0:
                    self.pdf.set_x(self.indentX)
                x = self.pdf.get_x()
            l = len(s)

    def setStyle(self, style: Style):
        # print("Style:", style)
        self.pdf.set_font(style.font, style.fontStyle, style.size)
        rgb = style.color.split(',')
        self.pdf.set_text_color(int(rgb[0]), int(rgb[1]), int(rgb[2]))

    def drawImage(self, imgName: str):
        style = self.curStyle
        dimen = style.dimen  # 60x40, wxh
        wh = dimen.split('x')
        w = int(wh[0])
        h = int(wh[1])
        x = self.pdf.get_x()
        y = self.pdf.get_y()
        if self.align == 'R':
            x = self.pageWidth - self.margins[2] - w - 10
        y -= h  # align lower edge of image with baseline of text (or so)
        if y < self.margins[1]:
            y = self.margins[1]
        self.pdf.image(imgName.strip(), x=x, y=y, w=w)  # h=h
        self.pdf.set_y(self.pdf.get_y() + 7)

    def expBeschreibung(self, tour, _):
        desc = tour.getBeschreibung(True)
        # desc = codecs.decode(desc, encoding = "unicode_escape")
        self.md.convert(desc)
        self.md.reset()
        return None

    def expTourLeiter(self, tour, _):
        tl = tour.getPersonen()
        if len(tl) == 0:
            return
        self.evalLine("/bold Tourleiter: /block " + "\uaffe".join(tl), tour)

    def expAbfahrten(self, tour, _):
        afs = tour.getAbfahrten()
        if len(afs) == 0:
            return
        afl = [af[0] + " " + af[1] + " " + af[2] for af in afs]
        self.evalLine("/bold Ort" + ("" if len(afs) == 1 else "e") + ": /block " + "\uaffe".join(afl), tour)

    def expBetreuer(self, termin, _):
        tl = termin.getPersonen()
        if len(tl) == 0:
            return
        self.evalLine("/bold Betreuer: /block " + "\uaffe".join(tl), termin)

    def expZusatzInfo(self, tour, _):
        zi = tour.getZusatzInfo()
        if len(zi) == 0:
            return
        self.evalLine("/bold Zusatzinfo: /block " + "\uaffe".join(zi), tour)

    """
pdf.add_page()
pdf.set_margins(20, 20, 10)

# document title
pdf.set_font("Times", "B", size=14)
pdf.cell(0, 10, txt=title_1, align="C", ln=1)

# document content
pdf.set_font("Times", "I", size=12)
pdf.cell(0, 7, txt=subtitle_1, ln=2)

# bullet points of content
pdf.set_font("Times", size=12)
pdf.set_xy(70.00, 40.00)
pdf.cell(0, 0, bullet_1, (pdf.get_x(), pdf.get_y()), ln=1)
pdf.set_xy(70.00, 47.00)
pdf.cell(0, 0, bullet_2, (pdf.get_x(), pdf.get_y()), ln=1)
# pdf.set_xy(30.00, 52.00)
# pdf.cell(0,0,bullet_3,(pdf.get_x(), pdf.get_y()), ln=1)
# pdf.set_xy(30.00, 59.00)
# pdf.cell(0,0,bullet_4,(pdf.get_x(), pdf.get_y()), ln=1)

# introduction section
pdf.set_font("Times", size=12)
pdf.set_xy(20.00, 52.00)
pdf.multi_cell(0, 7, text_1, (pdf.get_x(), pdf.get_y()))

# boxplot description
pdf.set_font("Times", "I", size=12)
pdf.cell(200, 7, txt=subtitle_2, ln=2)
示例#12
0
class PDFPrinter:
    PAGE_FORMAT = 'A4'
    UNIT = 'mm'
    MARGIN = 10
    CONTENT_WIDTH = 297 - 2 * MARGIN
    CONTENT_HEIGHT = 210 - 2 * MARGIN
    HEADER_HEIGHT = 30
    NOTES_HEIGHT = 17
    TABLE_HEIGHT = CONTENT_HEIGHT - HEADER_HEIGHT - NOTES_HEIGHT
    FONT_S = 7
    FONT_XS = 6.5

    def __init__(self):
        self.colors = {}
        self.timelinesCount = None
        self.fontSize = 12
        self.textColor = Color.WHITE

        self.pdf = FPDF(orientation='L',
                        unit=PDFPrinter.UNIT,
                        format=PDFPrinter.PAGE_FORMAT)
        self.pdf.add_font('regular',
                          '',
                          os.path.join('fonts', 'ubuntu', 'Ubuntu-B.ttf'),
                          uni=True)
        self.pdf.add_font('condensed',
                          '',
                          os.path.join('fonts', 'roboto',
                                       'RobotoCondensed-Regular.ttf'),
                          uni=True)
        self.pdf.add_font('italic',
                          '',
                          os.path.join('fonts', 'roboto',
                                       'RobotoCondensed-Bold.ttf'),
                          uni=True)
        self.pdf.set_font("regular", size=self.fontSize)
        self.pdf.add_page()
        self.pdf.set_margins(PDFPrinter.MARGIN, PDFPrinter.MARGIN,
                             PDFPrinter.MARGIN)

        self.uglyMeasure = FPDF(orientation='L',
                                unit=PDFPrinter.UNIT,
                                format=PDFPrinter.PAGE_FORMAT)
        self.uglyMeasure.add_font('regular',
                                  '',
                                  os.path.join('fonts', 'ubuntu',
                                               'Ubuntu-B.ttf'),
                                  uni=True)
        self.uglyMeasure.add_font('condensed',
                                  '',
                                  os.path.join('fonts', 'roboto',
                                               'RobotoCondensed-Regular.ttf'),
                                  uni=True)
        self.uglyMeasure.add_font('italic',
                                  '',
                                  os.path.join('fonts', 'roboto',
                                               'RobotoCondensed-Bold.ttf'),
                                  uni=True)
        self.uglyMeasure.set_font("regular", size=self.fontSize)
        self.uglyMeasure.add_page()

    def defineColor(self, key, color):
        hex = color.lstrip('#')
        self.colors[key.lower()] = tuple(
            int(hex[i:i + 2], 16) for i in (0, 2, 4))

    def printHeader(self, names):
        self.timelinesCount = len(names)
        boxWidth = PDFPrinter.CONTENT_WIDTH / self.timelinesCount

        boxPos = 0
        for name in names:
            color = self.colors[name.lower()]
            x = PDFPrinter.MARGIN + boxWidth * boxPos
            y = PDFPrinter.MARGIN
            w = boxWidth
            h = 7

            self._box(x,
                      y,
                      w,
                      h,
                      color=color,
                      lineColor=Color.BLACK,
                      lineWidth=0.1)
            self._text(x,
                       y,
                       w,
                       h,
                       text=name,
                       color=self.textColor,
                       font='regular',
                       size=self.fontSize)

            boxPos += 1

    def printTimetable(self, timetable):
        colCount = len(timetable.keys())
        colWidth = PDFPrinter.CONTENT_WIDTH / colCount

        tablePositionY = 30
        tableHeight = PDFPrinter.TABLE_HEIGHT + 1
        tableHeaderHeight = 7
        timelineRowHeight = tableHeight - tableHeaderHeight
        timelineRowPositionY = tablePositionY + tableHeaderHeight

        timeBlockWidth = (colWidth - 2) / self.timelinesCount
        timeWindow = self._findTimeWindow(timetable)
        yPerMin = (timelineRowHeight - 2) / (timeWindow["toTime"] -
                                             timeWindow["fromTime"])

        colNo = 0
        for key, schedules in timetable.items():
            x = PDFPrinter.MARGIN + colWidth * colNo

            self._box(x=x,
                      y=tablePositionY,
                      w=colWidth,
                      h=tableHeaderHeight,
                      color=Color.LIGHT_GREY,
                      lineColor=Color.BLACK,
                      lineWidth=0.2)
            self._text(x=x,
                       y=tablePositionY,
                       w=colWidth,
                       h=tableHeaderHeight,
                       text=key,
                       color=Color.BLACK,
                       font='regular',
                       size=self.fontSize)
            self._box(x=x,
                      y=timelineRowPositionY,
                      w=colWidth,
                      h=timelineRowHeight,
                      color=None,
                      lineColor=Color.BLACK,
                      lineWidth=0.2)

            self._drawTimeblocks(schedules,
                                 areaWidth=timeBlockWidth,
                                 areaPositionX=x,
                                 areaPositionY=timelineRowPositionY + 0.8,
                                 scaleY=yPerMin,
                                 timeWindowStart=timeWindow["fromTime"])

            colNo += 1

    def _drawTimeblocks(self, schedules, areaWidth, areaPositionX,
                        areaPositionY, scaleY, timeWindowStart):
        timeBlockNo = 0

        for person, timelines in schedules.items():
            blockColor = self.colors[person.lower()]
            blockPositionX = areaPositionX + areaWidth * timeBlockNo + 0.5 * timeBlockNo + 0.5

            for timeline in timelines:
                fromTimePosY = scaleY * (self._timeToInt(timeline.fromTime) -
                                         timeWindowStart) + 0.4
                blockPositionY = areaPositionY + fromTimePosY
                blockHeight = scaleY * (self._timeToInt(timeline.toTime) -
                                        timeWindowStart) - fromTimePosY

                self._box(x=blockPositionX,
                          y=blockPositionY,
                          w=areaWidth,
                          h=blockHeight,
                          color=blockColor,
                          lineColor=None)

                if (timeline.kind == "~"):
                    self._drawLeftLines(x=blockPositionX,
                                        y=blockPositionY,
                                        w=areaWidth,
                                        h=blockHeight)
                elif (timeline.kind == "d"):
                    self._drawTwoRightLines(x=blockPositionX,
                                            y=blockPositionY,
                                            w=areaWidth,
                                            h=blockHeight)
                elif (timeline.kind == "e"):
                    self._drawEmptyRightCorner(x=blockPositionX,
                                               y=blockPositionY,
                                               w=areaWidth,
                                               h=blockHeight)

                self._drawTimeblockLabels(areaX=blockPositionX,
                                          areaY=blockPositionY,
                                          areaW=areaWidth,
                                          areaH=blockHeight,
                                          timeline=timeline,
                                          backColor=blockColor)

            timeBlockNo += 1

    def _drawLeftLines(self, x, y, w, h):
        hw = h / w

        posX = x
        posXM = x + w
        posY = y
        posYM = y + h
        jump = 3
        while (posXM > x):
            posX += jump
            posXM -= jump
            posY += jump * hw
            posYM -= jump * hw

            if jump == 2:
                jump = 0.5
            else:
                jump = 2

            if (posX < x + w and posY < y + h):
                self._line(posX, y, x, posY, Color.WHITE, lineWidth=0.2)
            if (posXM > x and posYM > y):
                self._line(posXM,
                           y + h,
                           x + w,
                           posYM,
                           Color.WHITE,
                           lineWidth=0.2)

    def _drawTwoRightLines(self, x, y, w, h):
        hw = h / w

        posX = x
        posXM = x + w
        posY = y
        posYM = y + h
        jump = 2
        for _ in range(4):
            posX += jump
            posXM -= jump
            posY += jump * hw
            posYM -= jump * hw

            # if jump == 2:
            #     jump = 0.7
            # else:
            #     jump = 2

            if (posX < x + w and posY < y + h):
                self._line(posX, y + h, x, posYM, Color.WHITE, lineWidth=0.3)
            if (posXM > x and posYM > y):
                self._line(posXM, y, x + w, posY, Color.WHITE, lineWidth=0.3)

    def _drawEmptyRightCorner(self, x, y, w, h):
        hw = h / w

        posX = x
        posXM = x + w
        posY = y
        posYM = y + h
        jump = 1
        for p in range(9):
            posX += jump
            posXM -= jump
            posY += jump * hw
            posYM -= jump * hw

            if p > 5:
                jump = 1
            else:
                jump = 0.2

            if (posX < x + w and posY < y + h):
                self._line(posX, y + h, x, posYM, Color.WHITE, lineWidth=0.2)
            if (posXM > x and posYM > y):
                self._line(posXM, y, x + w, posY, Color.WHITE, lineWidth=0.2)

    def _drawTimeblockLabels(self, areaX, areaY, areaW, areaH, timeline,
                             backColor):
        label = []
        if (timeline.name):
            label.append(timeline.name.upper())
        for component in timeline.components:
            label.append(component.upper())

        if (label):
            self._textBlock(x=areaX,
                            y=areaY,
                            w=areaW,
                            h=areaH,
                            textLines=label,
                            color=Color.WHITE,
                            font='condensed',
                            size=PDFPrinter.FONT_XS,
                            align='C',
                            backColor=backColor)
        if (timeline.fromTime):
            textSize = self._measure(text=timeline.fromTime,
                                     font='italic',
                                     size=PDFPrinter.FONT_S)
            self._text(x=areaX,
                       y=areaY - 1,
                       w=areaW / 2,
                       h=textSize.y,
                       text=timeline.fromTime,
                       color=Color.WHITE,
                       font='italic',
                       size=PDFPrinter.FONT_S,
                       align='L',
                       backColor=backColor)
        if (timeline.toTime):
            textSize = self._measure(text=timeline.toTime,
                                     font='italic',
                                     size=PDFPrinter.FONT_S)
            self._text(x=areaX + areaW / 2,
                       y=areaY + areaH - textSize.y + 1,
                       w=areaW / 2,
                       h=textSize.y,
                       text=timeline.toTime,
                       color=Color.WHITE,
                       font='italic',
                       size=PDFPrinter.FONT_S,
                       align='R',
                       backColor=backColor)

    def printNotes(self, notes):
        x = PDFPrinter.MARGIN
        y = PDFPrinter.MARGIN + PDFPrinter.HEADER_HEIGHT + PDFPrinter.TABLE_HEIGHT
        w = PDFPrinter.CONTENT_WIDTH
        h = 5

        for note in notes:
            y += h
            self._text(x,
                       y,
                       w,
                       0,
                       text=note,
                       color=Color.BLACK,
                       font='regular',
                       size=self.fontSize,
                       align='L')

    def save(self, fileName):
        self.pdf.output(fileName)

    def _measure(self, text, font, size):
        self.uglyMeasure.set_font(font, size=size)
        self.uglyMeasure.set_xy(0, 0)
        self.uglyMeasure.write(size / 2.83, txt=text)
        sizeX = self.uglyMeasure.get_x()
        self.uglyMeasure.write(size / 2.83, txt="\n")
        sizeY = self.uglyMeasure.get_y()

        result = Size(sizeX, sizeY)
        return result

    def _text(self,
              x,
              y,
              w,
              h,
              text,
              color,
              font,
              size,
              align='C',
              backColor=None):
        self.pdf.set_text_color(color[0], color[1], color[2])
        self.pdf.set_font(font, size=size)
        self.pdf.set_xy(x, y)
        fillBackground = False
        if (backColor):
            self.pdf.set_fill_color(backColor[0], backColor[1], backColor[2])
            fillBackground = True
        self.pdf.cell(w, h, txt=text, ln=1, align=align, fill=fillBackground)

    def _textBlock(self,
                   x,
                   y,
                   w,
                   h,
                   textLines,
                   color,
                   font,
                   size,
                   align='C',
                   backColor=None):
        textH = 0
        texts = []
        for line in textLines:
            textSize = self._measure(text=line, font=font, size=size)
            textSize.y += 1
            textH += textSize.y

            texts.append({"txt": line, "height": textSize.y})

        self.pdf.set_text_color(color[0], color[1], color[2])
        self.pdf.set_font(font, size=size)

        posY = y + (h - textH) / 2

        fillBackground = False
        if (backColor):
            self.pdf.set_fill_color(backColor[0], backColor[1], backColor[2])
            fillBackground = True

        for line in texts:
            self.pdf.set_xy(x, posY)
            self.pdf.cell(w,
                          line["height"],
                          txt=line["txt"],
                          align=align,
                          fill=fillBackground)

            posY += line["height"]

    def _box(self, x, y, w, h, color, lineColor, lineWidth=0):
        style = ''

        if (lineColor):
            self.pdf.set_line_width(lineWidth)
            self.pdf.set_draw_color(lineColor[0], lineColor[1], lineColor[2])
            style += 'D'

        if (color):
            self.pdf.set_fill_color(color[0], color[1], color[2])
            style += 'F'

        self.pdf.rect(x, y, w, h, style)

    def _line(self, x1, y1, x2, y2, color, lineWidth):
        self.pdf.set_line_width(lineWidth)
        self.pdf.set_draw_color(color[0], color[1], color[2])

        self.pdf.line(x1, y1, x2, y2)

    def _findTimeWindow(self, timetable):
        minTime = self._timeToInt("24:00")
        maxTime = self._timeToInt("00:00")

        for daySchedule in timetable.values():
            for personalSchedule in daySchedule.values():
                for schedule in personalSchedule:
                    f = self._timeToInt(schedule.fromTime)
                    t = self._timeToInt(schedule.toTime)

                    minTime = min(minTime, f, t)
                    maxTime = max(maxTime, f, t)

        return {"fromTime": minTime, "toTime": maxTime}

    def _timeToInt(self, str):
        parts = str.split(':')
        return int(parts[0]) * 60 + int(parts[1])
示例#13
0
# for first table
pdf.set_font('Times', '', 12)
pdf.set_draw_color(128, 128, 128)

th = pdf.font_size

for row in test_case_related_info:
    # print(ybefore, '---', xbefore)
    for datum in row:
        # Enter data in columns
        # Notice the use of the function str to coerce any input to the
        # string type. This is needed
        # since pyFPDF expects a string, not a number.
        # pdf.cell(col_width, 1.5 * th, str(row), border=1)
        ybefore = pdf.get_y()
        xbefore = pdf.get_x()
        pdf.multi_cell(test_col_width,
                       2 * th,
                       str(datum),
                       align='C',
                       border=0,
                       fill=1)
        pdf.set_xy(test_col_width + xbefore, ybefore)
    pdf.ln(2 * th)

pdf.ln(25)

# feature case heading
pdf.set_font('Times', '', 12)
pdf.cell(0, 7, 'Feature Related Info-', 1, 1, 'L', fill=1)
pdf.ln(5)
def export_full_to_pdf(schedule_ref: Schedule,
                       title_text: str,
                       file_path: str,
                       font_name: str,
                       font_path: str,
                       encoding: str,
                       progress=None) -> None:
    """
    Method for exports to PDF file
    """
    file = QFileInfo(file_path)

    # pdf
    pdf = FPDF(orientation="L")

    # encoding
    if encoding == "UTF-8":
        pdf.add_font(font_name, "", font_path, uni=True)
    else:
        pdf.add_font(font_name, "", font_path)
        pdf.set_doc_option("core_fonts_encoding", encoding)

    pdf.set_font(font_name)
    pdf.add_page()

    x, y = float(pdf.get_x()), float(pdf.get_y())
    w = float(pdf.w) - 2 * float(pdf.get_x())
    h = float(pdf.h) - 2 * float(pdf.get_y()) - 6

    pdf.set_auto_page_break(True, margin=y)

    title = 10

    pdf.set_font_size(14)
    pdf.cell(w, title, txt=title_text, align="C", border=0)
    h -= title

    first_column, first_row = 4, 4

    step_column = (w - first_row) / 8
    step_row = (h - first_column) / 6

    indexes = schedule_ref.indexes()
    table_widget = schedule_editor_window.ScheduleTableWidget()
    table_widget.set_schedule(schedule_ref)

    # processing
    week_step = 100 / 7
    count = 0

    i = 0
    while i < 7:
        j = 0
        while j < 9:
            if i == 0 and j == 0:
                # upper-left cell
                pdf.set_xy(x, y + title)
                pdf.cell(first_column, first_row, border=1)
                j += 1
            elif i == 0:
                # top cells with time
                pdf.set_xy(x + first_row + step_column * (j - 1), y + title)
                pdf.set_font_size(8)
                pdf.cell(step_column,
                         first_row,
                         txt=TimePair.time_start_end(j - 1),
                         align="C",
                         border=1)
                j += 1
            elif j == 0:
                # left cells with days of the week
                pdf.set_xy(
                    x,
                    y + title + first_column + step_row * (i - 1) + step_row)
                pdf.rotate(90)
                pdf.set_font_size(8)
                pdf.cell(step_row,
                         first_row,
                         txt=str(DaysOfWeek.value_of(i - 1)),
                         align="C",
                         border=1)
                pdf.rotate(0)
                j += 1
            else:
                # cells inside the table
                pdf.set_xy(x + first_row + step_column * (j - 1),
                           y + title + first_column + step_row * (i - 1))

                simple_row = (step_row / indexes[i - 1])
                prev_x, prev_y = pdf.get_x(), pdf.get_y()

                start_index = sum(indexes[r] for r in range(i - 1))
                number_row = 0
                for m in range(start_index, start_index + indexes[i - 1]):
                    item = table_widget.item(m, j - 1)
                    if item is not None:
                        x_span_count = table_widget.columnSpan(m, j - 1)
                        y_span_count = table_widget.rowSpan(m, j - 1)

                        pdf.set_xy(prev_x, prev_y + number_row * simple_row)

                        pdf.cell(step_column * x_span_count,
                                 simple_row * y_span_count,
                                 border=1)

                        text = item.text()
                        if text != "":
                            draw_text(
                                pdf, x + first_row + step_column * (j - 1),
                                y + title + first_column + step_row * (i - 1) +
                                simple_row * number_row,
                                step_column * x_span_count,
                                simple_row * y_span_count, text)
                    number_row += 1
                    pdf.set_xy(prev_x, prev_y)
                j += 1
        i += 1

        if progress is not None:
            count += 1
            progress.setValue(week_step * count)
            if progress.wasCanceled():
                break

    pdf.output(file.absoluteFilePath())
示例#15
0
class Report:
    def __init__(self, data):
        self.output_path = os.path.join(data.data_path, "stats")
        self.dataset_name = os.path.basename(data.data_path)

        self.mapi_light_light_green = [210, 245, 226]
        self.mapi_light_green = [5, 203, 99]
        self.mapi_light_grey = [218, 222, 228]
        self.mapi_dark_grey = [99, 115, 129]

        self.pdf = FPDF("P", "mm", "A4")
        self.pdf.add_page()

        self.title_size = 20
        self.h1 = 16
        self.h2 = 13
        self.h3 = 10
        self.text = 10
        self.small_text = 8
        self.margin = 10
        self.cell_height = 7
        self.total_size = 190

        self.stats = self._read_stats_file("stats.json")

    def save_report(self, filename):
        self.pdf.output(os.path.join(self.output_path, filename), "F")

    def _make_table(self, columns_names, rows, row_header=False):
        self.pdf.set_font("Helvetica", "", self.h3)
        self.pdf.set_line_width(0.3)

        columns_sizes = [int(self.total_size / len(rows[0]))] * len(rows[0])

        if columns_names:
            self.pdf.set_draw_color(*self.mapi_light_grey)
            self.pdf.set_fill_color(*self.mapi_light_grey)
            for col, size in zip(columns_names, columns_sizes):
                self.pdf.rect(
                    self.pdf.get_x(),
                    self.pdf.get_y(),
                    size,
                    self.cell_height,
                    style="FD",
                )
                self.pdf.set_text_color(*self.mapi_dark_grey)
                self.pdf.cell(size, self.cell_height, col, align="L")
            self.pdf.set_xy(self.margin, self.pdf.get_y() + self.cell_height)

        self.pdf.set_draw_color(*self.mapi_light_grey)
        self.pdf.set_fill_color(*self.mapi_light_light_green)

        for row in rows:
            for i, (col, size) in enumerate(zip(row, columns_sizes)):
                if i == 0 and row_header:
                    self.pdf.set_draw_color(*self.mapi_light_grey)
                    self.pdf.set_fill_color(*self.mapi_light_grey)
                self.pdf.rect(
                    self.pdf.get_x(),
                    self.pdf.get_y(),
                    size,
                    self.cell_height,
                    style="FD",
                )
                self.pdf.set_text_color(*self.mapi_dark_grey)
                if i == 0 and row_header:
                    self.pdf.set_draw_color(*self.mapi_light_grey)
                    self.pdf.set_fill_color(*self.mapi_light_light_green)
                self.pdf.cell(size, self.cell_height, col, align="L")
            self.pdf.set_xy(self.margin, self.pdf.get_y() + self.cell_height)

    def _read_stats_file(self, filename):
        file_path = os.path.join(self.output_path, filename)
        with io.open_rt(file_path) as fin:
            return io.json_load(fin)

    def _make_section(self, title):
        self.pdf.set_font("Helvetica", "B", self.h1)
        self.pdf.set_text_color(*self.mapi_dark_grey)
        self.pdf.cell(0, self.margin, title, align="L")
        self.pdf.set_xy(self.margin, self.pdf.get_y() + 1.5 * self.margin)

    def _make_subsection(self, title):
        self.pdf.set_xy(self.margin, self.pdf.get_y() - 0.5 * self.margin)
        self.pdf.set_font("Helvetica", "B", self.h2)
        self.pdf.set_text_color(*self.mapi_dark_grey)
        self.pdf.cell(0, self.margin, title, align="L")
        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def _make_centered_image(self, image_path, desired_height):
        width, height = PIL.Image.open(image_path).size
        resized_width = width * desired_height / height
        if resized_width > self.total_size:
            resized_width = self.total_size
            desired_height = height * resized_width / width

        self.pdf.image(
            image_path,
            self.pdf.get_x() + self.total_size / 2 - resized_width / 2,
            self.pdf.get_y(),
            h=desired_height,
        )
        self.pdf.set_xy(self.margin,
                        self.pdf.get_y() + desired_height + self.margin)

    def make_title(self):
        # title
        self.pdf.set_font("Helvetica", "B", self.title_size)
        self.pdf.set_text_color(*self.mapi_light_green)
        self.pdf.cell(0, self.margin, "OpenSfM Quality Report", align="C")
        self.pdf.set_xy(self.margin, self.title_size)

        # version number
        try:
            out, _ = subprocess.Popen(
                ["git", "describe", "--tags"],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
            ).communicate()
            version = out.strip().decode()
        except BaseException as e:
            logger.warning(
                f"Exception thrwon while extracting 'git' version, {e}")
            version = ""

        # indicate we don't know the version
        version = "unknown" if version == "" else version

        self.pdf.set_font("Helvetica", "", self.small_text)
        self.pdf.set_text_color(*self.mapi_dark_grey)
        self.pdf.cell(0,
                      self.margin,
                      f"Processed with OpenSfM version {version}",
                      align="R")
        self.pdf.set_xy(self.margin, self.pdf.get_y() + 2 * self.margin)

    def make_dataset_summary(self):
        self._make_section("Dataset Summary")

        rows = [
            ["Dataset", self.dataset_name],
            ["Date", self.stats["processing_statistics"]["date"]],
            [
                "Area Covered",
                f"{self.stats['processing_statistics']['area']/1e6:.6f} km²",
            ],
            [
                "Processing Time",
                f"{self.stats['processing_statistics']['steps_times']['Total Time']:.2f} seconds",
            ],
        ]
        self._make_table(None, rows, True)
        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def _has_meaningful_gcp(self):
        return (self.stats["reconstruction_statistics"]["has_gcp"]
                and "average_error" in self.stats["gcp_errors"])

    def make_processing_summary(self):
        self._make_section("Processing Summary")

        rec_shots, init_shots = (
            self.stats["reconstruction_statistics"]
            ["reconstructed_shots_count"],
            self.stats["reconstruction_statistics"]["initial_shots_count"],
        )
        rec_points, init_points = (
            self.stats["reconstruction_statistics"]
            ["reconstructed_points_count"],
            self.stats["reconstruction_statistics"]["initial_points_count"],
        )

        geo_string = []
        if self.stats["reconstruction_statistics"]["has_gps"]:
            geo_string.append("GPS")
        if self._has_meaningful_gcp():
            geo_string.append("GCP")

        rows = [
            [
                "Reconstructed Images",
                f"{rec_shots} over {init_shots} shots ({rec_shots/init_shots*100:.1f}%)",
            ],
            [
                "Reconstructed Points",
                f"{rec_points} over {init_points} points ({rec_points/init_points*100:.1f}%)",
            ],
            [
                "Reconstructed Components",
                f"{self.stats['reconstruction_statistics']['components']} component",
            ],
            [
                "Detected Features",
                f"{self.stats['features_statistics']['detected_features']['median']} features",
            ],
            [
                "Reconstructed Features",
                f"{self.stats['features_statistics']['reconstructed_features']['median']} features",
            ],
            ["Geographic Reference", " and ".join(geo_string)],
        ]

        row_gps_gcp = [" / ".join(geo_string) + " errors"]
        geo_errors = []
        if self.stats["reconstruction_statistics"]["has_gps"]:
            geo_errors.append(
                f"{self.stats['gps_errors']['average_error']:.2f}")
        if self._has_meaningful_gcp():
            geo_errors.append(
                f"{self.stats['gcp_errors']['average_error']:.2f}")
        row_gps_gcp.append(" / ".join(geo_errors) + " meters")
        rows.append(row_gps_gcp)

        self._make_table(None, rows, True)
        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)

        topview_height = 130
        topview_grids = [
            f for f in os.listdir(self.output_path) if f.startswith("topview")
        ]
        self._make_centered_image(
            os.path.join(self.output_path, topview_grids[0]), topview_height)

        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def make_processing_time_details(self):
        self._make_section("Processing Time Details")

        columns_names = list(
            self.stats["processing_statistics"]["steps_times"].keys())
        formatted_floats = []
        for v in self.stats["processing_statistics"]["steps_times"].values():
            formatted_floats.append(f"{v:.2f} sec.")
        rows = [formatted_floats]
        self._make_table(columns_names, rows)
        self.pdf.set_xy(self.margin, self.pdf.get_y() + 2 * self.margin)

    def make_gps_details(self):
        self._make_section("GPS/GCP Errors Details")

        # GPS
        for error_type in ["gps", "gcp"]:
            rows = []
            columns_names = [error_type.upper(), "Mean", "Sigma", "RMS Error"]
            if "average_error" not in self.stats[error_type + "_errors"]:
                continue
            for comp in ["x", "y", "z"]:
                row = [comp.upper() + " Error (meters)"]
                row.append(
                    f"{self.stats[error_type + '_errors']['mean'][comp]:.3f}")
                row.append(
                    f"{self.stats[error_type +'_errors']['std'][comp]:.3f}")
                row.append(
                    f"{self.stats[error_type +'_errors']['error'][comp]:.3f}")
                rows.append(row)

            rows.append([
                "Total",
                "",
                "",
                f"{self.stats[error_type +'_errors']['average_error']:.3f}",
            ])
            self._make_table(columns_names, rows)
            self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)

        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)

    def make_features_details(self):
        self._make_section("Features Details")

        heatmap_height = 60
        heatmaps = [
            f for f in os.listdir(self.output_path) if f.startswith("heatmap")
        ]
        self._make_centered_image(os.path.join(self.output_path, heatmaps[0]),
                                  heatmap_height)
        if len(heatmaps) > 1:
            logger.warning("Please implement multi-model display")

        columns_names = ["", "Min.", "Max.", "Mean", "Median"]
        rows = []
        for comp in ["detected_features", "reconstructed_features"]:
            row = [comp.replace("_", " ").replace("features", "").capitalize()]
            for t in columns_names[1:]:
                row.append(
                    f"{self.stats['features_statistics'][comp][t.replace('.', '').lower()]:.0f}"
                )
            rows.append(row)
        self._make_table(columns_names, rows)

        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def make_reconstruction_details(self):
        self._make_section("Reconstruction Details")

        rows = [
            [
                "Average reprojection Error",
                f"{self.stats['reconstruction_statistics']['reprojection_error']:.2f} pixels",
            ],
            [
                "Average Track Length",
                f"{self.stats['reconstruction_statistics']['average_track_length']:.2f} images",
            ],
            [
                "Average Track Length (> 2)",
                f"{self.stats['reconstruction_statistics']['average_track_length_over_two']:.2f} images",
            ],
        ]
        self._make_table(None, rows, True)
        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def make_camera_models_details(self):
        self._make_section("Camera Models Details")

        for camera, params in self.stats["camera_errors"].items():
            residual_grids = [
                f for f in os.listdir(self.output_path)
                if f.startswith("residuals_" + str(camera.replace("/", "_")))
            ]
            if not residual_grids:
                continue

            initial = params["initial_values"]
            optimized = params["optimized_values"]
            names = [""] + list(initial.keys())

            rows = []
            rows.append(["Initial"] + [f"{x:.4f}" for x in initial.values()])
            rows.append(["Optimized"] +
                        [f"{x:.4f}" for x in optimized.values()])

            self._make_subsection(camera)
            self._make_table(names, rows)
            self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)

            residual_grid_height = 80
            self._make_centered_image(
                os.path.join(self.output_path, residual_grids[0]),
                residual_grid_height)

    def make_tracks_details(self):
        self._make_section("Tracks Details")
        matchgraph_height = 60
        matchgraph = [
            f for f in os.listdir(self.output_path)
            if f.startswith("matchgraph")
        ]
        self._make_centered_image(
            os.path.join(self.output_path, matchgraph[0]), matchgraph_height)

        histogram = self.stats["reconstruction_statistics"][
            "histogram_track_length"]
        start_length, end_length = 2, 10
        row_length = ["Length"]
        for length, _ in sorted(histogram.items(), key=lambda x: int(x[0])):
            if int(length) < start_length or int(length) > end_length:
                continue
            row_length.append(length)
        row_count = ["Count"]
        for length, count in sorted(histogram.items(),
                                    key=lambda x: int(x[0])):
            if int(length) < start_length or int(length) > end_length:
                continue
            row_count.append(f"{count}")

        self._make_table(None, [row_length, row_count], True)

        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def add_page_break(self):
        self.pdf.add_page("P")

    def generate_report(self):
        self.make_title()
        self.make_dataset_summary()
        self.make_processing_summary()
        self.add_page_break()

        self.make_features_details()
        self.make_reconstruction_details()
        self.make_tracks_details()
        self.add_page_break()

        self.make_camera_models_details()
        self.make_gps_details()
        self.make_processing_time_details()
示例#16
0
def createPDFacordo(db: Session, vaga: PessoaProjeto):

    contratado = get_pessoa_by_id(db, vaga.pessoa_id)
    projeto = get_projeto(db, vaga.projeto_id)
    contratante = get_pessoa_by_id(db, projeto.pessoa_id)
    acordo = get_tipo_acordo_by_id(db, vaga.tipo_acordo_id)
    # Observar após refatoração
    if (vaga.papel_id == 1):
        papel = "aliado"
    elif (vaga.papel_id == 2):
        papel = "colaborador"
    elif (vaga.papel_id == 3):
        papel = "idealizador"

    pdf = FPDF()
    pdf.add_page(orientation='P')

    espacamento = 8

    pdf.set_margins(20, 20, 20)
    pdf.set_font("Arial", 'B', size=16)
    # Espaço de formatação
    pdf.cell(20, 20, txt='', ln=1)
    pdf.cell(175, 12, txt='ACORDO DE PRESTAÇÃO DE SERVIÇOS', ln=1, align="C")
    pdf.set_font("Arial", 'B', size=14)
    pdf.cell(175,
             12,
             txt='IDENTIFICAÇÃO DAS PARTES CONTRATANTES',
             ln=1,
             align="L")

    # Corpo
    pdf.set_font("Arial", 'B', size=12)
    pdf.cell(pdf.get_string_width('CONTRATANTE: '),
             espacamento,
             txt='CONTRATANTE: ',
             align="L")
    pdf.set_font("Arial", size=12)
    w = pdf.get_x()
    pdf.cell(w, espacamento, txt=contratante.nome, ln=1, align="L")
    pdf.set_font("Arial", 'B', size=12)
    pdf.cell(pdf.get_string_width('CONTRATADO: '),
             espacamento,
             txt='CONTRATADO: ',
             align="L")
    pdf.set_font("Arial", size=12)
    w = pdf.get_x()
    pdf.cell(w, espacamento, txt=contratado.nome, ln=1, align="L")
    pdf.cell(20, 5, txt='', ln=1)
    pdf.multi_cell(
        0,
        espacamento,
        txt=
        'As partes acima identificadas têm, entre si, justo e acertado o presente Acordo de Prestação de Serviços, que se regerá pelo objeto do acordo pelas condições de remuneração, forma e termo de pagamento descritas no presente.',
        align="J")

    pdf.set_font("Arial", 'B', size=14)

    pdf.cell(175, 15, txt='DO OBJETO DE ACORDO', ln=1, align="L")

    pdf.set_font("Arial", size=12)
    pdf.multi_cell(
        0,
        espacamento,
        txt='É objeto do presente acordo a prestação do serviço no projeto ' +
        projeto.nome + ' como ' + papel + ' na vaga de ' + vaga.titulo +
        ' por meio de um contrato como ' + acordo.descricao + '.',
        align="J")

    if (vaga.remunerado):
        pdf.multi_cell(
            0,
            espacamento,
            txt=
            'Esta prestação de serviços será remunerada com valores e pagamentos a serem negociados entre ambas as partes.',
            align="J")
    else:
        pdf.multi_cell(
            0,
            espacamento,
            txt=
            'Esta prestação de serviços não será remunerada conforme anunciado na plataforma Conectar.',
            align="J")

    pdf.cell(20, 10, txt='', ln=1)

    pdf.multi_cell(
        0,
        espacamento,
        txt=
        'A execução da prestação de serviço aqui acordada será de responsabilidade das partes envolvidas, eximindo da plataforma Conectar de qualquer obrigação com o contratante ou contratado.',
        align="J")

    hoje = datetime.now()
    data_str = 'Dois Vizinhos, ' + \
        str(hoje.day) + " de " + MESES[hoje.month] + " de " + str(hoje.year)

    pdf.cell(20, 7, txt='', ln=1)
    pdf.cell(200, espacamento, txt=data_str, ln=1, align="L")

    pdf.cell(20, 20, txt='', ln=1)

    pdf.cell(175,
             espacamento,
             txt='___________________            ___________________',
             ln=1,
             align="C")
    pdf.cell(175,
             espacamento,
             txt='Contratante                            Contratado',
             ln=1,
             align="C")

    saida = str(uuid.uuid4().hex) + ".pdf"

    pdf.output(PDF_PATH + saida)

    if not os.getenv("DEV_ENV"):
        upload_object(PDF_PATH + saida, 'conectar')
    os.remove(PDF_PATH + saida)

    return saida
def create_report(patient_name, interp_date, study_date, patient_code, interp_dr, sex, dob, height, weight, bmi, recording_time, monitoring_time, ahi, odi, mean_spo2, min_spo2, mean_heart_rate, diagnosis, recommendations, age, lights_off_time, lights_on_time, bed_time, oai, cai):
    pdf = FPDF()
    pdf.set_left_margin(margin=25)
    pdf.set_right_margin(margin=25)

    # First Page
    pdf.add_page()

    pdf.image('resources/logo.png',
              x=(WIDTH-150)/2, y=2, w=150, type='PNG')
    pdf.ln(20)

    pdf.set_font(family='Arial', style='B', size=10)
    pdf.multi_cell(
        w=0, h=4, txt='1060 S. Main St., Suite 301A\nSt. George, UT 84770\n(855) 276-3263', align='C')
    pdf.ln(5)

    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=0, h=4, txt='HOME SLEEP TEST ANALYSIS REPORT', align='L', ln=1)
    pdf.ln(5)

    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Patient Name: {patient_name}', align='L')
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Sex: {sex}', align='L', ln=1)
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Interp. Date: {interp_date}', align='L')
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'DOB: {dob}', align='L', ln=1)
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Study Date: {study_date}', align='L')
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Height: {height} in.', align='L', ln=1)
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Patient Code: {patient_code}', align='L')
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Weight: {weight} lbs.', align='L', ln=1)
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Interp Physician: {interp_dr}', align='L')
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'BMI: {bmi}', align='L', ln=1)
    pdf.ln(5)

    pdf.set_font(family='Arial', style='', size=9)
    pdf.multi_cell(
        w=0, h=4, txt='Test Sibel underwent a home sleep diagnostic study on 8/26/2019 investigating the possibility of obstructive sleep apnea. The study was conducted utilizing the Respironics Alice NightOne device. Raw data from the NightOne study was reviewed.')
    pdf.ln(5)

    pdf.cell(w=0, h=4, txt='Summary of Findings:', align='L', ln=1)
    pdf.ln(2)

    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Study Date: {study_date}', align='L')
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'ODI: {odi}', align='L', ln=1)
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Recording Time (min): {recording_time}', align='L')
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Mean Sp02 Sat: {mean_spo2}%', align='L', ln=1)
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Monitoring Time (min): {monitoring_time}', align='L')
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Min. Sp02 Desat: {min_spo2}%', align='L', ln=1)
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'AHI: {ahi}', align='L')
    pdf.cell(w=(REMAINING_WIDTH)/2, h=4,
             txt=f'Mean Heart Rate: {mean_heart_rate}', align='L', ln=1)
    pdf.ln(3)

    pdf.set_font(family='Arial', style='', size=9)
    pdf.multi_cell(
        w=0, h=4, txt='AHI=Apneas + Hypopneas per hour of sleep. All apneas and hypopneas must be at least 10 seconds in duration and have a minimum of 4% associated desaturation. AHI calculated using Remmers Respiratory Disturbance Index.ODI=Oxygen desaturation of at least 4% from baseline per hour of sleep')
    pdf.ln(5)

    pdf.cell(w=18, h=4,
             txt='Diagnosis: ', align='L')
    pdf.set_font(family='Arial', style='B', size=10)
    pdf.cell(w=(REMAINING_WIDTH-18), h=4,
             txt=f'{diagnosis}', align='L', ln=1)
    pdf.ln(5)

    pdf.set_font(family='Arial', style='', size=9)
    pdf.cell(w=0, h=4, txt='Recommendations: ', align='L')
    pdf.ln(4)

    for i in recommendations:
        pdf.cell(w=8, h=4,
                 txt='  -', align='L')
        pdf.multi_cell(w=(REMAINING_WIDTH-18), h=4,
                       txt=i.recommendation_data)
        for j in i.sub_list:
            pdf.cell(w=8, h=4, align='L')
            pdf.cell(w=8, h=4, txt='  -', align='L')
            pdf.multi_cell(w=(REMAINING_WIDTH-18), h=4, txt=j)
        pdf.ln(2)
    pdf.ln(2)

    pdf.multi_cell(
        w=0, h=4, txt='Clinical follow-up as deemed necessary would be appropriate. Patient should be advised on the long term consequences of OSA if left untreated, need for treatment, and close follow up. Retesting or follow up is recommended to ensure the apnea is controlled and the symptoms are relieved on the chosen therapy. ')
    pdf.ln(5)

    pdf.multi_cell(
        w=0, h=4, txt='Untreated obstructive sleep apnea is associated with hypertension, heart disease, stroke, daytime sleepiness, cognitive dysfunction, mood disorders and sudden death.')
    pdf.ln(5)

    pdf.ln(SIGN_LOCATION_Y-pdf.get_y())
    pdf.cell(w=50, h=4, txt="Sincerely,", align='L')
    pdf.image('resources/sign.png',
              x=20, y=SIGN_LOCATION_Y+5, w=60, type='PNG')
    pdf.ln(20)
    pdf.multi_cell(
        w=0, h=4, txt=f'Dr.{interp_dr}\nDiplomate ABIM-Sleep Medicine\nElectronically Signed')

    # Second Page
    pdf.add_page()

    pdf.image('resources/philips-logo.png',
              x=LEFT_MARGIN, y=10, w=60, type='PNG')
    pdf.ln(15)

    pdf.set_font(family='Arial', style='B', size=20)
    pdf.cell(w=60, h=4)
    pdf.cell(w=120, h=10, txt='Sleep Test Report', align='C', ln=1)
    pdf.ln(5)

    pdf.set_font(family='Arial', style='B', size=10)  # Table Header
    pdf.set_draw_color(r=0, g=102, b=204)
    pdf.set_fill_color(r=213, g=227, b=187)
    pdf.cell(w=100, h=7, align='L', border=1, fill=True)
    pdf.cell(w=REMAINING_WIDTH-100, h=7,
             txt=f'Study Date: {study_date}', align='L', border=1, fill=True, ln=1)

    pdf.set_font(family='Arial', style='B', size=10)  # Row 1
    pdf.cell(w=20, h=5, txt='Patient', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=60, h=5, txt=f'{patient_name}', align='L', border=1)
    pdf.set_font(family='Arial', style='B', size=10)
    pdf.cell(w=20, h=5, txt='Recording', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=60, h=5, txt='Alice NightOne', align='L', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=10)  # Row 2
    pdf.cell(w=20, h=5, txt='Sex', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=60, h=5, txt=f'{sex}', align='L', border=1)
    pdf.set_font(family='Arial', style='B', size=10)
    pdf.cell(w=20, h=5, txt='Height', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=60, h=5, txt=f'{height} in.', align='L', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=10)  # Row 3
    pdf.cell(w=20, h=5, txt='DOB', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=60, h=5, txt=f'{dob}', align='L', border=1)
    pdf.set_font(family='Arial', style='B', size=10)
    pdf.cell(w=20, h=5, txt='Weight', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=60, h=5, txt=f'{weight} lbs.', align='L', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=10)  # Row 4
    pdf.cell(w=20, h=5, txt='Age', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=60, h=5, txt=f'{age} years', align='L', border=1)
    pdf.set_font(family='Arial', style='B', size=10)
    pdf.cell(w=20, h=5, txt='BMI', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=60, h=5, txt=f'{bmi}', align='L', border=1, ln=1)
    pdf.ln(5)

    pdf.set_font(family='Arial', style='B', size=10)  # Table-2 Header
    pdf.cell(w=REMAINING_WIDTH, h=7, txt='Times and Durations',
             align='L', border=1, fill=True, ln=1)

    pdf.set_font(family='Arial', style='B', size=10)  # Row 1
    pdf.cell(w=40, h=5, txt='Lights off clock time', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=40, h=5, txt=f'{lights_off_time}', align='L', border=1)
    pdf.set_font(family='Arial', style='B', size=10)
    pdf.cell(w=40, h=5, txt='Total Time Recording', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=40, h=5, txt=f'{recording_time} minutes',
             align='L', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=10)  # Row 2
    pdf.cell(w=40, h=5, txt='Lights on clock time', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=40, h=5, txt=f'{lights_on_time}', align='L', border=1)
    pdf.set_font(family='Arial', style='B', size=10)
    pdf.cell(w=40, h=5, txt='Time In Bed', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=40, h=5, txt=f'{bed_time} minutes',
             align='L', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=10)  # Row 3
    pdf.cell(w=40, h=5, txt='', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=40, h=5, txt='', align='L', border=1)
    pdf.set_font(family='Arial', style='B', size=10)
    pdf.cell(w=40, h=5, txt='Monitoring Time', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=10)
    pdf.cell(w=40, h=5, txt=f'{monitoring_time} minutes',
             align='L', border=1, ln=1)
    pdf.ln(5)

    pdf.set_font(family='Arial', style='B', size=10)  # Table-3 Header
    pdf.cell(w=REMAINING_WIDTH, h=7, txt='Device and Sensor Details',
             align='L', border=1, fill=True, ln=1)

    pdf.set_font(family='Arial', style='', size=10)  # Row 1
    pdf.multi_cell(
        w=REMAINING_WIDTH, h=4, txt='The study was recorded on a Philips Respironics Alice NightOne device using 1 RIP effort belt and a pressure based flow sensor. The heart rate is derived from the oximeter sensor and the snore signal is derived from the pressure sensor. The device also records body position and uses it to determine the monitoring time(sleep/wake periods).', align='', border=1)
    pdf.ln(5)

    pdf.set_font(family='Arial', style='B', size=10)  # Table-4 Header
    pdf.cell(w=REMAINING_WIDTH, h=7, txt='Summary',
             align='L', border=1, fill=True, ln=1)

    pdf.set_fill_color(r=250, g=191, b=143)
    pdf.cell(w=20, h=6, txt='AHI', align='C', border=1)  # Row 1
    pdf.cell(w=20, h=6, txt=f'{ahi}', align='C', border=1, fill=True)
    pdf.cell(w=20, h=6, txt='OAI', align='C', border=1)
    pdf.cell(w=20, h=6, txt=f'{oai}', align='C', border=1, fill=True)
    pdf.cell(w=20, h=6, txt='CAI', align='C', border=1)
    pdf.cell(w=20, h=6, txt=f'{cai}', align='C', border=1, fill=True)
    pdf.cell(w=20, h=6, txt='Min Desat', align='C', border=1)
    pdf.cell(w=20, h=6, txt=f'{min_spo2}',
             align='C', border=1, fill=True, ln=1)

    pdf.set_font(family='Arial', style='', size=8.5)
    pdf.set_text_color(r=107, g=107, b=107)
    pdf.multi_cell(
        w=REMAINING_WIDTH, h=4, txt='AHI is the number of respiratory events per hour. OAI is the number of obstructive apneas per hour. CAI is the number of central apneas per hour. Lowest Desat is the lowest blood oxygen level that lasted at least 2 seconds.', align='', )
    pdf.ln(5)

    pdf.set_text_color(r=0, g=0, b=0)  # Table 5 - Header
    pdf.set_fill_color(r=213, g=227, b=187)
    pdf.set_font(family='Arial', style='B', size=10)
    pdf.cell(w=REMAINING_WIDTH, h=7, txt='Respiratory Events',
             align='L', border=1, fill=True, ln=1)
    temp_y = pdf.get_y()

    pdf.set_font(family='Arial', style='B', size=8)  # Row 1
    pdf.cell(w=30, h=12, txt='', align='C', border=1)
    temp_x = pdf.get_x()
    pdf.multi_cell(w=15, h=6, txt='Index (#/hour)', align='C', border=1)
    pdf.set_y(temp_y)
    pdf.set_x(temp_x+15)
    temp_x = pdf.get_x()
    pdf.multi_cell(w=15, h=6, txt='Total # of Events', align='C', border=1)
    pdf.set_y(temp_y)
    pdf.set_x(temp_x+15)
    temp_x = pdf.get_x()
    pdf.multi_cell(w=15, h=6, txt='Mean Duration', align='C', border=1)
    pdf.set_y(temp_y)
    pdf.set_x(temp_x+15)
    temp_x = pdf.get_x()
    pdf.multi_cell(w=15, h=6, txt='Max Duration', align='C', border=1)
    pdf.set_y(temp_y)
    pdf.set_x(temp_x+15)
    pdf.cell(w=70, h=4, txt='# of Events by Position',
             align='C', border=1, ln=1)
    pdf.set_y(temp_y+4)
    pdf.set_x(temp_x+15)
    pdf.cell(w=14, h=8, txt='Supine', align='C', border=1)
    pdf.cell(w=14, h=8, txt='Prone', align='C', border=1)
    pdf.cell(w=14, h=8, txt='Left', align='C', border=1)
    pdf.cell(w=14, h=8, txt='Right', align='C', border=1)
    pdf.cell(w=14, h=8, txt='Up', align='C', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=8)  # Row 2
    pdf.cell(w=30, h=6, txt='Central Apneas', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=8)
    pdf.cell(w=15, h=6, txt='4.3', align='C', border=1)
    pdf.cell(w=15, h=6, txt='29', align='C', border=1)
    pdf.cell(w=15, h=6, txt='21.7', align='C', border=1)
    pdf.cell(w=15, h=6, txt='127', align='C', border=1)
    pdf.cell(w=14, h=6, txt='1', align='C', border=1)
    pdf.cell(w=14, h=6, txt='3', align='C', border=1)
    pdf.cell(w=14, h=6, txt='2', align='C', border=1)
    pdf.cell(w=14, h=6, txt='23', align='C', border=1)
    pdf.cell(w=14, h=6, txt='0', align='C', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=8)  # Row 3
    pdf.cell(w=30, h=6, txt='Constructive Apneas', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=8)
    pdf.cell(w=15, h=6, txt='4.3', align='C', border=1)
    pdf.cell(w=15, h=6, txt='29', align='C', border=1)
    pdf.cell(w=15, h=6, txt='21.7', align='C', border=1)
    pdf.cell(w=15, h=6, txt='127', align='C', border=1)
    pdf.cell(w=14, h=6, txt='1', align='C', border=1)
    pdf.cell(w=14, h=6, txt='3', align='C', border=1)
    pdf.cell(w=14, h=6, txt='2', align='C', border=1)
    pdf.cell(w=14, h=6, txt='23', align='C', border=1)
    pdf.cell(w=14, h=6, txt='0', align='C', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=8)  # Row 4
    pdf.cell(w=30, h=6, txt='Mixed Apneas', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=8)
    pdf.cell(w=15, h=6, txt='4.3', align='C', border=1)
    pdf.cell(w=15, h=6, txt='29', align='C', border=1)
    pdf.cell(w=15, h=6, txt='21.7', align='C', border=1)
    pdf.cell(w=15, h=6, txt='127', align='C', border=1)
    pdf.cell(w=14, h=6, txt='1', align='C', border=1)
    pdf.cell(w=14, h=6, txt='3', align='C', border=1)
    pdf.cell(w=14, h=6, txt='2', align='C', border=1)
    pdf.cell(w=14, h=6, txt='23', align='C', border=1)
    pdf.cell(w=14, h=6, txt='0', align='C', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=8)  # Row 5
    pdf.cell(w=30, h=6, txt='Hypoapneas', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=8)
    pdf.cell(w=15, h=6, txt='4.3', align='C', border=1)
    pdf.cell(w=15, h=6, txt='29', align='C', border=1)
    pdf.cell(w=15, h=6, txt='21.7', align='C', border=1)
    pdf.cell(w=15, h=6, txt='127', align='C', border=1)
    pdf.cell(w=14, h=6, txt='1', align='C', border=1)
    pdf.cell(w=14, h=6, txt='3', align='C', border=1)
    pdf.cell(w=14, h=6, txt='2', align='C', border=1)
    pdf.cell(w=14, h=6, txt='23', align='C', border=1)
    pdf.cell(w=14, h=6, txt='0', align='C', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=8)  # Row 6
    pdf.cell(w=30, h=6, txt='RERAs', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=8)
    pdf.cell(w=15, h=6, txt='4.3', align='C', border=1)
    pdf.cell(w=15, h=6, txt='29', align='C', border=1)
    pdf.cell(w=15, h=6, txt='21.7', align='C', border=1)
    pdf.cell(w=15, h=6, txt='127', align='C', border=1)
    pdf.cell(w=14, h=6, txt='1', align='C', border=1)
    pdf.cell(w=14, h=6, txt='3', align='C', border=1)
    pdf.cell(w=14, h=6, txt='2', align='C', border=1)
    pdf.cell(w=14, h=6, txt='23', align='C', border=1)
    pdf.cell(w=14, h=6, txt='0', align='C', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=8)  # Row 7
    pdf.cell(w=30, h=6, txt='Total', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=8)
    pdf.cell(w=15, h=6, txt='4.3', align='C', border=1)
    pdf.cell(w=15, h=6, txt='29', align='C', border=1)
    pdf.cell(w=15, h=6, txt='21.7', align='C', border=1)
    pdf.cell(w=15, h=6, txt='127', align='C', border=1)
    pdf.cell(w=14, h=6, txt='1', align='C', border=1)
    pdf.cell(w=14, h=6, txt='3', align='C', border=1)
    pdf.cell(w=14, h=6, txt='2', align='C', border=1)
    pdf.cell(w=14, h=6, txt='23', align='C', border=1)
    pdf.cell(w=14, h=6, txt='0', align='C', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=8)  # Row 8
    pdf.cell(w=90, h=6, txt='Time in Position', align='L', border=1)
    pdf.set_font(family='Arial', style='', size=8)
    pdf.cell(w=14, h=6, txt='1', align='C', border=1)
    pdf.cell(w=14, h=6, txt='3', align='C', border=1)
    pdf.cell(w=14, h=6, txt='2', align='C', border=1)
    pdf.cell(w=14, h=6, txt='23', align='C', border=1)
    pdf.cell(w=14, h=6, txt='0', align='C', border=1, ln=1)

    pdf.set_font(family='Arial', style='B', size=8)  # Row 9
    pdf.cell(w=90, h=6, txt='Position', align='L', border=1)
    pdf.cell(w=14, h=6, txt='1', align='C', border=1)
    pdf.cell(w=14, h=6, txt='3', align='C', border=1)
    pdf.cell(w=14, h=6, txt='2', align='C', border=1)
    pdf.cell(w=14, h=6, txt='23', align='C', border=1)
    pdf.cell(w=14, h=6, txt='0', align='C', border=1, ln=1)

    # Output
    pdf.output('sibel-report.pdf', 'F')
def image_adder(no_of_pages = 0, page_dimension = (0,0), big_frame_dimension = (0, 0), frame_dimension = (0,0), padding_btw_frames = (1,1), image_resize = (0,0), circle_required = False, repetition = 1):

	dimensions_page = (px_to_pt_converter(page_dimension[0]), px_to_pt_converter(page_dimension[1]))
	
	if image_resize[0] == 0 or image_resize[1] == 0:
		image_resize = frame_dimension

	# Creating a directory where all the images will be saved
	directory = BASE_DIR + "/uploader/qrcodes/"
	try:
		mkdir(directory)
	
	except FileExistsError:
		print("Directory already exists! Need to delete it.")
		rmtree(directory)
		mkdir(directory)
	except OSError:
		print("Error creating a directory with name \'qrcodes\'")
		raise OSError
	else:
		print("Successfully created a directory with name \'qrcodes\'")

	try:
		# Extract zip files to a folder
		extractZip(directory)
	except FileNotFoundError:
		print("Error occurred not able to find the directory!")
		raise FileNotFoundError
	except RuntimeError:
		print("Runtime error while processing zipfiles!")
		raise RuntimeError

	try:
		# Directory of the images are required.
		images = resize_images_replicate_and_fetch(directory, image_resize, repetition)
	except IOError:
		print("Either file doesn't exist or image cannot be opened and identified!")
		rmtree(directory)
		raise IOError

	# print(images)
	TOTAL_IMAGES = len(images)
	index_images = 0

	# Incrementing this value for the filename.
	suffix_filename = 1

	while index_images < TOTAL_IMAGES:
		# Initialize pdf variable.
		pdf = FPDF('P', 'pt', dimensions_page)

		# Add a page to the pdf
		pdf.add_page()
		# print(pdf.get_x(), pdf.get_y())
		pdf.set_font('Arial', 'B', 10)
		# Big frame 
		dimensions_bigframe = (px_to_pt_converter(page_dimension[0]-50), px_to_pt_converter(page_dimension[1]-50))
		default_current_pos_x = pdf.get_x()
		default_current_pos_y = pdf.get_y()
		pdf.rect(pdf.get_x(), pdf.get_y(), dimensions_bigframe[0], dimensions_bigframe[1], style = 'D')

		# Frame
		pdf.set_x(default_current_pos_x) 
		pdf.set_y(default_current_pos_y)
		dimensions_frame = (int(px_to_pt_converter(frame_dimension[0])),int(px_to_pt_converter(frame_dimension[1])))

		current_pos_x = default_current_pos_x
		current_pos_y = default_current_pos_y

		
		for row in nm.arange(current_pos_y, dimensions_bigframe[1], dimensions_frame[1]+padding_btw_frames[1]):
			for col in nm.arange(current_pos_x, dimensions_bigframe[0], dimensions_frame[0]+padding_btw_frames[0]):
				if ((col + dimensions_frame[0]) > dimensions_bigframe[0]) or ((row + dimensions_frame[1]) > dimensions_bigframe[1]):
					break
				position_in_x_direction = col+px_to_pt_converter(padding_btw_frames[0])
				position_in_y_direction = row+px_to_pt_converter(padding_btw_frames[1])
				pdf.rect(position_in_x_direction, position_in_y_direction, dimensions_frame[0], dimensions_frame[1], style = 'D')
				if index_images < TOTAL_IMAGES:
					try:
						load_image_to_pdf(pdf, directory + images[index_images], position_in_x_direction, position_in_y_direction, dimensions_frame[0], dimensions_frame[1], circle_required)
					except FileNotFoundError:
						rmtree(directory)
						raise FileNotFoundError
					# processed images are removed
					remove(directory + images[index_images])
					pdf.set_x(col+dimensions_frame[0])
					pdf.set_y(row)
				index_images += 1

			pdf.set_y(row)
			pdf.set_x(current_pos_x)

		# output the pdf to a file. FILENAME = qrcodes(1...n).pdf
		FILE_NAME = BASE_DIR + "/uploader/" + FILE_NAME_PREFIX + str(suffix_filename) + ".pdf"
		pdf.output(FILE_NAME, 'F')
		suffix_filename = suffix_filename + 1
		pdf.close()
		
		
	
	# Removing the directory after processing
	print("Removing the images directory after processing")	
	rmtree(directory)
	print("Removing the zip files after processing")
	rmtree(BASE_DIR + "/uploader/zipfiles")
示例#19
0
def create_invoice(o_id,file_no):

    cur.execute('SELECT * FROM `user orders` WHERE `order id` = %s',(o_id,))
    for k in cur:
        order_id = 'Order id - ' + str(k[0])
        name = 'Customer Name - ' + k[2]
        number = 'Customer Number - ' + k[3]
        address = 'Customer Address - ' + k[4]
        rest = 'Restaurant Name - ' + k[5]
        rest_address = 'Restaurant Address - ' + k[-3]
        rest_number = 'Restaurant Number - ' + k[-2]
        ord_time = 'Order Time - ' + str(k[-1])
        item = k[6].split(',')
        item.pop()
        quantity = k[7].split(',')
        quantity.pop()
        price = k[8].split(',')
        price.pop()
        date = 'Order Date - ' + str(k[9])
        total_quantity = 0
        total_price = 0
        for i in range(len(item)):
            total_quantity += int(quantity[i])
            total_price += int(price[i]) * int(quantity[i])


    pdf = FPDF()

    pdf.add_page()


    pdf.set_font('Arial', size = 14)



    pdf.cell(200,10, txt = 'Python Project', ln = 1, align = 'C') 

    pdf.cell(200,5, txt = 'Food Ordering Program', ln = 1, align = 'C')

    pdf.dashed_line(34, 27, 185, 27, dash_length = 1)

    pdf.cell(200,12, txt = 'Invoice', ln = 1, align = 'C')

    pdf.dashed_line(34, 35, 185, 35, dash_length = 1)

    pdf.set_left_margin(33)

    pdf.cell(200,8, txt = order_id, ln = 1, align = 'L')
    pdf.cell(200,7, txt = date, ln = 1, align = 'L')
    pdf.cell(200,7, txt = ord_time, ln = 1, align = 'L')
    pdf.cell(200,7, txt = rest, ln = 1, align = 'L')
    pdf.cell(200,7, txt = rest_number, ln = 1, align = 'L')
    pdf.cell(200,7, txt = rest_address, ln = 1, align = 'L')
    pdf.cell(200,7, txt = name, ln = 1, align = 'L')
    pdf.cell(200,7, txt = number, ln = 1, align = 'L')
    pdf.cell(200,7, txt = address, ln = 1, align = 'L')

    pdf.dashed_line(34, 110, 185, 110, dash_length = 1)

    pdf.set_y(104)
    pdf.set_x(38)
    pdf.cell(200, 22, txt = 'Item', ln = 1)

    pdf.set_y(104)
    pdf.set_x(120)
    pdf.cell(200, 22, txt = 'Quantity', ln = 1)

    pdf.set_y(104)
    pdf.set_x(160)
    pdf.cell(200, 22, txt = 'Price', ln = 1)

    pdf.dashed_line(34, 120, 185, 120, dash_length = 1)

    

    for i in range(len(item)):
        pdf.set_x(38)
        y = pdf.get_y()
        pdf.cell(200, 10, txt = str(item[i]), ln = 1)



        pdf.set_y(y)
        pdf.set_x(125)
        pdf.cell(200, 10, txt = quantity[i], ln = 1)
        pdf.set_y(y)
        pdf.set_x(162)
        pdf.cell(200, 10, txt = price[i] + '.00', ln = 1)

    pdf.dashed_line(34, pdf.get_y() + 1.5, 185, pdf.get_y() + 1.5, dash_length = 1)

    

    pdf.set_x(38)
    y = pdf.get_y()
    pdf.cell(200, 17, txt = 'Total', ln = 1)
    pdf.set_y(y)
    pdf.set_x(125)
    pdf.cell(200, 17, txt = str(total_quantity), ln = 1)
    pdf.set_y(y)
    pdf.set_x(162)
    pdf.cell(200,17, txt = str(total_price) + '.00', ln = 1)

    y = pdf.get_y() - 10
    pdf.set_y(y)
    pdf.set_x(38)
    pdf.cell(200, 17, txt = 'GST(18%)', ln = 1)
    pdf.set_y(y)
    pdf.set_x(125)
    pdf.cell(200, 17, txt = str(total_quantity), ln = 1)
    pdf.set_y(y)
    pdf.set_x(162)
    tax = str(total_price * (18/100))
    fin_tax = ''
    cnt = 0
    for i in tax:
        if i == '.':
            fin_tax = fin_tax + tax[cnt:cnt + 3]
            break
        else:
            fin_tax = fin_tax + i
            cnt += 1

            
    pdf.cell(200, 17, txt = fin_tax, ln = 1)

    pdf.dashed_line(34, pdf.get_y() - 3, 185, pdf.get_y() - 3, dash_length = 1)

    y = pdf.get_y() - 5
    pdf.set_y(y)
    pdf.set_x(38)
    pdf.cell(200, 17, txt = 'Grand Total', ln = 1)
    pdf.set_y(y)
    pdf.set_x(125)
    pdf.cell(200, 17, txt = str(total_quantity), ln = 1)
    pdf.set_y(y)
    pdf.set_x(162)

    fin_tot_0 = str(total_price + float(fin_tax))
    fin_tot = ''
    cnt = 0
    for i in fin_tot_0:
        if i == '.':
            fin_tot = fin_tot + fin_tot_0[cnt:cnt + 3]
            break
        else:
            fin_tot = fin_tot + i
            cnt += 1


    pdf.cell(200,17, txt = fin_tot, ln = 1)

    pdf.dashed_line(34, pdf.get_y() - 3, 185, pdf.get_y() - 3, dash_length = 1)

    pdf.set_x(pdf.get_x() - 20)
    pdf.cell(200,17, txt = 'Thank you for ordering', ln = 1, align = 'C')
    pdf.set_y(pdf.get_y() - 8)
    pdf.set_x(pdf.get_x() - 20)
    pdf.cell(200,17, txt = 'We hope you have a great day!', ln = 1, align = 'C')

    file_name = os.getcwd() + '/Invoice/Invoice_' + str(file_no) + '.pdf'
    pdf.output(name = file_name)

    return file_name
def make_bulletin():
    global y_appr
    global p
    p = FPDF('L', 'cm', 'A4')
    p.set_margins(
        marge, marge,
        marge)  # marges (pas de marge_bottom, mais ligne suivante aide)
    p.set_auto_page_break(
        False
    )  # empêcher les page break automatiques (donc ~ pas de marge en bas)
    p.add_page()

    #################################
    #  Logo + coordonnées du lycée  #
    #################################

    # Logo
    p.image('logo_lycée.png', marge, marge, w=w_logo)

    # Adresse
    p.set_font('Arial', '', 7)
    p.set_xy(w_logo + marge, marge)
    adr_lycee = "Académie de Créteil\nLycée Polyvalent Louise Michel\n7 Rue Pierre Marie Derrien\n94500 Champigny-sur-Marne\nTél. : 01.48.82.07.35"
    p.multi_cell(w_adr_lycee, h_cell - 0.1, adr_lycee, aff_bord, 'C', False)

    ###############################
    #  En-tête période + vie sco  #
    ###############################

    # Titres en gras: bulletin de période, vie scolaire
    p.set_font('Arial', 'B', 9)
    p.cell(w_periode, h_cell, "Bulletin du " + periode.lower(), aff_bord, 0,
           'C')
    p.cell(0, h_cell, "Vie scolaire", aff_bord, 0, 'C')

    # ligne horizontale
    x0 = marge + w_logo + w_adr_lycee
    x1 = width - marge
    y0 = marge + h_cell
    y1 = marge + h_cell
    p.line(x0, y0, x1, y1)

    # Infos de la classe
    p.set_font('Arial', '', 9)
    p.set_xy(x0, y0)  # on commence au début de la ligne
    p.cell(w_infos_classe, h_cell, 'Année scolaire: %s' % annee_sco, aff_bord,
           2, 'L')
    p.cell(w_infos_classe, h_cell, 'Classe: %s' % classe, aff_bord, 2, 'L')

    # PP: on peut en avoir plusieurs. Tri des noms et affichage correct.
    if len(prof_principal) == 1:
        PP = prof_principal[0]
    else:
        prof_principal.sort(key=lambda x: x.split(" ")[-1]
                            )  # on trie par nom sans considérer M/Mme
        PP = ''
        for i in range(len(prof_principal)):
            PP += prof_principal[i]
            PP += '\n       '
    p.multi_cell(w_infos_classe, h_cell, 'PP: %s' % PP, aff_bord, 'L')

    p.set_xy(x0 + w_infos_classe, y0)

    # prénom élève
    p.set_font('Arial', 'B', 9)
    p.cell(w_periode - w_infos_classe, h_cell, nom, aff_bord, 2, 'L')

    # Infos persos élève (TODO)
    p.set_font('Arial', '', 9)
    if genre == 'M' or genre == 'I':
        infos_perso = "Né le %s\nINE : %s" % (date_naissance, INE)
    if genre == 'F':
        infos_perso = "Née le %s\nINE : %s" % (date_naissance, INE)
    p.multi_cell(w_periode - w_infos_classe, h_cell, infos_perso, aff_bord,
                 'L')

    # Absences + appréciation vie sco
    # TODO: Appréciation vie scolaire
    p.set_xy(p.get_x(), p.get_y() - h_cell)
    texte_viesco = "Absences : %s demi-journée" % abs
    if int(abs) > 1:
        texte_viesco += "s"
    texte_viesco += " dont %s non-réglée" % abs_non_reglees
    if int(abs_non_reglees) > 1:
        texte_viesco += "s"
    texte_viesco += ".\nAppréciation : %s" % appr_vie_sco

    p.multi_cell(0, h_cell, texte_viesco, aff_bord, 'L')

    ########################
    #  Bloc appréciations  #
    ########################

    # NOTE: On veut faire apparaître les appréciations dans un ordre précis
    # hardcodé dans ordre_matieres

    # Matières du tronc commun
    i = 0
    for matiere in ordre_matieres:
        infos_appr = (matiere, moyennes[matiere].get('prof', ''),
                      moyennes[matiere].get('appreciation', ''))
        ligne_appreciation(x_appr, y_appr + i * height_appr, infos_appr)
        i += 1

    # On vérifie s'il n'y a pas d'option à ajouter
    for m in moyennes:
        if m == "Vie scolaire":
            continue  # L'appréciation vie sco n'apparaît pas ici
        if m not in ordre_matieres:
            infos_appr = (m, moyennes[m].get('prof', ''),
                          moyennes[m].get('appreciation', ''))
            ligne_appreciation(x_appr, y_appr + i * height_appr, infos_appr)
            i += 1

    ###################
    #  Bloc moyennes  #
    ###################

    # Vu qu'on a un template fixe, on va se contenter d'appeler des fonctions bien définies
    # On construit des lignes de 3 blocs, dans l'ordre souhaité des matières.

    # Ligne FR/EN/ES
    temp_dict = {
        ordre_matieres[i]: moyennes[ordre_matieres[i]]['moyennes']
        for i in range(0, 3)
    }
    ligne_eval(x_bloc, y_bloc, temp_dict)

    # Ligne HG/EMC/SES
    temp_dict = {
        ordre_matieres[i]: moyennes[ordre_matieres[i]]['moyennes']
        for i in range(3, 6)
    }
    ligne_eval(x_bloc, y_bloc + 7 * h_cell + h_offset_blocs, temp_dict)

    # Ligne Maths/PC/SVT
    temp_dict = {
        ordre_matieres[i]: moyennes[ordre_matieres[i]]['moyennes']
        for i in range(6, 9)
    }
    ligne_eval(x_bloc, y_bloc + 2 * (7 * h_cell + h_offset_blocs), temp_dict)

    # Selon la maquette, 2 situations:
    # - Soit on a deux blocs sur la dernière ligne (EPS et SNT)
    # - Soit on a trois blocs sur la dernière ligne (EPS, SNT, option)
    temp_dict = {
        ordre_matieres[i]: moyennes[ordre_matieres[i]]['moyennes']
        for i in range(9, 11)
    }
    # On cherche l'option
    skip = 1  # Par défaut, pas d'option donc 1 bloc masqué
    for m in moyennes:
        if m == 'Vie scolaire':  # on ignore la moyenne de vie sco (mais elle existe pour pouvoir mettre une appr à l'élève)
            continue
        if m not in ordre_matieres:  # Si on trouve une option (qui n'est pas dans l'ordre de base)
            # On l'ajoute à temp_dict pour que les moyennes sortent
            temp_dict[m] = moyennes[m]['moyennes']
            skip = 0  # ... et on ne saute pas le dernier bloc

    ligne_eval(x_bloc,
               y_bloc + 3 * (7 * h_cell + h_offset_blocs),
               temp_dict,
               skip=skip)

    # Légende des couleurs sous les blocs
    legende(x_bloc, y_bloc + 4 * (7 * h_cell + h_offset_blocs))

    #############################
    #  Appr. générale/mentions  #
    #############################

    # Appréciation de la direction/PP
    p.set_font('Arial', 'B', 8)
    p.set_xy(x_appr_dir, y_appr_dir)
    p.cell(w_prof, h_cell, 'Appréciation globale :', aff_bord, 0)
    p.set_font('Arial', '', 8)
    p.multi_cell(0, h_cell, appr_dir, aff_bord, 'L')

    # Mention
    # TODO: Question à poser: "mention:" apparaît toujours même si pas de mention ?
    p.set_font('Arial', 'B', 8)
    p.set_xy(x_appr_dir, y_appr_dir + 5 * h_cell)
    p.cell(w_prof / 2, h_cell, 'Mention :', aff_bord, 0)
    p.set_font('Arial', '', 8)
    p.cell(0, h_cell, mention, aff_bord, 0)

    ####################
    #  Signature chef  #
    ####################
    # Mention "le chef d'établissement" + signature
    p.set_xy(x_chef, y_chef)
    p.cell(w_prof, h_cell, "Le chef d'établissement", aff_bord, 0)
    #p.image(signature,p.get_x(),p.get_y()-0.5*h_cell, h=h_signature)

    #####################
    # Adresse du parent #
    #####################
    p.add_page(orientation='P', format="A4")
    p.set_xy(x_parent, y_parent)
    p.set_font('Arial', 'B', 12)
    p.multi_cell(0, h_cell * 1.25, parent_nom, aff_bord, 'L')
    # Le pointeur a besoin de sauter 1 ou 2 lignes
    # selon le nombre de noms affichés (présence de \n si 2 noms)
    if '\n' in parent_nom:
        p.set_xy(x_parent, y_parent + 2.5 * h_cell)
    else:
        p.set_xy(x_parent, y_parent + 1.25 * h_cell)
    p.set_font('Arial', '', 12)
    p.multi_cell(0, h_cell * 1.25, parent_adresse, aff_bord, 'L')

    ### Création du fichier
    fname = nom + str(numero_bulletin)
    try:
        p.output('bulletin/%s.pdf' % fname, 'F')
    except FileNotFoundError as e:
        os.mkdir("bulletin")
        p.output('bulletin/%s.pdf' % fname, 'F')
示例#21
0
def makePDF(printed_values, pdf_save_path):

    report_no = printed_values[0]

    # printing parameters
    # enable generalization
    # currenty set to printing on A4 format (210x297 mm)
    W = 190
    H = 278
    f_size = 5  # font size
    c_height = 0.02 * H  # cell height

    rep = FPDF()
    rep.add_page()

    if find_font_file('segoeui.ttf') != []:
        rep.add_font('Segoe', '', find_font_file('segoeui.ttf')[0], uni=True)
        rep.add_font('Segoe', 'B', find_font_file('segoeuib.ttf')[0], uni=True)
        f_type = "Segoe"  # font type
    if find_font_file('arial.ttf') != []:
        rep.add_font('Arial', '', find_font_file('arial.ttf')[0], uni=True)
        rep.add_font('Arial', 'B', find_font_file('arialbd.ttf')[0], uni=True)
        f_type = "Arial"  # font type
    if find_font_file('DejaVuSans.ttf') != []:
        rep.add_font('DejaVu',
                     '',
                     find_font_file('DejaVuSans.ttf')[0],
                     uni=True)
        rep.add_font('DejaVu',
                     'B',
                     find_font_file('DejaVuSans-Bold.ttf')[0],
                     uni=True)
        f_type = "DejaVu"  # font type

    rep.set_font(f_type, 'B', size=5 * f_size)
    rep.cell(0.8 * W,
             2.5 * c_height,
             txt="OPIS ZDARZENIA",
             align="C",
             border=1,
             ln=0)
    rep.set_font(f_type, 'B', size=3 * f_size)
    rep.cell(0.2 * W,
             2.5 * c_height,
             txt="  LP.   " + str(report_no),
             align="L",
             border=1,
             ln=1)

    rep.ln(c_height)

    rep.set_font(f_type, 'B', size=2 * f_size)
    left_margin = rep.get_x()
    ybefore = rep.get_y()
    rep.multi_cell(0.33 * W,
                   1.2 * c_height,
                   txt=" DATA WYJAZDU:\n " + printed_values[1],
                   align="L",
                   border=1)
    rep.set_xy(W * 0.33 + left_margin, ybefore)
    rep.multi_cell(0.33 * W,
                   1.2 * c_height,
                   txt=" GODZINA WYJAZDU:\n " + printed_values[2],
                   align="L",
                   border=1)
    rep.set_xy(W * 0.66 + left_margin, ybefore)
    rep.multi_cell(0.34 * W,
                   1.2 * c_height,
                   txt=" NA MIEJSCU: \n " + printed_values[3],
                   align="L",
                   border=1)

    ybefore = rep.get_y()
    left_margin = rep.get_x()
    rep.multi_cell(0.33 * W,
                   2 * c_height,
                   txt=" MIEJSCE ZDARZENIA:\n " + printed_values[4],
                   align="L",
                   border=1)
    rep.set_xy(W * 0.33 + left_margin, ybefore)
    rep.multi_cell(0.67 * W,
                   2 * c_height,
                   txt=" RODZAJ ZDARZENIA:\n " + printed_values[5],
                   align="L",
                   border=1)

    rep.ln(c_height)

    ybefore = rep.get_y()
    rep.multi_cell(0.33 * W,
                   1.2 * c_height,
                   txt=" DOWODCA SEKCJI:\n " + printed_values[6],
                   align="L",
                   border=1)
    rep.set_xy(W * 0.33 + left_margin, ybefore)
    rep.multi_cell(0.33 * W,
                   1.2 * c_height,
                   txt=" DOWODCA AKCJI:\n " + printed_values[7],
                   align="L",
                   border=1)
    rep.set_xy(W * 0.66 + left_margin, ybefore)
    rep.multi_cell(0.34 * W,
                   1.2 * c_height,
                   txt=" KIEROWCA: \n " + printed_values[8],
                   align="L",
                   border=1)

    ybefore = rep.get_y()
    rep.multi_cell(0.33 * W,
                   2 * c_height,
                   txt=" SPRAWCA:\n " + printed_values[9],
                   align="L",
                   border=1)
    rep.set_xy(left_margin, ybefore + 4 * c_height)
    rep.multi_cell(0.33 * W,
                   2 * c_height,
                   txt=" POSZKODOWANY:\n " + printed_values[10],
                   align="L",
                   border=1)
    rep.set_xy(W * 0.33 + left_margin, ybefore)
    rep.multi_cell(0.67 * W,
                   4 * c_height,
                   txt=" SEKCJA:\n " + printed_values[11],
                   align="L",
                   border=1)

    rep.ln(c_height)

    rep.multi_cell(1 * W,
                   5 * c_height,
                   txt=" SZCZEGOLY ZDARZENIA:\n " + printed_values[12],
                   align="L",
                   border=1)

    rep.ln(c_height)

    ybefore = rep.get_y()
    rep.multi_cell(0.2 * W,
                   2 * c_height,
                   txt=" DATA POWROTU:\n " + printed_values[13],
                   align="L",
                   border=1)
    rep.set_xy(W * 0.2 + left_margin, ybefore)
    rep.multi_cell(0.35 * W,
                   2 * c_height,
                   txt=" GODZ. ZAKONCZ.:    " + printed_values[14],
                   align="L",
                   border=1)
    rep.set_xy(W * 0.2 + left_margin, ybefore + 2 * c_height)
    rep.multi_cell(0.35 * W,
                   2 * c_height,
                   txt=" GODZ. W REMIZIE.:   " + printed_values[15],
                   align="L",
                   border=1)
    rep.set_xy(W * 0.55 + left_margin, ybefore)
    rep.multi_cell(0.2 * W,
                   2 * c_height,
                   txt=" STAN LICZNIKA: \n " + printed_values[16],
                   align="C",
                   border=1)
    rep.set_xy(W * 0.75 + left_margin, ybefore)
    rep.multi_cell(0.25 * W,
                   2 * c_height,
                   txt=" KM. DO MIEJSCA ZD: \n " + printed_values[17],
                   align="C",
                   border=1)

    modDate = str(printed_values[18])[11:].replace(":", "")
    path = pdf_save_path + "/" + str(report_no) + "_" + str(
        printed_values[4]) + "_" + str(
            printed_values[1]) + "_" + modDate + ".pdf"
    rep.output(path)
示例#22
0
pdf.cell(table_width, table_height, 'Score 0~4:', 1, 1)
for row in Table_Data_0_4:
    for item in row:
        split_item = item.split()
        divide = math.ceil(len(split_item) / char_per_line)
        mod = len(split_item) % char_per_line
        for i in range(divide):
            split_portion = split_item[i * char_per_line:(i + 1) *
                                       char_per_line:]
            each_portion = ' '.join(split_portion)
            pdf.cell(table_width, table_height, each_portion, 1, 1)
            # if i == (divide - 1):
            #     split_portion = split_item[i*char_per_line:i*char_per_line+mod:]
            #     each_portion = ' '.join(split_portion)
            #     pdf.cell(table_width, table_height, each_portion, 1, 1)

pdf.set_xy(int(pdf.get_x()), int(pdf.get_y()) + 20)
pdf.cell(table_width, table_height, 'Score 5~7:', 1, 1)
for row in Table_Data_5_7:
    for item in row:
        split_item = item.split()
        divide = math.ceil(len(split_item) / char_per_line)
        mod = len(split_item) % char_per_line
        for i in range(divide):
            split_portion = split_item[i * char_per_line:(i + 1) *
                                       char_per_line:]
            each_portion = ' '.join(split_portion)
            pdf.cell(table_width, table_height, each_portion, 1, 1)

pdf.output("App_Satisfication.pdf")
示例#23
0
文件: pdf.py 项目: PinkyJie/resume
 pdf.dashed_line(page_size['left'] + 1, header_y, page_size['end_x'] + 1, header_y, 1, 1)
 pdf.ln(2)
 # about section
 pdf.set_font(title_font, '', font_size['section_title'])
 pdf.cell(1, line_height['section'] - 1, data['sections']['about'], ln=2)
 pdf.set_font(text_font, '', font_size['text'])
 col_1_count = len(data['about']['introduction']) / 2
 desc_y = pdf.get_y()
 for idx, desc in enumerate(data['about']['introduction']):
     if idx == col_1_count:
         pdf.set_y(desc_y)
     if idx < col_1_count:
         pdf.set_x(page_size['left'] + page_size['section_indent'])
     else:
         pdf.set_x(page_size['middle_x'])
     pdf.ellipse(pdf.get_x(), pdf.get_y() + 1.1, ellipse['size'], ellipse['size'], 'F')
     pdf.cell(ellipse['margin'])
     pdf.cell(1, line_height['text'] - 1, desc, ln=2)
 pdf.ln(page_size['section_margin'])
 # education section
 pdf.set_x(page_size['left'])
 pdf.set_font(title_font, '', font_size['section_title'])
 pdf.cell(1, line_height['section'] - 1, data['sections']['education'], ln=2)
 pdf.set_font(text_font, '', font_size['text'])
 for univ in data['education']['universities']:
     pdf.set_x(page_size['left'] + page_size['section_indent'])
     univ_y = pdf.get_y()
     pdf.set_font_size(font_size['text'] + 1)
     pdf.set_text_color(*brown)
     pdf.cell(1, line_height['text'], univ['name'], ln=2)
     pdf.set_font_size(font_size['text'])
示例#24
0
def formatPdf(data):
	pdf = FPDF()
	pdf.add_page()
	pdf.set_font('Arial', 'B', 16)
	
	# title of the label 
	pdf.cell(w = 0,h = 15, txt='Rivia.Ai', border=0, ln=1, align = 'C')
	
	# adding seller 
	
	pdf.set_font('Arial', 'B', 12)
	pdf.cell(w = 95, h = 15, txt = "Sold By", border=0, ln = 0, align = 'L')
	pdf.set_font('Arial', '', 12)
	sellerName = ""
	if 'sold_by' in data.keys():
		sellerName = str(data['sold_by'])
	pdf.cell(w = 95, h = 15, txt = sellerName, border=0, ln = 1, align = 'R')
	
	pdf.set_font('Arial', 'B', 12)
	pdf.cell(w = 95, h = 15, txt = "Delivered By", border=0, ln = 0, align = 'L')
	pdf.set_font('Arial', '', 12)
	deliveryAgent = ""
	if 'delivered_by' in data.keys():
		deliveryAgent = str(data['delivered_by'])
	pdf.cell(w = 95, h = 15, txt = deliveryAgent, border=0, ln = 1, align = 'R')
	
	if 'shipping_address' in data.keys():
		pdf.set_font('Arial', 'B', 12)
		address = "Shipping Address:\n"
		for part in data['shipping_address'].values():
			address += part
			address += '\n'
		x = pdf.get_x()
		y = pdf.get_y()
		pdf.multi_cell(w = 95, h = 5, txt = address, border=0, align = 'L')
		p = pdf.get_x()
		q = pdf.get_y()
		x += 95
		pdf.set_xy(x, y)
		pdf.set_font('Arial', 'B', 30)
		if 'payment' in data.keys():
			if 'mode' in data['payment'].keys():
				pdf.cell(w = 95, h = q-y, txt = str(data['payment']['mode']), border=0, ln = 1, align = 'C')
		pdf.set_xy(p, q)

	pdf.cell(w = 95, h = 10, txt = "", border=0, ln = 0, align = 'L')
	pdf.cell(w = 95, h = 10, txt = "", border=0, ln = 1, align = 'R')
	
	pdf.set_font('Arial', 'B', 12)
	pdf.cell(w = 95, h = 5, txt = "Order Date:", border=0, ln = 0, align = 'L')
	pdf.cell(w = 95, h = 5, txt = "Tracking ID:", border=0, ln = 1, align = 'R')
	pdf.set_font('Arial', '', 12)
	order_date = ""
	tracking_id = ""
	if 'order_date' in data.keys():
		order_date = data['order_date']
	if 'tracking_id' in data.keys():
		tracking_id = data['tracking_id']
	pdf.cell(w = 95, h = 5, txt = order_date, border=0, ln = 0, align = 'L')
	pdf.cell(w = 95, h = 5, txt = tracking_id, border=0, ln = 1, align = 'R')
	
	pdf.cell(w = 95, h = 10, txt = "", border=0, ln = 0, align = 'L')
	pdf.cell(w = 95, h = 10, txt = "", border=0, ln = 1, align = 'R')
	
	if 'line_items' in data.keys():
		itemsToBeDilivered = [["PRODUCT", "DETAILS(opt)", "QTY"]]
		for item in data['line_items']:
			product = []
			for productDetails in item.values():
				product.append(str(productDetails))
			itemsToBeDilivered.append(product)
		for r in itemsToBeDilivered:
			for c in range(3):
				if c != 2:
					pdf.cell(w = (190.00 / 3), h = 10, txt = str(r[c]), border=1, ln = 0, align = 'L')
				else:
					pdf.cell(w = (190.00 / 3), h = 10, txt = str(r[c]), border=1, ln = 1, align = 'L')

	pdf.set_font('Arial', 'B', 16)

	pdf.cell(w = 95, h = 20, txt = "Invoice Value ", border=0, ln = 0, align = 'C')
	cost = 0
	if 'payment' in data.keys():
		if 'amount' in data['payment'].keys():
			cost = float(str(data['payment']['amount']))
	pdf.cell(w = 95, h = 20, txt = "INR " + str(cost), border=0, ln = 1, align = 'C')

	returnAddress = ""
	if 'return_address' in data.keys():
		for addr in data['return_address'].values():
			returnAddress += str(addr)
			returnAddress += " "
	pdf.set_font('Arial', 'B', 14)
	pdf.cell(w = 0,h = 15, txt="Return Address:", border=0, ln=1, align = 'C')
	pdf.set_font('Arial', '', 14)
	pdf.cell(w = 0,h = 15, txt=returnAddress, border=0, ln=1, align = 'C')	
	return pdf
def export_weeks_to_pdf(schedule_ref: Schedule,
                        title_text: str,
                        add_date: bool,
                        file_path: str,
                        font_name: str,
                        font_path: str,
                        encoding: str,
                        start: datetime.date,
                        end: datetime.date,
                        color_a: QColor,
                        color_b: QColor,
                        progress=None) -> None:
    """
    Method for exports to PDF file
    """

    file = QFileInfo(file_path)

    # pdf
    pdf = FPDF(orientation="L")

    # encoding
    if encoding == "UTF-8":
        pdf.add_font(font_name, "", font_path, uni=True)
    else:
        pdf.add_font(font_name, "", font_path)
        pdf.set_doc_option("core_fonts_encoding", encoding)

    # processing
    week_step = 100 / (end - start).days / 7
    count = 0

    pdf.set_font(font_name)

    while True:
        pdf.add_page()

        schedule = schedule_ref.create_week_schedule(
            start, start + datetime.timedelta(days=6))

        indexes = schedule.indexes()
        table_widget = schedule_editor_window.ScheduleTableWidget()
        table_widget.set_schedule(schedule)

        start += datetime.timedelta(days=6)

        x, y = float(pdf.get_x()), float(pdf.get_y())
        w = float(pdf.w) - 2 * float(pdf.get_x())
        h = float(pdf.h) - 2 * float(pdf.get_y()) - 6

        pdf.set_auto_page_break(True, margin=y)

        title = 10
        title_page = title_text
        if add_date:
            start_week = (start +
                          datetime.timedelta(days=-6)).strftime("%d.%m.%Y")
            end_week = start.strftime("%d.%m.%Y")
            title_page += f". {start_week} - {end_week}"

        pdf.set_font_size(14)
        pdf.cell(w, title, txt=title_page, align="C", border=0)
        h -= title

        first_column, first_row = 4, 4

        step_column = (w - first_row) / 8
        step_row = (h - first_column) / 6

        i = 0
        while i < 7:
            j = 0
            while j < 9:
                if i == 0 and j == 0:
                    # upper-left cell
                    pdf.set_xy(x, y + title)
                    pdf.cell(first_column, first_row, border=1)
                    j += 1
                elif i == 0:
                    # top cells with time
                    pdf.set_xy(x + first_row + step_column * (j - 1),
                               y + title)
                    pdf.set_font_size(8)
                    pdf.cell(step_column,
                             first_row,
                             txt=TimePair.time_start_end(j - 1),
                             align="C",
                             border=1)
                    j += 1
                elif j == 0:
                    # left cells with days of the week
                    pdf.set_xy(
                        x, y + title + first_column + step_row * (i - 1) +
                        step_row)
                    pdf.rotate(90)
                    pdf.set_font_size(8)
                    pdf.cell(step_row,
                             first_row,
                             txt=str(DaysOfWeek.value_of(i - 1)),
                             align="C",
                             border=1)
                    pdf.rotate(0)
                    j += 1
                else:
                    # cells inside the table
                    pdf.set_xy(x + first_row + step_column * (j - 1),
                               y + title + first_column + step_row * (i - 1))

                    simple_row = (step_row / indexes[i - 1])
                    prev_x, prev_y = pdf.get_x(), pdf.get_y()

                    start_index = sum(indexes[r] for r in range(i - 1))
                    number_row = 0
                    for m in range(start_index, start_index + indexes[i - 1]):
                        item = table_widget.item(m, j - 1)
                        if item is not None:
                            x_span_count = table_widget.columnSpan(m, j - 1)
                            y_span_count = table_widget.rowSpan(m, j - 1)

                            pdf.set_xy(prev_x,
                                       prev_y + number_row * simple_row)

                            # pdf.cell(step_column * x_span_count,
                            #          simple_row * y_span_count,
                            #          border=1)

                            day, number, duration = i - 1, j - 1, x_span_count
                            pairs = schedule.pairs_by_index(
                                day, number, duration, number_row)

                            # select color for cell
                            if all(pair["subgroup"].get_subgroup() ==
                                   SubgroupPairAttrib.Common
                                   for pair in pairs):
                                # common
                                pdf.cell(step_column * x_span_count,
                                         simple_row * y_span_count,
                                         border=1)

                            elif all(pair["subgroup"].get_subgroup() ==
                                     SubgroupPairAttrib.A for pair in pairs):
                                # A subgroup
                                pdf.set_fill_color(color_a.red(),
                                                   color_a.green(),
                                                   color_a.blue())
                                pdf.cell(step_column * x_span_count,
                                         simple_row * y_span_count,
                                         border=1,
                                         fill=1)
                            elif all(pair["subgroup"].get_subgroup() ==
                                     SubgroupPairAttrib.B for pair in pairs):
                                # B subgroup
                                pdf.set_fill_color(color_b.red(),
                                                   color_b.green(),
                                                   color_b.blue())
                                pdf.cell(step_column * x_span_count,
                                         simple_row * y_span_count,
                                         border=1,
                                         fill=1)
                            else:
                                # A and B subgroup
                                prev_x = pdf.get_x()
                                prev_y = pdf.get_y()

                                toggle = True

                                row = 5
                                column = math.ceil(step_column * x_span_count /
                                                   step_row * row)

                                for t in range(column):
                                    for n in range(row):
                                        pdf.set_xy(
                                            prev_x + t * step_column *
                                            x_span_count / column,
                                            prev_y + n * step_row / row)

                                        if toggle:
                                            color = color_a
                                            toggle = False
                                        else:
                                            color = color_b
                                            toggle = True

                                        pdf.set_fill_color(
                                            color.red(), color.green(),
                                            color.blue())
                                        pdf.cell(step_column * x_span_count /
                                                 column,
                                                 simple_row * y_span_count /
                                                 row,
                                                 border=0)

                                pdf.set_xy(prev_x, prev_y)
                                pdf.cell(step_column * x_span_count,
                                         simple_row * y_span_count,
                                         border=1)

                            if len(pairs) != 0:
                                text = "\n".join(str(pair) for pair in pairs)
                                draw_text(
                                    pdf, x + first_row + step_column * (j - 1),
                                    y + title + first_column + step_row *
                                    (i - 1) + simple_row * number_row,
                                    step_column * x_span_count,
                                    simple_row * y_span_count, text)
                        number_row += 1
                        pdf.set_xy(prev_x, prev_y)
                    j += 1

                    # old
                    # pairs = schedule.pairs_by_index(i - 1, j - 1, 1) \
                    #     + schedule.pairs_by_index(i - 1, j - 1, 2)
                    #
                    # max_duration = max([1, *[pair["time"].duration() for pair in pairs]])
                    #
                    # # select color for cell
                    # if all(pair["subgroup"].get_subgroup() == SubgroupPairAttrib.Common
                    #        for pair in pairs):
                    #     # common
                    #     pdf.cell(step_column * max_duration,
                    #              step_row,
                    #              border=1)
                    # elif all(pair["subgroup"].get_subgroup() == SubgroupPairAttrib.A
                    #          for pair in pairs):
                    #     # A subgroup
                    #     pdf.set_fill_color(color_a.red(), color_a.green(), color_a.blue())
                    #     pdf.cell(step_column * max_duration,
                    #              step_row,
                    #              border=1,
                    #              fill=1)
                    # elif all(pair["subgroup"].get_subgroup() == SubgroupPairAttrib.B
                    #          for pair in pairs):
                    #     # B subgroup
                    #     pdf.set_fill_color(color_b.red(), color_b.green(), color_b.blue())
                    #     pdf.cell(step_column * max_duration,
                    #              step_row,
                    #              border=1,
                    #              fill=1)
                    # else:
                    #     # A and B subgroup
                    #     prev_x = pdf.get_x()
                    #     prev_y = pdf.get_y()
                    #
                    #     toggle = True
                    #
                    #     row = 5
                    #     column = math.ceil(step_column * max_duration / step_row * row)
                    #
                    #     for m in range(column):
                    #         for n in range(row):
                    #             pdf.set_xy(prev_x + m * step_column * max_duration / column,
                    #                        prev_y + n * step_row / row)
                    #
                    #             if toggle:
                    #                 color = color_a
                    #                 toggle = False
                    #             else:
                    #                 color = color_b
                    #                 toggle = True
                    #
                    #             pdf.set_fill_color(color.red(), color.green(), color.blue())
                    #             pdf.cell(step_column * max_duration / column,
                    #                      step_row / row,
                    #                      border=0,
                    #                      fill=1)
                    #     pdf.set_xy(prev_x, prev_y)
                    #     pdf.cell(step_column * max_duration,
                    #              step_row,
                    #              border=1)
                    # text = ""
                    # for pair in pairs:
                    #     text += str(pair) + "\n"
                    #
                    # if text != "":
                    #     draw_text(pdf,
                    #               x + first_row + step_column * (j - 1),
                    #               y + title + first_column + step_row
                    #               * (i - 1),
                    #               step_column * max_duration,
                    #               step_row,
                    #               text)
                    # j += max_duration
            i += 1

        if progress is not None:
            count += 1
            progress.setValue(week_step * count)
            if progress.wasCanceled():
                break

        start += datetime.timedelta(days=1)
        if end <= start:
            break

    pdf.output(file.absoluteFilePath())
示例#26
0
for page in range(pages):
    pdf.add_page()
    pdf.set_y(margin_top)
    for row in range(rows):
        pdf.set_x(margin_left)
        for column in range(columns):
            cell_id = start_id + (column + row * columns)
            qr_filename = image_folder + str(cell_id) + ".png"
            url = base_url + str(cell_id)
            # Generate QR CODE
            img = qrcode.make(url, border=0)
            img.save(qr_filename, "PNG")
            # Write in our QR code
            pdf.image(
                x=pdf.get_x() + image_border,
                y=pdf.get_y() + image_border,
                w=max_dimension - image_border * 2,
                h=max_dimension - image_border * 2,
                name=qr_filename,
                link=url,
            )
            # Add the logo
            pdf.image(
                x=pdf.get_x() + max_dimension,
                y=pdf.get_y() + image_border,
                w=logo_width,
                h=logo_height,
                name=logo_filename,
            )
            # Print the id
示例#27
0
class Report:
    def __init__(self, data: DataSet, stats=None) -> None:
        self.output_path = os.path.join(data.data_path, "stats")
        self.dataset_name = os.path.basename(data.data_path)
        self.io_handler = data.io_handler

        self.mapi_light_light_green = [255, 255, 255]
        self.mapi_light_green = [0, 0, 0]
        self.mapi_light_grey = [218, 222, 228]
        self.mapi_dark_grey = [0, 0, 0]

        self.pdf = FPDF("P", "mm", "A4")
        self.pdf.add_page()

        self.title_size = 20
        self.h1 = 16
        self.h2 = 13
        self.h3 = 10
        self.text = 10
        self.small_text = 8
        self.margin = 10
        self.cell_height = 7
        self.total_size = 190
        self.odm_stat = 'odm_processing_statistics'

        if stats is not None:
            self.stats = stats
        else:
            self.stats = self._read_stats_file("stats.json")

    def save_report(self, filename: str) -> None:
        # pyre-fixme[28]: Unexpected keyword argument `dest`.
        bytestring = self.pdf.output(dest="S")
        if isinstance(bytestring, str):
            bytestring = bytestring.encode("utf8")

        with self.io_handler.open(os.path.join(self.output_path, filename),
                                  "wb") as fwb:
            fwb.write(bytestring)

    def _make_table(self, columns_names, rows, row_header=False) -> None:
        self.pdf.set_font("Helvetica", "", self.h3)
        self.pdf.set_line_width(0.3)

        columns_sizes = [int(self.total_size / len(rows[0]))] * len(rows[0])

        if columns_names:
            self.pdf.set_draw_color(*self.mapi_light_grey)
            self.pdf.set_fill_color(*self.mapi_light_grey)
            for col, size in zip(columns_names, columns_sizes):
                self.pdf.rect(
                    self.pdf.get_x(),
                    self.pdf.get_y(),
                    size,
                    self.cell_height,
                    style="FD",
                )
                self.pdf.set_text_color(*self.mapi_dark_grey)
                self.pdf.cell(size, self.cell_height, col, align="L")
            self.pdf.set_xy(self.margin, self.pdf.get_y() + self.cell_height)

        self.pdf.set_draw_color(*self.mapi_light_grey)
        self.pdf.set_fill_color(*self.mapi_light_light_green)

        for row in rows:
            for i, (col, size) in enumerate(zip(row, columns_sizes)):
                if i == 0 and row_header:
                    self.pdf.set_draw_color(*self.mapi_light_grey)
                    self.pdf.set_fill_color(*self.mapi_light_grey)
                self.pdf.rect(
                    self.pdf.get_x(),
                    self.pdf.get_y(),
                    size,
                    self.cell_height,
                    style="FD",
                )
                self.pdf.set_text_color(*self.mapi_dark_grey)
                if i == 0 and row_header:
                    self.pdf.set_draw_color(*self.mapi_light_grey)
                    self.pdf.set_fill_color(*self.mapi_light_light_green)
                self.pdf.cell(size, self.cell_height, col, align="L")
            self.pdf.set_xy(self.margin, self.pdf.get_y() + self.cell_height)

    def _read_stats_file(self, filename) -> Dict[str, Any]:
        file_path = os.path.join(self.output_path, filename)
        with self.io_handler.open_rt(file_path) as fin:
            return io.json_load(fin)

    def _read_gcp_stats_file(self, filename):
        file_path = os.path.join(self.output_path,
                                 "ground_control_points.json")

        with self.io_handler.open_rt(file_path) as fin:
            return io.json_load(fin)

    def _make_section(self, title: str) -> None:
        self.pdf.set_font("Helvetica", "B", self.h1)
        self.pdf.set_text_color(*self.mapi_dark_grey)
        self.pdf.cell(0, self.margin, title, align="L")
        self.pdf.set_xy(self.margin, self.pdf.get_y() + 1.5 * self.margin)

    def _make_subsection(self, title: str) -> None:
        self.pdf.set_xy(self.margin, self.pdf.get_y() - 0.5 * self.margin)
        self.pdf.set_font("Helvetica", "B", self.h2)
        self.pdf.set_text_color(*self.mapi_dark_grey)
        self.pdf.cell(0, self.margin, title, align="L")
        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def _make_centered_image(self, image_path: str,
                             desired_height: float) -> None:

        with tempfile.TemporaryDirectory() as tmp_local_dir:
            local_image_path = os.path.join(tmp_local_dir,
                                            os.path.basename(image_path))
            with self.io_handler.open(local_image_path, "wb") as fwb:
                with self.io_handler.open(image_path, "rb") as f:
                    fwb.write(f.read())

            width, height = PIL.Image.open(local_image_path).size
            resized_width = width * desired_height / height
            if resized_width > self.total_size:
                resized_width = self.total_size
                desired_height = height * resized_width / width

            self.pdf.image(
                local_image_path,
                self.pdf.get_x() + self.total_size / 2 - resized_width / 2,
                self.pdf.get_y(),
                h=desired_height,
            )
            self.pdf.set_xy(self.margin,
                            self.pdf.get_y() + desired_height + self.margin)

    def make_title(self) -> None:
        # title
        self.pdf.set_font("Helvetica", "B", self.title_size)
        self.pdf.set_text_color(*self.mapi_light_green)
        self.pdf.cell(0, self.margin, "ODM Quality Report", align="C")
        self.pdf.set_xy(self.margin, self.title_size)

        # version number
        version_file = os.path.abspath(
            os.path.join(os.path.dirname(__file__), "../../../../../VERSION"))
        try:
            with open(version_file, 'r') as f:
                version = f.read().strip()
        except Exception as e:  # indicate we don't know the version
            version = "unknown"
            logger.warning(f"Invalid ODM version {version_file}: " + str(e))

        self.pdf.set_font("Helvetica", "", self.small_text)
        self.pdf.set_text_color(*self.mapi_dark_grey)
        self.pdf.cell(0,
                      self.margin,
                      f"Processed with ODM version {version}",
                      align="R")
        self.pdf.set_xy(self.margin, self.pdf.get_y() + 2 * self.margin)

    def make_dataset_summary(self) -> None:
        self._make_section("Dataset Summary")

        rows = [
            #["Dataset", self.dataset_name],
            ["Date", self.stats["processing_statistics"]["date"]],
            [
                "Area Covered",
                f"{self.stats['processing_statistics']['area']/1e6:.6f} km²",
            ],
            [
                "Processing Time",
                self.stats[self.odm_stat]['total_time_human'] if self.odm_stat in self.stats else \
                f"{self.stats['processing_statistics']['steps_times']['Total Time']:.2f} seconds",
            ],
            ["Capture Start", self.stats["processing_statistics"]["start_date"]],
            ["Capture End", self.stats["processing_statistics"]["end_date"]],
        ]
        self._make_table(None, rows, True)
        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def _has_meaningful_gcp(self) -> bool:
        return (self.stats["reconstruction_statistics"]["has_gcp"]
                and "average_error" in self.stats["gcp_errors"])

    def make_processing_summary(self) -> None:
        self._make_section("Processing Summary")

        rec_shots, init_shots = (
            self.stats["reconstruction_statistics"]
            ["reconstructed_shots_count"],
            self.stats["reconstruction_statistics"]["initial_shots_count"],
        )
        rec_points, init_points = (
            self.stats["reconstruction_statistics"]
            ["reconstructed_points_count"],
            self.stats["reconstruction_statistics"]["initial_points_count"],
        )

        geo_string = []
        if self.stats["reconstruction_statistics"]["has_gps"]:
            geo_string.append("GPS")
        if self._has_meaningful_gcp():
            geo_string.append("GCP")

        ratio_shots = rec_shots / init_shots * 100 if init_shots > 0 else -1
        rows = [
            [
                "Reconstructed Images",
                f"{rec_shots} over {init_shots} shots ({ratio_shots:.1f}%)",
            ],
            [
                "Reconstructed Points (Sparse)",
                f"{rec_points} over {init_points} points ({rec_points/init_points*100:.1f}%)",
            ],
            # [
            #     "Reconstructed Components",
            #     f"{self.stats['reconstruction_statistics']['components']} component",
            # ],
            [
                "Detected Features",
                f"{self.stats['features_statistics']['detected_features']['median']:,} features",
            ],
            [
                "Reconstructed Features",
                f"{self.stats['features_statistics']['reconstructed_features']['median']:,} features",
            ],
            ["Geographic Reference", " and ".join(geo_string)],
        ]

        # Dense (if available)
        if self.stats.get('point_cloud_statistics'):
            if self.stats['point_cloud_statistics'].get('dense'):
                rows.insert(2, [
                    "Reconstructed Points (Dense)",
                    f"{self.stats['point_cloud_statistics']['stats']['statistic'][0]['count']:,} points"
                ])

        # GSD (if available)
        if self.odm_stat in self.stats and self.stats[self.odm_stat].get(
                'average_gsd'):
            rows.insert(3, [
                "Average Ground Sampling Distance (GSD)",
                f"{self.stats[self.odm_stat]['average_gsd']:.1f} cm"
            ])

        row_gps_gcp = [" / ".join(geo_string) + " errors"]
        geo_errors = []
        if self.stats["reconstruction_statistics"]["has_gps"]:
            geo_errors.append(
                f"{self.stats['gps_errors']['average_error']:.2f}")
        if self._has_meaningful_gcp():
            geo_errors.append(
                f"{self.stats['gcp_errors']['average_error']:.2f}")
        row_gps_gcp.append(" / ".join(geo_errors) + " meters")
        rows.append(row_gps_gcp)

        self._make_table(None, rows, True)
        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)

        topview_height = 110
        topview_grids = [
            f for f in self.io_handler.ls(self.output_path)
            if f.startswith("topview")
        ]
        self._make_centered_image(
            os.path.join(self.output_path, topview_grids[0]), topview_height)

        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def make_processing_time_details(self) -> None:
        self._make_section("Processing Time Details")

        columns_names = list(
            self.stats["processing_statistics"]["steps_times"].keys())
        formatted_floats = []
        for v in self.stats["processing_statistics"]["steps_times"].values():
            formatted_floats.append(f"{v:.2f} sec.")
        rows = [formatted_floats]
        self._make_table(columns_names, rows)
        self.pdf.set_xy(self.margin, self.pdf.get_y() + 2 * self.margin)

    def make_gcp_error_details(self):
        self._make_section("Ground Control Point Error")

        gcp_stats = self._read_gcp_stats_file("ground_control_points.json")

        rows = []
        column_names = ["ID", "Error X (m)", "Error Y (m)", "Error Z (m)"]

        for gcp in gcp_stats:
            row = [gcp["id"]]
            row.append(f"{gcp['error'][0]:.3f}")
            row.append(f"{gcp['error'][1]:.3f}")
            row.append(f"{gcp['error'][2]:.3f}")

            rows.append(row)

        self._make_table(column_names, rows)
        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)

    def make_gps_details(self) -> None:
        self._make_section("GPS/GCP/3D Errors Details")

        # GPS
        table_count = 0
        for error_type in ["gps", "gcp", "3d"]:
            rows = []
            columns_names = [error_type.upper(), "Mean", "Sigma", "RMS Error"]
            if "average_error" not in self.stats[error_type + "_errors"]:
                continue
            for comp in ["x", "y", "z"]:
                row = [comp.upper() + " Error (meters)"]
                row.append(
                    f"{self.stats[error_type + '_errors']['mean'][comp]:.3f}")
                row.append(
                    f"{self.stats[error_type +'_errors']['std'][comp]:.3f}")
                row.append(
                    f"{self.stats[error_type +'_errors']['error'][comp]:.3f}")
                rows.append(row)

            rows.append([
                "Total",
                "",
                "",
                f"{self.stats[error_type +'_errors']['average_error']:.3f}",
            ])
            self._make_table(columns_names, rows)
            self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)
            table_count += 1

        if table_count > 0:
            abs_error_type = "gps" if table_count == 2 else "gcp"

            a_ce90 = self.stats[abs_error_type + "_errors"].get("ce90", 0)
            a_le90 = self.stats[abs_error_type + "_errors"].get("le90", 0)
            r_ce90 = self.stats["3d_errors"].get("ce90", 0)
            r_le90 = self.stats["3d_errors"].get("le90", 0)

            rows = []
            if a_ce90 > 0 and a_le90 > 0:
                rows += [[
                    "Horizontal Accuracy CE90 (meters)",
                    f"{a_ce90:.3f}",
                    f"{r_ce90:.3f}" if r_ce90 > 0 else "-",
                ],
                         [
                             "Vertical Accuracy LE90 (meters)",
                             f"{a_le90:.3f}",
                             f"{r_le90:.3f}" if r_le90 > 0 else "-",
                         ]]

            if rows:
                if table_count > 2:
                    self.add_page_break()
                self._make_table(["", "Absolute", "Relative"], rows, True)
                self.pdf.set_xy(self.margin,
                                self.pdf.get_y() + self.margin / 2)

        # rows = []
        # columns_names = [
        #     "GPS Bias",
        #     "Scale",
        #     "Translation",
        #     "Rotation",
        # ]
        # for camera, params in self.stats["camera_errors"].items():
        #     bias = params["bias"]
        #     s, t, R = bias["scale"], bias["translation"], bias["rotation"]
        #     rows.append(
        #         [
        #             camera,
        #             f"{s:.2f}",
        #             f"{t[0]:.2f}      {t[1]:.2f}      {t[2]:.2f}",
        #             f"{R[0]:.2f}      {R[1]:.2f}      {R[2]:.2f}",
        #         ]
        #     )
        # self._make_table(columns_names, rows)

        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)

    def make_features_details(self) -> None:
        self._make_section("Features Details")

        heatmap_height = 60
        heatmaps = [
            f for f in self.io_handler.ls(self.output_path)
            if f.startswith("heatmap")
        ]
        self._make_centered_image(os.path.join(self.output_path, heatmaps[0]),
                                  heatmap_height)
        if len(heatmaps) > 1:
            logger.warning("Please implement multi-model display")

        columns_names = ["", "Min.", "Max.", "Mean", "Median"]
        rows = []
        for comp in ["detected_features", "reconstructed_features"]:
            row = [comp.replace("_", " ").replace("features", "").capitalize()]
            for t in columns_names[1:]:
                row.append(
                    f"{self.stats['features_statistics'][comp][t.replace('.', '').lower()]:.0f}"
                )
            rows.append(row)
        self._make_table(columns_names, rows)

        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def make_reconstruction_details(self) -> None:
        self._make_section("Reconstruction Details")

        rows = [
            [
                "Average Reprojection Error (normalized / pixels / angular)",
                (f"{self.stats['reconstruction_statistics']['reprojection_error_normalized']:.2f} / "
                 f"{self.stats['reconstruction_statistics']['reprojection_error_pixels']:.2f} / "
                 f"{self.stats['reconstruction_statistics']['reprojection_error_angular']:.5f}"
                 ),
            ],
            [
                "Average Track Length",
                f"{self.stats['reconstruction_statistics']['average_track_length']:.2f} images",
            ],
            [
                "Average Track Length (> 2)",
                f"{self.stats['reconstruction_statistics']['average_track_length_over_two']:.2f} images",
            ],
        ]
        self._make_table(None, rows, True)
        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 1.5)

        residual_histogram_height = 60
        residual_histogram = [
            f for f in self.io_handler.ls(self.output_path)
            if f.startswith("residual_histogram")
        ]
        self._make_centered_image(
            os.path.join(self.output_path, residual_histogram[0]),
            residual_histogram_height,
        )
        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def make_camera_models_details(self) -> None:
        self._make_section("Camera Models Details")

        for camera, params in self.stats["camera_errors"].items():
            residual_grids = [
                f for f in self.io_handler.ls(self.output_path)
                if f.startswith("residuals_" + str(camera.replace("/", "_")))
            ]
            if not residual_grids:
                continue

            initial = params["initial_values"]
            optimized = params["optimized_values"]
            names = [""] + list(initial.keys())

            rows = []
            rows.append(["Initial"] + [f"{x:.4f}" for x in initial.values()])
            rows.append(["Optimized"] +
                        [f"{x:.4f}" for x in optimized.values()])

            self._make_subsection(camera)
            self._make_table(names, rows)
            self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)

            residual_grid_height = 100
            self._make_centered_image(
                os.path.join(self.output_path, residual_grids[0]),
                residual_grid_height)

    def make_rig_cameras_details(self) -> None:
        if len(self.stats["rig_errors"]) == 0:
            return

        self._make_section("Rig Cameras Details")

        columns_names = [
            "Translation X",
            "Translation Y",
            "Translation Z",
            "Rotation X",
            "Rotation Y",
            "Rotation Z",
        ]
        for rig_camera_id, params in self.stats["rig_errors"].items():
            initial = params["initial_values"]
            optimized = params["optimized_values"]

            rows = []
            r_init, t_init = initial["rotation"], initial["translation"]
            r_opt, t_opt = optimized["rotation"], optimized["translation"]
            rows.append([
                f"{t_init[0]:.4f} m",
                f"{t_init[1]:.4f} m",
                f"{t_init[2]:.4f} m",
                f"{r_init[0]:.4f}",
                f"{r_init[1]:.4f}",
                f"{r_init[2]:.4f}",
            ])
            rows.append([
                f"{t_opt[0]:.4f} m",
                f"{t_opt[1]:.4f} m",
                f"{t_opt[2]:.4f} m",
                f"{r_opt[0]:.4f}",
                f"{r_opt[1]:.4f}",
                f"{r_opt[2]:.4f}",
            ])

            self._make_subsection(rig_camera_id)
            self._make_table(columns_names, rows)
            self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)

    def make_tracks_details(self) -> None:
        self._make_section("Tracks Details")
        matchgraph_height = 80
        matchgraph = [
            f for f in self.io_handler.ls(self.output_path)
            if f.startswith("matchgraph")
        ]
        self._make_centered_image(
            os.path.join(self.output_path, matchgraph[0]), matchgraph_height)

        histogram = self.stats["reconstruction_statistics"][
            "histogram_track_length"]
        start_length, end_length = 2, 10
        row_length = ["Length"]
        for length, _ in sorted(histogram.items(), key=lambda x: int(x[0])):
            if int(length) < start_length or int(length) > end_length:
                continue
            row_length.append(length)
        row_count = ["Count"]
        for length, count in sorted(histogram.items(),
                                    key=lambda x: int(x[0])):
            if int(length) < start_length or int(length) > end_length:
                continue
            row_count.append(f"{count}")

        self._make_table(None, [row_length, row_count], True)

        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

    def add_page_break(self) -> None:
        self.pdf.add_page("P")

    def make_survey_data(self):
        self._make_section("Survey Data")

        self._make_centered_image(
            os.path.join(self.output_path, "overlap.png"), 90)
        self._make_centered_image(
            os.path.join(self.output_path, "overlap_diagram_legend.png"), 3)

        self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin / 2)

    def _add_image_label(self, text):
        self.pdf.set_font_size(self.small_text)
        self.pdf.text(
            self.pdf.get_x() + self.total_size / 2 -
            self.pdf.get_string_width(text) / 2,
            self.pdf.get_y() - 5, text)

    def make_preview(self):
        ortho = os.path.join(self.output_path, "ortho.png")
        dsm = os.path.join(self.output_path, "dsm.png")
        dtm = os.path.join(self.output_path, "dtm.png")
        count = 0

        if os.path.isfile(ortho) or os.path.isfile(dsm):
            self._make_section("Previews")

            if os.path.isfile(ortho):
                self._make_centered_image(
                    os.path.join(self.output_path, ortho), 110)
                self._add_image_label("Orthophoto")
                count += 1

            if os.path.isfile(dsm) and self.stats.get('dsm_statistics'):
                self._make_centered_image(os.path.join(self.output_path, dsm),
                                          110)
                self._add_image_label("Digital Surface Model")

                self._make_centered_image(
                    os.path.join(self.output_path, "dsm_gradient.png"), 4)
                self.pdf.set_font_size(self.small_text)
                min_text = "{:,.2f}m".format(
                    self.stats['dsm_statistics']['min'])
                max_text = "{:,.2f}m".format(
                    self.stats['dsm_statistics']['max'])
                self.pdf.text(self.pdf.get_x() + 40,
                              self.pdf.get_y() - 5, min_text)
                self.pdf.text(
                    self.pdf.get_x() + 40 + 110.5 -
                    self.pdf.get_string_width(max_text),
                    self.pdf.get_y() - 5, max_text)
                count += 1

            if os.path.isfile(dtm) and self.stats.get('dtm_statistics'):
                if count >= 2:
                    self.add_page_break()

                self._make_centered_image(os.path.join(self.output_path, dtm),
                                          110)
                self._add_image_label("Digital Terrain Model")

                self._make_centered_image(
                    os.path.join(self.output_path, "dsm_gradient.png"), 4)
                self.pdf.set_font_size(self.small_text)
                min_text = "{:,.2f}m".format(
                    self.stats['dtm_statistics']['min'])
                max_text = "{:,.2f}m".format(
                    self.stats['dtm_statistics']['max'])
                self.pdf.text(self.pdf.get_x() + 40,
                              self.pdf.get_y() - 5, min_text)
                self.pdf.text(
                    self.pdf.get_x() + 40 + 110.5 -
                    self.pdf.get_string_width(max_text),
                    self.pdf.get_y() - 5, max_text)

            self.pdf.set_xy(self.margin, self.pdf.get_y() + self.margin)

            return True

    def generate_report(self) -> None:
        self.make_title()
        self.make_dataset_summary()
        self.make_processing_summary()
        self.add_page_break()

        if self.make_preview():
            self.add_page_break()

        if os.path.isfile(os.path.join(self.output_path, "overlap.png")):
            self.make_survey_data()

        self.make_gps_details()

        if os.path.isfile(
                os.path.join(self.output_path, "ground_control_points.json")):
            self.make_gcp_error_details()

        self.add_page_break()

        self.make_features_details()
        self.make_reconstruction_details()
        self.add_page_break()

        self.make_tracks_details()
        self.make_camera_models_details()
class MathWorksheetGenerator:
    """class for generating math worksheet of specified size and main_type"""
    def __init__(self, type_: str, max_number: int, question_count: int):
        self.main_type = type_
        self.max_number = max_number
        self.question_count = question_count
        self.pdf = FPDF()

        self.small_font_size = 10
        self.middle_font_size = 15
        self.large_font_size = 30
        self.size = 21
        self.tiny_pad_size = 2
        self.pad_size = 10
        self.large_pad_size = 30
        self.num_x_cell = 4
        self.num_y_cell = 2
        self.font_1 = 'Times'
        self.font_2 = 'Arial'

    # From https://stackoverflow.com/questions/6800193/what-is-the-most-efficient-way-of-finding-all-the-factors-of-a
    # -number-in-python
    def factors(self, n: int):
        return set(
            reduce(list.__add__,
                   ([i, n // i]
                    for i in range(1,
                                   int(n**0.5) + 1) if n % i == 0)))

    def division_helper(self, num) -> [int, int, int]:
        # prevent num = 0 or divisor = 1 or divisor = dividend
        factor = 1
        while not num or factor == 1 or factor == num:
            num = random.randint(0, self.max_number)
            # pick a factor of num; answer will always be an integer
            if num:
                factor = random.sample(self.factors(num), 1)[0]
        answer = int(num / factor)
        return [num, factor, answer]

    def generate_question(self) -> QuestionInfo:
        """Generates each question and calculate the answer depending on the type_ in a list
        To keep it simple, number is generated randomly within the range of 0 to 100
        :return:  list of value1, main_type, value2, and answer for the generated question
        """
        num_1 = random.randint(0, self.max_number)
        num_2 = random.randint(0, self.max_number)
        if self.main_type == 'mix':
            current_type = random.choice(['+', '-', 'x', '/'])
        else:
            current_type = self.main_type

        if current_type == '+':
            answer = num_1 + num_2
        elif current_type == '-':
            #  avoid having a negative answer which is an advanced concept
            num_1, num_2 = sorted((num_1, num_2), reverse=True)
            answer = num_1 - num_2
        elif current_type == 'x':
            answer = num_1 * num_2
        elif current_type == '/':
            num_1, num_2, answer = self.division_helper(num_1)

        else:
            raise RuntimeError(
                f'Question main_type {current_type} not supported')
        return num_1, current_type, num_2, answer

    def get_list_of_questions(self, question_count: int) -> List[QuestionInfo]:
        """Generate all the questions for the worksheet in a list. Initially trying for unique questions, but
        allowing duplicates if needed (e.g. asking for 80 addition problems with max size 3 requires duplication)
        :return: list of questions
        """
        questions = []
        duplicates = 0
        while len(questions) < question_count:
            new_question = self.generate_question()
            if new_question not in questions or duplicates >= 10:
                questions.append(new_question)
            else:
                duplicates += 1
        return questions

    def make_question_page(self, data: List[QuestionInfo]):
        """Prepare a single page of questions"""
        page_area = self.num_x_cell * self.num_y_cell
        problems_per_page = self.split_arr(self.question_count, page_area)
        total_pages = len(problems_per_page)
        for page in range(total_pages):
            self.pdf.add_page(orientation='L')
            if problems_per_page[page] < self.num_x_cell:
                self.print_question_row(data, page * page_area,
                                        problems_per_page[page])
            else:
                problems_per_row = self.split_arr(problems_per_page[page],
                                                  self.num_x_cell)
                total_rows = len(problems_per_row)
                self.print_question_row(data, page * page_area,
                                        problems_per_row[0])
                for row in range(1, total_rows):
                    page_row = row * self.num_x_cell
                    self.print_horizontal_separator()
                    self.print_question_row(data, page * page_area + page_row,
                                            problems_per_row[row])

    def split_arr(self, x: int, y: int):
        """Split x into x = y + y + ... + (x % y)"""
        quotient, remainder = divmod(x, y)
        if remainder != 0:
            return [y] * quotient + [remainder]

        return [y] * quotient

    def print_top_row(self, question_num: str):
        """Helper function to print first character row of a question row"""
        self.pdf.set_font(self.font_1, size=self.middle_font_size)
        self.pdf.cell(self.pad_size,
                      self.pad_size,
                      txt=question_num,
                      border='LT',
                      align='C')
        self.pdf.cell(self.size, self.pad_size, border='T')
        self.pdf.cell(self.size, self.pad_size, border='T')
        self.pdf.cell(self.pad_size, self.pad_size, border='TR')

    def print_second_row(self, num: int):
        """Helper function to print second character row of a question row"""
        self.pdf.set_font(self.font_2, size=self.large_font_size)
        self.pdf.cell(self.pad_size, self.size, border='L')
        self.pdf.cell(self.size, self.size)
        self.pdf.cell(self.size, self.size, txt=str(num), align='R')
        self.pdf.cell(self.pad_size, self.size, border='R')

    def print_second_row_division(self, num_1: int, num_2: int):
        """Helper function to print second character row of a question row for division"""
        self.pdf.set_font(self.font_2, size=self.large_font_size)
        self.pdf.cell(self.pad_size, self.size, border='L')
        self.pdf.cell(self.size, self.size, txt=str(num_2), align='R')
        x_cor = self.pdf.get_x() - 3
        y_cor = self.pdf.get_y()
        self.pdf.image(name='division.png', x=x_cor, y=y_cor)
        self.pdf.cell(self.size, self.size, txt=str(num_1), align='R')
        self.pdf.cell(self.pad_size, self.size, border='R')

    def print_third_row(self, num: int, current_type: str):
        """Helper function to print third character row of a question row"""
        self.pdf.cell(self.pad_size, self.size, border='L')
        self.pdf.cell(self.size, self.size, txt=current_type, align='L')
        self.pdf.cell(self.size, self.size, txt=str(num), align='R')
        self.pdf.cell(self.pad_size, self.size, border='R')

    def print_third_row_division(self):
        """Helper function to print third character row of a question row for division"""
        self.pdf.cell(self.pad_size, self.size, border='L')
        self.pdf.cell(self.size, self.size, align='L')
        self.pdf.cell(self.size, self.size, align='R')
        self.pdf.cell(self.pad_size, self.size, border='R')

    def print_bottom_row(self):
        """Helper function to print bottom row of question"""
        self.pdf.cell(self.pad_size, self.size, border='LB')
        self.pdf.cell(self.size, self.size, border='TB')
        self.pdf.cell(self.size, self.size, border='TB')
        self.pdf.cell(self.pad_size, self.size, border='BR')

    def print_bottom_row_division(self):
        """Helper function to print bottom row of question"""
        self.pdf.cell(self.pad_size, self.size, border='LB')
        self.pdf.cell(self.size, self.size, border='B')
        self.pdf.cell(self.size, self.size, border='B')
        self.pdf.cell(self.pad_size, self.size, border='BR')

    def print_edge_vertical_separator(self):
        """Print space between question for the top or bottom row"""
        self.pdf.cell(self.pad_size, self.pad_size)

    def print_middle_vertical_separator(self):
        """Print space between question for the second or third row"""
        self.pdf.cell(self.pad_size, self.size)

    def print_horizontal_separator(self):
        """Print line breaker between two rows of questions"""
        self.pdf.cell(self.size, self.size)
        self.pdf.ln()

    def print_question_row(self, data, offset, num_problems):
        """Print a single row of questions (total question in a row is set by num_x_cell)"""
        for x in range(0, num_problems):
            self.print_top_row(str(x + 1 + offset))
            self.print_edge_vertical_separator()
        self.pdf.ln()
        for x in range(0, num_problems):
            if data[x + offset][1] == '/':
                self.print_second_row_division(data[x + offset][0],
                                               data[x + offset][2])
            else:
                self.print_second_row(data[x + offset][0])
            self.print_middle_vertical_separator()
        self.pdf.ln()
        for x in range(0, num_problems):
            if data[x + offset][1] == '/':
                self.print_third_row_division()
            else:
                self.print_third_row(data[x + offset][2], data[x + offset][1])
            self.print_middle_vertical_separator()
        self.pdf.ln()
        for x in range(0, num_problems):
            if data[x + offset][1] == '/':
                self.print_bottom_row_division()
            else:
                self.print_bottom_row()
            self.print_edge_vertical_separator()
        self.pdf.ln()

    def make_answer_page(self, data):
        """Print answer sheet"""
        self.pdf.add_page(orientation='L')
        self.pdf.set_font(self.font_1, size=self.large_font_size)
        self.pdf.cell(self.large_pad_size,
                      self.large_pad_size,
                      txt='Answers',
                      ln=1,
                      align='C')

        for i in range(len(data)):
            self.pdf.set_font(self.font_1, size=self.small_font_size)
            self.pdf.cell(self.pad_size,
                          self.pad_size,
                          txt=f'{i + 1}:',
                          border='TLB',
                          align='R')
            self.pdf.set_font(self.font_2, size=self.small_font_size)
            self.pdf.cell(self.pad_size,
                          self.pad_size,
                          txt=str(data[i][3]),
                          border='TB',
                          align='R')
            self.pdf.cell(self.tiny_pad_size,
                          self.pad_size,
                          border='TRB',
                          align='R')
            self.pdf.cell(self.tiny_pad_size, self.pad_size, align='C')
            if i >= 9 and (i + 1) % 10 == 0:
                self.pdf.ln()
示例#29
0
now = datetime.datetime.now()
# title is generated with today's date time
picks_file = "reptilinks-picks-" + now.strftime("%Y-%m-%d %H%M%S") + ".pdf"
title = "Orders: " + str(order_num_min) + " - " + str(order_num_max)

# refer to https://pyfpdf.readthedocs.io/en/latest docs
# for more information on how to use their libary to format a pdf
pdf = FPDF(format="Letter")
pdf.add_page()
pdf.set_font('Times', '', 8)
pdf.cell(70, 5, title, 0, 1)

############################################
# regular
############################################
x = pdf.get_x()
y = pdf.get_y()

# refer to layout.py file for PrintCells function def
(xr, yr) = layout.PrintCells(pdf, "Regular", regular_products, x, y, y)

############################################
# Mini
############################################
(xm, ym) = layout.PrintCells(pdf, "Mini", mini_products, xr, yr, y)

############################################
# Non link
############################################
(xn, yn) = layout.PrintCells(pdf, "Non-link", non_sausage, xm, ym, y)
示例#30
0
                 header_y, 1, 1)
 pdf.ln(2)
 # about section
 pdf.set_font(title_font, '', font_size['section_title'])
 pdf.cell(1, line_height['section'] - 1, data['sections']['about'], ln=2)
 pdf.set_font(text_font, '', font_size['text'])
 col_1_count = len(data['about']['introduction']) / 2
 desc_y = pdf.get_y()
 for idx, desc in enumerate(data['about']['introduction']):
     if idx == col_1_count:
         pdf.set_y(desc_y)
     if idx < col_1_count:
         pdf.set_x(page_size['left'] + page_size['section_indent'])
     else:
         pdf.set_x(page_size['middle_x'])
     pdf.ellipse(pdf.get_x(),
                 pdf.get_y() + 1.1, ellipse['size'], ellipse['size'], 'F')
     pdf.cell(ellipse['margin'])
     pdf.cell(1, line_height['text'] - 1, desc, ln=2)
 pdf.ln(page_size['section_margin'])
 # education section
 pdf.set_x(page_size['left'])
 pdf.set_font(title_font, '', font_size['section_title'])
 pdf.cell(1,
          line_height['section'] - 1,
          data['sections']['education'],
          ln=2)
 pdf.set_font(text_font, '', font_size['text'])
 for univ in data['education']['universities']:
     pdf.set_x(page_size['left'] + page_size['section_indent'])
     pdf.set_font_size(font_size['text'] + 1)
示例#31
0
# pyFPDF
# https://pyfpdf.readthedocs.io/en/latest/

from fpdf import FPDF

# FPDF(orientation = 'P', unit = 'mm', format='A4')
pdf = FPDF()
pdf.add_page()
pdf.set_font("Helvetica", "", 12)

#pdf.text(5,10,"Hello, World!")
#length = pdf.get_string_width("Hello, World!    ")
#pdf.text(5,15,"print(Hello, World!)")
pdf.set_xy(20, 100)
#fpdf.cell(w, h = 0, txt = '', border = 0, ln = 0, align = '', fill = False, link = '')
pdf.cell(30, 5, "Hello, World!", border="LTBR", align="C")
pdf.cell(0, 5, "Hola, Mundo!", border="LTBR", align="C", ln=2)
pdf.cell(0, 5, "Olá, Mundo!", border="LTBR", align="C", ln=2)

x, y = pdf.get_x(), pdf.get_y()
print(x, y)
pdf.set_text_color(47, 172, 155)
pdf.text(x, y, "AAAAAAAAAAAA")

pdf.output("output/myfirstpdf.pdf")
示例#32
0
文件: main.py 项目: papalos/elvira
    def createPDF(self, dict_person, stamp, date_doc):

        for faculty in dict_person:

            # формируем список с именами волонтеров
            sort_person_list = [i for i in dict_person[faculty]]
            # сортируем его
            sort_person_list.sort()

            # на основе отсортированного списка формируем новый словарь, с упорядоченным значением имен
            sort_dict = {}
            for name in sort_person_list:
                sort_dict[name] = dict_person[faculty][name]

            pdf = FPDF()
            pdf.add_page()
            pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True)
            pdf.add_font('DejaVu',
                         'B',
                         'DejaVuSansCondensed-Bold.ttf',
                         uni=True)
            pdf.set_font('DejaVu', 'B', 16)
            pdf.cell(0, 10, 'ОЦЕНОЧНАЯ ВЕДОМОСТЬ ПО ПРОЕКТУ', 0, 1, 'C')
            pdf.set_font('DejaVu', '', 12)
            pdf.cell(0, 10, 'Волонтеры: олимпиадный марафон(название проекта)',
                     0, 1, 'C')
            pdf.cell(0, 10, 'Сервисный проект (тип проекта)', 0, 1, 'C')
            pdf.cell(0, 10, 'Январь – май (срок выполнения проекта)', 0, 1,
                     'C')

            # Таблица 1
            pdf.cell(30, 10, '', 0, 0, 'C')
            pdf.multi_cell(65, 7, 'Руководитель проекта:\nФИО \nДолжность\n\n',
                           1, 'L')
            pdf.set_y(pdf.get_y() - 28)
            pdf.set_x(pdf.get_x() + 65 + 30)
            pdf.multi_cell(
                90, 7,
                'Протасевич Тамара Анатольевна \nДиректор по профессиональной ориентации и работе с '
                'одаренными учащимися', 1, 'L')
            pdf.cell(30, 10, '', 0, 0, 'C')
            pdf.multi_cell(65, 7, 'Образовательная программа\n\n\n', 1, 'L')
            # устанавливаем позицию следующей мульти-ячейки
            pdf.set_xy(pdf.get_x() + 65 + 30, pdf.get_y() - 7 * 3)
            # расчет положения последней ячейки
            f = faculty + '\n\n' if 40 <= len(
                faculty) < 80 else faculty + '\n\n\n' if len(
                    faculty) < 40 else faculty
            pdf.multi_cell(90, 7, f, 1, 'L')

            pdf.ln(20)

            # Таблица 2 заголовки
            w_cell1 = 90
            w_cell2 = 40
            w_cell3 = 30
            w_cell4 = 30
            h_cell = 5 * 3
            pdf.set_font('DejaVu', 'B', 12)
            pdf.multi_cell(w_cell1, 5, '\nФИО\n\n', 1, 'C')
            pdf.set_xy(pdf.get_x() + w_cell1, pdf.get_y() - h_cell)
            pdf.multi_cell(w_cell2, 5, '\nКурс\n\n', 1, 'C')
            pdf.set_xy(pdf.get_x() + w_cell1 + w_cell2, pdf.get_y() - h_cell)
            pdf.multi_cell(w_cell3, 5, 'Оценка по 10-балльной шкале', 1, 'C')
            pdf.set_xy(pdf.get_x() + w_cell1 + w_cell2 + w_cell3,
                       pdf.get_y() - h_cell)
            pdf.multi_cell(w_cell4, 5, 'Количество ЗЕ за проект', 1, 'C')

            # Таблица 2 тело
            pdf.set_font('DejaVu', '', 12)

            # добавляем строки таблице и заполняем содержимым переданного словарая с волонтерами
            for person in sort_dict:

                pdf.cell(90, 5, person, 1, 0, 'L')
                pdf.cell(40, 5, sort_dict[person][1], 1, 0, 'C')
                pdf.cell(30, 5, '10', 1, 0, 'C')
                grade = sort_dict[person][0]
                if grade < 3:
                    value = '1'
                elif grade == 3:
                    value = '2'
                else:
                    value = '3'
                pdf.cell(30, 5, value, 1, 1, 'C')

            pdf.ln(5)

            # Вставляем дату
            pdf.cell(100, 5, f'Дата заполнения: {date_doc}', 0, 0, 'L')
            pdf.cell(90, 5, 'Протасевич Т.А.', 0, 1, 'R')

            if stamp:
                pdf.image('123.png', x=120, w=73, h=40.5)

            # путь сохранения файла
            path_save = faculty.replace('"', '').replace(':', '')
            a = f'{self._dirForSave}/{path_save}.pdf'
            # # сохраняем созданный документ
            pdf.output(a)