Dzień dobry,
Jeden z praktykantów miał za zadanie stworzyć raport błędów generujący listę obiektów QGIS w tablicy.
Zrobił to i na jego komputerze wychodziło bardzo dobrze.
Teraz mam z zadanie wrzucić go do głównego projektu.
Kod wygląda tak:
class PDF(FPDF): # stopka z numerem strony
def footer(self):
self.set_y(-15)
self.cell(0, 10, f'Strona {self.page_no()}', 0, 0, 'C')
def create_pdf(filename):
czas = time.strftime("%Y-%m-%d %H:%M")
pdf = PDF()
walidator_sciezka = os.path.dirname(os.path.realpath(__file__))
pdf.add_page()
pdf.alias_nb_pages()
pdf.set_margins(10,10,10)
pdf.add_font('Verdana', '', walidator_sciezka + "/fpdf\Verdana.ttf", uni = True)
pdf.add_font("Verdana", "B", walidator_sciezka + "/fpdf\Verdana-bold.ttf", uni = True)
pdf.set_font('Verdana', 'B',14)
pdf.cell(0,5,ln = 1)
pdf.cell(0,0, "Raport z kontroli", align='C',ln=2)
pdf.set_font("Verdana", "", 8)
pdf.cell(0,5,ln = 1)
pdf.cell(100,0, "wynik kontroli:", align = "R", ln = 0)
print ('ustalony font i komórki')
if len(bledyKontroli["KLASA"]) == 0:
wynikkontroli = "Pozytywny"
pdf.set_text_color(0,255,0)
else:
wynikkontroli = "Negatywny"
pdf.set_text_color(255,0,0)
lightblue = (143, 216, 255)
gray = (220,220,220)
pdf.cell(100,0,wynikkontroli, align = "L")
pdf.cell(0,5,ln = 1)
pdf.set_text_color(0,0,0)
pdf.cell(100,0, "wynik walidacji:", align = "R", ln = 0)
print ('ustalony font i komórki 2')
if len(bledyWalidacji["WIERSZ"]) == 0:
wynikw = "Pozytywny"
pdf.set_text_color(0,255,0)
else:
wynikw = "Negatywny"
pdf.set_text_color(255,0,0)
pdf.cell(100,0,wynikw, align = "L")
pdf.cell(0,5, ln = 1) # wolne miejsce
pdf.set_text_color(0,0,0)
pdf.cell(100,0,"data kontroli:", ln=0, align = "R") # tekst
pdf.cell(100,0, czas , ln = 1, align = "L")
pdf.cell(0,1,ln = 1)
print ("ustawienie komórek")
with pdf.table(first_row_as_headings = False, col_widths = (105,95), borders_layout = "NONE", v_align = "TOP") as tabelaskp:
rzad = tabelaskp.row()
rzad.cell("szablon kontroli:", align = "R", padding=(1,1,1,1))
rzad.cell("skp", align = "J", padding = (1,40,1,1))
pdf.cell(0,1,ln=1)
# tabela walidacji
if len(bledyWalidacji["WIERSZ"]) > 0:
pdf.set_font("Verdana", "B", 14)
pdf.cell(0,0,"Tabela z błędami walidacji", align = "C")
pdf.set_font("Verdana", "", 8)
pdf.cell(0,5,ln = 1)
pdf.set_fill_color(lightblue)
with pdf.table(col_widths=(40,12,40,88), text_align = "J",padding = (1)) as table:
pdf.set_font("Verdana", "", 5)
headings = table.row()
headings.cell("WALIDOWANY PLIK")
headings.cell("WIERSZ")
headings.cell("OPIS BŁĘDU")
headings.cell("KOMUNIKAT BŁĘDU")
pdf.set_fill_color(gray)
with pdf.table(datawalidacja, col_widths=(40,12,40,88), first_row_as_headings = False, text_align = "J", padding = (1)):
pass
pdf.set_fill_color(255,255,255)
pdf.set_font("Verdana", "" , 6)
else: # jak nie ma błędów walidacji
pdf.set_font("Verdana", "", 14)
pdf.cell(0,0, "Nie znaleziono błędów walidacji", align = "C")
pdf.cell(w=0,h=10,txt = " ",ln=1)
# tabela konotroli
if len(bledyKontroli["KLASA"]) > 0:
pdf.set_font("Verdana", "B", 14)
pdf.cell(0,0,"Tabela z błędami kontroli", align="C")
pdf.set_font("Verdana", "", 5)
pdf.cell(0,5,ln = 1)
pdf.set_fill_color(lightblue)
with pdf.table(col_widths=(40,20,50,70), text_align = "J", padding = (1)) as table1:
headings = table1.row()
headings.cell("KONTROLOWANY PLIK")
headings.cell("KLASA")
headings.cell("LOKALNY ID")
headings.cell("KOMUNIKAT BŁĘDU")
pdf.set_fill_color(gray)
with pdf.table(datakontrola, col_widths=(40,20,50,70), first_row_as_headings = False, text_align="J", padding = (1)):
pass
else:
pdf.set_font("Verdana", "B", 14)
pdf.cell(0,0,"Nie znaleziono błędów kontroli", align = "C")
pdf.set_font("Verdana", "", 5)
pdf.output(filename)
create_pdf(pdfpath)
jednakże w ostatniej linijce wyskakuje mi błąd odnoszący się do... jednego z wewnętrznych plików biblioteki fpdf.
Pełny błąd jest taki:
File "[pelna sciezka]", line 473, in walidacjaIKontrolaAtrybutow -> nazwa głównego pliku
create_pdf(pdfpath)
File "[pelna sciezka]\walidatorPlikowGML.py", line 472, in create_pdf
pdf.output(filename)
File "[pelna sciezka]\Walidator_plikow_gml\fpdf\fpdf.py", line 5014, in output
self.buffer = output_producer.bufferize()
File "[pelna sciezka]\Walidator_plikow_gml\fpdf\output.py", line 380, in bufferize
font_objs_per_index = self._add_fonts()
File "[pelna sciezka]\Walidator_plikow_gml\fpdf\output.py", line 549, in _add_fonts
print(f"Font name for TTF: {font.name}")
AttributeError: name
TTF pochodzi z linii: pdf.add_font('Verdana', '', walidator_sciezka + "/fpdf\Verdana.ttf", uni = True)
jest to oddzielny plik przechowujący czcionkę Verdana ( walidator_sciezka to zmienna przechowująca ścieżkę do folderu). Jak sprawdziłem, printami że atrybut name jest możliwy dla zmiennej font w pliku output.py (kod podam na końcu), ale się nie uzupełnia.
... i w ogóle czy warto zmieniać/wchodzić w głąb biblioteki fpdf, zamiast obejść dookoła?
Składania output.py jest taka:
def _add_fonts(self):
font_objs_per_index = {}
for font in sorted(self.fpdf.fonts.values(), key=lambda font: font.i):
# Standard font
print("Dostępne atrybuty dla font:", dir(font), 'wartosci',self.fpdf.fonts.values(),'fonty' ,self.fpdf.fonts) # dir wykazał że metoda .name jest możliwa,m zaś kolejne dwie wartości wyglądają tak: wartosci dict_values([TTFFont(i=1, fontkey=verdana), TTFFont(i=2, fontkey=verdanaB)]) fonty {'verdana': TTFFont(i=1, fontkey=verdana), 'verdanaB': TTFFont(i=2, fontkey=verdanaB)}
if font.type == "core":
encoding = (
"WinAnsiEncoding"
if font.name not in ("Symbol", "ZapfDingbats")
else None
)
core_font_obj = PDFFont(
subtype="Type1", base_font=font.name, encoding=encoding
)
self._add_pdf_obj(core_font_obj, "fonts")
font_objs_per_index[font.i] = core_font_obj
elif font.type == "TTF":
fontname = f"MPDFAA+{font.name}"
Oczywiście trzeba znać fpdf, aby znaleźć źródło problemów.
Z góry dziękuje za każdą pomoc!