def make_pdf(number, ctype): BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) main_img = os.path.join(BASE_DIR, 'content', 'cover.png') pdf = FPDF() pdf.add_page('P') pdf.set_font("Arial", size=15) pdf.cell(10, 10, txt=number, ln=1, align="C") if ctype == 1: pdf.rotate(-90.1) imwrite(main_img, warpImage(imread(main_img), cover_type=0)) pdf.image(main_img, 100, -165, 78, 85) pdf.image(os.path.join(BASE_DIR, 'content', 'template', 'big.png'), 9, -172, 258, 110.3) pdf.output(os.path.join(BASE_DIR, 'content', 'big.pdf')) os.remove(main_img) elif ctype == 0: pdf.rotate(-89.75) imwrite(main_img, warpImage(imread(main_img), cover_type=1)) pdf.image(main_img, 103, -71, 74, 60) pdf.image(os.path.join(BASE_DIR, 'content', 'template', 'small.png'), 17.5, -74, 240, 84) pdf.output(os.path.join(BASE_DIR, 'content', 'small.pdf')) os.remove(main_img)
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())
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())
def get(self, data = None): out_type = self.get_argument('type', 'html') components = [] components = self.get_query_arguments('action[]', []) multiply = int(self.get_argument('multiply', 5)) layout = self.get_argument('template', '70x40_simple') skip = int(self.get_argument('skip', 0)) #print("Soucastky..",components) if len(components) > 0: comp = list(self.mdb.stock.find({'_id' : {'$in' : components}})) else: comp = list(self.mdb.stock.find().sort([("category", 1), ("_id",1)])) page = 0 #print("Budeme tisknout:", comp) if layout == 'souhrn_01': autori = self.get_query_argument('autor', None) if not autori: autori = ['autory vlozite pridanim autoru do adresy s parametrem "autor"', 'autoru muze byt vice, pouzijte vice parametru', 'Například pridanim tohoto na konec adresy: &autor=Tester První'] datum = self.get_argument('datum', ">>pro specifikovani pridejte parametr 'datum' do GET parametru<<") page = 1 money_sum = 0 Err = [] print ("pozadovany format je:", layout) pdf = FPDF('P', 'mm', format='A4') pdf.set_auto_page_break(False) pdf.add_font('pt_sans', '', 'static/pt_sans/PT_Sans-Web-Regular.ttf', uni=True) pdf.add_font('pt_sans-bold', '', 'static/pt_sans/PT_Sans-Web-Bold.ttf', uni=True) pdf.set_font('pt_sans', '', 12) pdf.add_page() pdf.set_xy(0, 40) pdf.cell(pdf.w, 0, 'Celkový přehled skladu', align='C', ln=2) pdf.set_xy(0, 46) pdf.cell(pdf.w, 0, 'Universal Scientific Technologies s.r.o.', align='C', ln=2) pdf.set_xy(20, 200) pdf.cell(1,0, 'Inventuru provedli:', ln=2) for x in autori: pdf.cell(1,20, x, ln=2) pdf.set_font('pt_sans', '', 8) pdf.set_xy(120, 288) pdf.cell(10, 0, "Generováno %s, strana %s z %s" %(datetime.datetime.now(), page, pdf.alias_nb_pages()) ) pdf.add_page() data = self.mdb.stock.aggregate([ {'$addFields': {'count': {'$sum': '$history.bilance'}}} ]) gen_time = datetime.datetime(2018, 10, 1) lastOid = ObjectId.from_datetime(gen_time) for i, component in enumerate(data): #for i, component in enumerate(list(data)[:30]): print(i, "=============================") print(component['_id']) try: ## Pokud je konec stránky if pdf.get_y() > pdf.h-20: pdf.line(10, pdf.get_y()+0.5, pdf.w-10, pdf.get_y()+0.5) pdf.set_font('pt_sans', '', 10) pdf.set_xy(150, pdf.get_y()+1) pdf.cell(100, 5, 'Součet strany: {:6.2f} Kč'.format(page_sum)) pdf.add_page() ## Pokud je nová strana if page != pdf.page_no(): pdf.set_font('pt_sans', '', 8) page = pdf.page_no() pdf.set_xy(120, 288) pdf.cell(10, 0, "Generováno %s, strana %s z %s" %(datetime.datetime.now(), page, pdf.alias_nb_pages()) ) pdf.set_font('pt_sans', '', 11) pdf.set_xy(10, 10) pdf.cell(100, 5, 'Skladová položka') pdf.set_x(95) pdf.cell(10, 5, "Počet kusů", align='R') pdf.set_x(120) pdf.cell(10, 5, "Cena za 1ks", align='R') pdf.set_x(180) pdf.cell(10, 5, "Cena položky (bez DPH)", align='R', ln=2) pdf.line(10, 15, pdf.w-10, 15) pdf.set_y(18) page_sum = 0 pdf.set_font('pt_sans', '', 10) count = component['count'] if count >0: price = 0 price_ks = 0 first_price = 0 pdf.set_x(10) pdf.cell(100, 5, component['_id']) pdf.set_x(95) pdf.cell(10, 5, "%5.d" %(count), align='R') pdf.set_x(10) pdf.cell(100, 5, "{:5.0f} {}".format(i, component['_id'])) inventura = False for x in reversed(component.get('history', [])): if x.get('operation', None) == 'inventory': print("inventura", x) if x['_id'].generation_time > lastOid.generation_time: print("#############") inventura = True count = x['absolute'] pdf.set_x(110) pdf.cell(1, 5, "i") break; pdf.set_font('pt_sans', '', 10) pdf.set_x(95) pdf.cell(10, 5, "{} j".format(count), align='R') rest = count for x in reversed(component.get('history', [])): if x.get('price', 0) > 0: if first_price == 0: first_price = x['price'] if x['bilance'] > 0: if x['bilance'] <= rest: price += x['price']*x['bilance'] rest -= x['bilance'] else: price += x['price']*rest rest = 0 print("Zbývá", rest, "ks, secteno", count-rest, "za cenu", price) if(count-rest): price += rest*first_price money_sum += price page_sum +=price if price == 0.0 and x.get('count', 0) > 0: Err.append('Polozka >%s< nulová cena, nenulový počet' %(component['_id'])) pdf.set_x(120) if count > 0: pdf.cell(10, 5, "%6.2f Kč" %(price/count), align='R') else: pdf.cell(10, 5, "%6.2f Kč" %(0), align='R') pdf.set_font('pt_sans-bold', '', 10) pdf.set_x(180) pdf.cell(10, 5, "%6.2f Kč" %(price), align='R') except Exception as e: Err.append('Err' + repr(e) + component['_id']) print(e) pdf.set_y(pdf.get_y()+4) pdf.line(10, pdf.get_y(), pdf.w-10, pdf.get_y()) pdf.set_font('pt_sans', '', 8) pdf.set_x(180) pdf.cell(10, 5, "Konec souhrnu", align='R') pdf.set_font('pt_sans', '', 10) pdf.set_xy(150, pdf.get_y()+3) pdf.cell(100, 5, 'Součet strany: {:6.2f} Kč'.format(page_sum)) pdf.page = 1 pdf.set_xy(20,175) pdf.set_font('pt_sans', '', 12) pdf.cell(20,20, "Cena skladových zásob k %s je %0.2f Kč (bez DPH)" %(datum, money_sum)) if len(Err) > 0: pdf.set_xy(30,80) pdf.cell(1,6,"Pozor, chyby ve skladu:", ln=2) pdf.set_x(32) for ch in Err: pdf.cell(1,5,ch,ln=2) pdf.page = page print(autori) if layout == '105x74_simple': page = 0 page_cols = 2 page_rows = 4 page_cells = page_cols * page_rows cell_w = 105 cell_h = 75 print ("pozadovany format je:", layout) pdf = FPDF('P', 'mm', format='A4') pdf.add_font('pt_sans', '', 'static/pt_sans/PT_Sans-Web-Regular.ttf', uni=True) pdf.add_font('pt_sans-bold', '', 'static/pt_sans/PT_Sans-Web-Bold.ttf', uni=True) pdf.set_font('pt_sans-bold', '', 12) pdf.set_auto_page_break(False) pdf.add_page() for i, component in enumerate(comp): i += skip id = component['_id'].strip().replace('/', '') code128.image(component['_id']).save("static/barcode/%s.png"%(id)) if i != 0 and i%(page_cells) == 0: page += 1 pdf.add_page() print("New PAGE --- ", i, i%page_cells) row = int(i/page_cols)-page*page_rows column = i%page_cols cell_x = column*cell_w cell_y = row*cell_h print(component) pdf.set_font('pt_sans-bold', '', 14) pdf.set_xy(cell_x+5, cell_y+5) pdf.cell(cell_w-10, 0, component['_id']) pdf.set_xy(cell_x, cell_y+10) pdf.image('static/barcode/%s.png'%(id), w = cell_w, h=10) pdf.set_font('pt_sans', '', 11) pdf.set_xy(cell_x+5, cell_y+23) try: pdf.multi_cell(cell_w-10, 5, component['description']) except Exception as e: pdf.multi_cell(cell_w-10, 5, "ERR" + repr(e)) pdf.set_xy(cell_x+5, cell_y+cell_h-15) pdf.set_font('pt_sans', '', 8) pdf.cell(cell_w-10, 10, ', '.join(component['category']) + " | " + str(datetime.datetime.now()) + " | " + "UST") if layout == '70x42-3_simple': page = 0 page_cols = 3 page_rows = 7 page_cells = page_cols * page_rows cell_w = 210/page_cols cell_h = 297/page_rows print ("pozadovany format je:", layout) pdf = FPDF('P', 'mm', format='A4') pdf.add_font('pt_sans', '', 'static/pt_sans/PT_Sans-Web-Regular.ttf', uni=True) pdf.add_font('pt_sans-bold', '', 'static/pt_sans/PT_Sans-Web-Bold.ttf', uni=True) pdf.set_font('pt_sans-bold', '', 12) pdf.set_auto_page_break(False) pdf.add_page() for i, component in enumerate(comp): i += skip id = component['name'].strip().replace('/', '_') code128.image(component['_id']).save("static/barcode/%s.png"%(id)) if i != 0 and i%(page_cells) == 0: page += 1 pdf.add_page() print("New PAGE --- ", i, i%page_cells) row = int(i/page_cols)-page*page_rows column = i%page_cols cell_x = column*cell_w cell_y = row*cell_h pdf.set_xy(cell_x+5, cell_y+6.75) if len(component['name'])<23: pdf.set_font('pt_sans-bold', '', 14) else: pdf.set_font('pt_sans-bold', '', 10) pdf.cell(cell_w-10, 0, component['name'][:35]) pdf.set_xy(cell_x+2.5, cell_y+9) pdf.image('static/barcode/%s.png'%(id), w = cell_w-5, h=7) pdf.set_font('pt_sans', '', 11) pdf.set_xy(cell_x+4, cell_y+20) try: pdf.multi_cell(cell_w-8, 4, component['description'][:185]) except Exception as e: pdf.multi_cell(cell_w-10, 5, "ERR" + repr(e)) pdf.set_xy(cell_x+5, cell_y+cell_h-7) pdf.set_xy(cell_x+5, cell_y+13) pdf.set_font('pt_sans', '', 7.5) pdf.cell(cell_w-10, 10, ', '.join(component['category']) + " |" + str(datetime.date.today()) + "| " + component['_id']) if layout == '105x48_simple': page = 0 page_cols = 2 page_rows = 6 page_cells = page_cols * page_rows #cell_w = 105 #cell_h = 48 cell_w = 210/page_cols cell_h = 297/page_rows print ("pozadovany format je:", layout) pdf = FPDF('P', 'mm', format='A4') pdf.add_font('pt_sans', '', 'static/pt_sans/PT_Sans-Web-Regular.ttf', uni=True) pdf.add_font('pt_sans-bold', '', 'static/pt_sans/PT_Sans-Web-Bold.ttf', uni=True) pdf.set_font('pt_sans-bold', '', 12) pdf.set_auto_page_break(False) pdf.add_page() for i, component in enumerate(comp): i += skip id = component['_id'].strip().replace('/', '') code128.image(component['_id']).save("static/barcode/%s.png"%(id)) if i != 0 and i%(page_cells) == 0: page += 1 pdf.add_page() print("New PAGE --- ", i, i%page_cells) row = int(i/page_cols)-page*page_rows column = i%page_cols cell_x = column*cell_w cell_y = row*cell_h print(component) pdf.set_font('pt_sans-bold', '', 14) pdf.set_xy(cell_x+5, cell_y+5) pdf.cell(cell_w-10, 0, component['_id']) pdf.set_xy(cell_x, cell_y+10) pdf.image('static/barcode/%s.png'%(id), w = cell_w, h=10) pdf.set_font('pt_sans', '', 10) pdf.set_xy(cell_x+5, cell_y+20) try: pdf.multi_cell(cell_w-10, 4, component['description'][:275]) except Exception as e: pdf.multi_cell(cell_w-10, 4, "ERR" + repr(e)) pdf.set_xy(cell_x+5, cell_y+cell_h-10) pdf.set_font('pt_sans', '', 8) pdf.cell(cell_w-10, 10, ', '.join(component['category']) + " | " + str(datetime.datetime.now()) + " | " + "UST") elif layout == '105x48_panorama': page = 0 page_cols = 6 page_rows = 2 page_cells = page_cols * page_rows cell_w = 48 cell_h = 105 print ("pozadovany format je:", layout) pdf = FPDF('L', 'mm', format='A4') pdf.add_font('pt_sans', '', 'static/pt_sans/PT_Sans-Web-Regular.ttf', uni=True) pdf.add_font('pt_sans-bold', '', 'static/pt_sans/PT_Sans-Web-Bold.ttf', uni=True) pdf.set_font('pt_sans-bold', '', 12) pdf.set_auto_page_break(False) pdf.add_page() for i, component in enumerate(comp): i += skip id = component['_id'].strip().replace('/', '') code128.image(component['_id']).save("static/barcode/%s.png"%(id)) if i != 0 and i%(page_cells) == 0: page += 1 pdf.add_page() print("New PAGE --- ", i, i%page_cells) row = int(i/page_cols)-page*page_rows column = i%page_cols cell_x = column*cell_w cell_y = row*cell_h print(component) pdf.set_font('pt_sans-bold', '', 14) pdf.set_xy(cell_x+5, cell_y+5) pdf.cell(cell_w-10, 0, component['_id']) pdf.set_xy(cell_x, cell_y+cell_h) pdf.rotate(90) pdf.image('static/barcode/%s.png'%(id), w = cell_h-5, h=10) pdf.rotate(0) pdf.set_font('pt_sans', '', 11) pdf.set_xy(cell_x+8, cell_y+20) try: pdf.multi_cell(cell_w-10, 5, component['description']) except Exception as e: pdf.multi_cell(cell_w-10, 5, "ERR" + repr(e)) pdf.set_xy(cell_x+5, cell_y+cell_h-15) pdf.set_font('pt_sans', '', 8) pdf.cell(cell_w-10, 10, ', '.join(component['category']) + " | " + str(datetime.datetime.now()) + " | " + "UST") pdf.output("static/tmp/sestava.pdf") with open('static/tmp/sestava.pdf', 'rb') as f: self.set_header("Content-Type", 'application/pdf; charset="utf-8"') self.set_header("Content-Disposition", "inline; filename=UST_tiskova_sestava.pdf") self.write(f.read()) f.close()
class MakePDF(FPDF): def __init__(self, result_dict: dict, filename: str): super().__init__() # try: self._result = SelectIndividual(result_dict) self._result_dict = self._result.get_result_dict() self.annotation = "Даний підбір виконано автоматично. Для підтвердження підбору зверніться у проектну організацію" self.title1 = "З/б балка Б-1. Опалубне креслення" self.title2 = "З/б балка Б-1. Армування" self.title3 = "Специфікація" if int(self._result_dict["Б-1"][2]) < 2500 and int(self._result_dict["Б-1"][3]) < 400: self.scale = 10 else: self.scale = 20 self.count_of_lines = 11 self.form3 = FPDF(orientation="L", unit="mm", format="A3") self.form3.add_page() self.form3.add_font("iso", "", "static/ISOCPEUR/ISOCPEUR.ttf", uni=True) self._draw_form_3() self._draw_specification(self._result_dict, 20, 184, self.title3) self._make() self.form3.output(f"static/{filename}") # except: # self.make_error() # def _initial_scale_dimension(self): # self.scale = 10 # self.l = (int(self._result_dict["Б-1"][2]) + 500) / self.scale # self.h = int(self._result_dict["Б-1"][3]) / self.scale # self.b = int(self._result_dict["Б-1"][4]) / self.scale # diam_pos1 = self._result_dict["1"][1] / self.scale # diam_pos2 = self._result_dict["2"][1] / self.scale # diam_pos3 = self._result_dict["3"][1] / self.scale # diam_pos4 = self._result_dict["4"][1] / self.scale # self.a = diam_pos1 / 2 + 20 / self.scale def make_error(self): return "Помилка! З даними параметрами неможливо виконати розрахунок. Збільшіть висоту перерізу." def _make(self): self._draw_beam(36, 30) self._draw_rainforcment(36, 110) def _draw_beam(self, x, y): x0 = x y0 = y l = (int(self._result_dict["Б-1"][2]) + 500) / self.scale h = int(self._result_dict["Б-1"][3]) / self.scale b = int(self._result_dict["Б-1"][4]) / self.scale self.form3.set_font("iso", "", 14) self.form3.text(x0 + l / 2.5, y0 - 5, self.title1) self.form3.set_line_width(0.5) self.form3.rect(x0, y0, l, h) self._dim_h(x0, y0 + h, l) self._dim_v(x0, y0, h) if l > 250: self.form3.rect(x0 + l + 16, y0, b, h) self._dim_h(x0 + l + 16, y0 + h, b) else: self.form3.rect(x0 + l + 30, y0, b, h) self._dim_h(x0 + l + 30, y0 + h, b) def _draw_rainforcment(self, x, y): x0 = x y0 = y l = (int(self._result_dict["Б-1"][2]) + 500) / self.scale h = int(self._result_dict["Б-1"][3]) / self.scale b = int(self._result_dict["Б-1"][4]) / self.scale self.form3.set_font("iso", "", 14) self.form3.text(x0 + l / 2.35, y0 - 5, self.title2) diam_pos1 = self._result_dict["1"][1] / self.scale diam_pos2 = self._result_dict["2"][1] / self.scale diam_pos3 = self._result_dict["3"][1] / self.scale diam_pos4 = self._result_dict["4"][1] / self.scale a = diam_pos1 / 2 + 20 / self.scale self.form3.set_line_width(0.05) self.form3.rect(x0, y0, l, h) pos1_l = int(self._result_dict["1"][3] / self.scale * 1000) pos2_l = int(self._result_dict["2"][3] / self.scale * 1000) self.form3.set_line_width(0.5) self.form3.line(x0 + 30 / self.scale, y0 + h - a, x0 + 30 / self.scale + pos1_l, y0 + h - 30 / self.scale) self.form3.line(x0 + 30 / self.scale, y0 + a, x0 + 30 / self.scale + pos2_l, y0 + 30 / self.scale) pos3_data = self._result.get_distance_position_3_4() def draw_pos3(x, y): self.form3.line( x, y + a - diam_pos2 / 2 - diam_pos3 / 2, x, y + h - a + diam_pos2 / 2 + diam_pos3 / 2, ) draw_pos3(x0 + (30 + 50) / self.scale, y0) draw_pos3(x0 + (30 + 50) / self.scale + pos3_data[1] * 1000 / self.scale, y0) draw_pos3(x0 + l - (30 + 50) / self.scale - pos3_data[1] * 1000 / self.scale, y0) draw_pos3(x0 + l - (30 + 50) / self.scale, y0) mid_dist_temp = round((pos2_l * self.scale - (50 + pos3_data[1] * 1000) * 2 - pos3_data[3] * 1000) / 2) mid_dist = mid_dist_temp / self.scale draw_pos3(x0 + 30 / self.scale + (50 + pos3_data[1] * 1000) / self.scale + mid_dist, y0) draw_pos3(x0 + 30 / self.scale + (50 + pos3_data[1] * 1000 + pos3_data[3] * 1000) / self.scale + mid_dist, y0) s = (b - 2 * a) / (self._result_dict["1"][0] - 1) if l > 250: self.form3.set_line_width(0.05) self.form3.rect(x0 + l + 16, y0, b, h) self.form3.set_line_width(0.5) self.form3.line( x0 + l + 16 + a - (diam_pos3 + diam_pos1) / 2, y0 + 10 / self.scale, x0 + l + 16 + a - (diam_pos3 + diam_pos1) / 2, y0 + h - 10 / self.scale ) self.form3.line( x0 + l + 16 + b - a + (diam_pos3 + diam_pos1) / 2, y0 + 10 / self.scale, x0 + l + 16 + b - a + (diam_pos3 + diam_pos1) / 2, y0 + h - 10 / self.scale ) self.form3.line( x0 + l + 16 + 10 / self.scale, y0 + a - (diam_pos3 + diam_pos2) / 2, x0 + l + 16 + b - 10 / self.scale, y0 + a - (diam_pos3 + diam_pos2) / 2 ) self.form3.line( x0 + l + 16 + 10 / self.scale, y0 + h - a + (diam_pos3 + diam_pos1) / 2, x0 + l + 16 + b - 10 / self.scale, y0 + h - a + (diam_pos3 + diam_pos1) / 2 ) self.form3.set_line_width(0.05) self.form3.ellipse(x0 + l + 16 + a - diam_pos1 / 2, y0 + a - diam_pos2 / 2, diam_pos2, diam_pos2, "FD") self.form3.ellipse(x0 + l + 16 - a + diam_pos1 / 2 + b - diam_pos2, y0 + a - diam_pos2 / 2, diam_pos2, diam_pos2, "FD") for i in range(self._result_dict["1"][0]): self.form3.ellipse(x0 + l + 16 + a - diam_pos1 / 2 + s * i, y0 + h - a - diam_pos1 / 2, diam_pos1, diam_pos1, "FD") else: self.form3.set_line_width(0.05) self.form3.rect(x0 + l + 30, y0, b, h) self.form3.set_line_width(0.5) self.form3.line( x0 + l + 30 + a - (diam_pos3 + diam_pos1) / 2, y0 + 10 / self.scale, x0 + l + 30 + a - (diam_pos3 + diam_pos1) / 2, y0 + h - 10 / self.scale ) self.form3.line( x0 + l + 30 + b - a + (diam_pos3 + diam_pos1) / 2, y0 + 10 / self.scale, x0 + l + 30 + b - a + (diam_pos3 + diam_pos1) / 2, y0 + h - 10 / self.scale ) self.form3.line( x0 + l + 30 + 10 / self.scale, y0 + a - (diam_pos3 + diam_pos2) / 2, x0 + l + 30 + b - 10 / self.scale, y0 + a - (diam_pos3 + diam_pos2) / 2 ) self.form3.line( x0 + l + 30 + 10 / self.scale, y0 + h - a + (diam_pos3 + diam_pos1) / 2, x0 + l + 30 + b - 10 / self.scale, y0 + h - a + (diam_pos3 + diam_pos1) / 2 ) self.form3.set_line_width(0.05) self.form3.ellipse(x0 + l + 30 + a - diam_pos1 / 2, y0 + a - diam_pos2 / 2, diam_pos2, diam_pos2, "FD") self.form3.ellipse(x0 + l + 30 - a + diam_pos1 / 2 + b - diam_pos2, y0 + a - diam_pos2 / 2, diam_pos2, diam_pos2, "FD") for i in range(self._result_dict["1"][0]): self.form3.ellipse(x0 + l + 30 + a - diam_pos1 / 2 + s * i, y0 + h - a - diam_pos1 / 2, diam_pos1, diam_pos1, "FD") self._dim_h(x0, y0 + h, 30 / self.scale, -3.5) self._dim_h(x0 + 30 / self.scale, y0 + h, 50 / self.scale, 5) self._dim_h( x0 + 30 / self.scale + 50 / self.scale, y0 + h, pos3_data[1] * 1000 / self.scale, -5, f"{pos3_data[0] - 1}x100={(pos3_data[0] - 1) * 100}" ) self._dim_h( x0 + 30 / self.scale + 50 / self.scale + pos3_data[1] * 1000 / self.scale, y0 + h, mid_dist ) self._dim_h( x0 + 30 / self.scale + 50 / self.scale + pos3_data[1] * 1000 / self.scale + mid_dist, y0 + h, pos3_data[3] * 1000 / self.scale, -5, f"{pos3_data[2] - 1}x200={(pos3_data[2] - 1) * 200}" ) self._dim_h( x0 + 30 / self.scale + 50 / self.scale + pos3_data[1] * 1000 / self.scale + mid_dist + pos3_data[3] * 1000 / self.scale, y0 + h, mid_dist ) self._dim_h( x0 + 30 / self.scale + 50 / self.scale + pos3_data[1] * 1000 / self.scale + 2 * mid_dist + pos3_data[3] * 1000 / self.scale, y0 + h, pos3_data[1] * 1000 / self.scale, -5, f"{pos3_data[0] - 1}x100={(pos3_data[0] - 1) * 100}" ) self._dim_h( x0 + 30 / self.scale + 50 / self.scale + 2 * pos3_data[1] * 1000 / self.scale + 2 * mid_dist + pos3_data[3] * 1000 / self.scale, y0 + h, 50 / self.scale, -4.5 ) self._dim_h( x0 + 30 / self.scale + 2 * 50 / self.scale + 2 * pos3_data[1] * 1000 / self.scale + 2 * mid_dist + pos3_data[3] * 1000 / self.scale, y0 + h, 30 / self.scale, 4 ) self._dim_v(x0, y0, a, 3) self._dim_v(x0, y0 + a, h - 2 * a) self._dim_v(x0, y0 - a + h, a, -3) if l > 250: self._dim_h(x0 + l + 16, y0 + h, a, -3) if self._result_dict['1'][0] > 2: self._dim_h( x0 + l + 16 + a, y0 + h, b - 2 * a, -1, f" " ) self.form3.set_line_width(0.05) self.form3.line(x0 + l + 16 + b / 2, y0 + h + 8, x0 + l + 16 + b / 2, y0 + h + 13) self.form3.line(x0 + l + 16 + b / 2, y0 + h + 13, x0 + l + 16 + b / 2 + 15, y0 + h + 13) self.form3.text( x0 + l + 16 + b / 2 + 1, y0 + h + 12.5, f"{self._result_dict['1'][0] - 1}x" f"{int(round((b - 2 * a) * self.scale / (self._result_dict['1'][0] - 1), 0))}=" f"{int(round((b - 2 * a) * self.scale, 0))}") else: self._dim_h( x0 + l + 16 + a, y0 + h, b - 2 * a, -1, f"{int(round((b - 2 * a) * self.scale / (self._result_dict['1'][0] - 1), 0))}" ) self._dim_h(x0 + l + 16 - a + b, y0 + h, a, 3.5) self._dim_v(x0 + l + 16, y0, a, 3) self._dim_v(x0 + l + 16, y0 + a, h - 2 * a) self._dim_v(x0 + l + 16, y0 - a + h, a, -3) else: self._dim_h(x0 + l + 30, y0 + h, a, -3) if self._result_dict['1'][0] > 2: self._dim_h( x0 + l + 30 + a, y0 + h, b - 2 * a, -1, " " #f"{self._result_dict['1'][0] - 1}x{int(round((b - 2 * a) * self.scale / (self._result_dict['1'][0] - 1), 0))}" ) self.form3.set_line_width(0.05) self.form3.line(x0 + l + 30 + b / 2, y0 + h + 8, x0 + l + 30 + b / 2, y0 + h + 13) self.form3.line(x0 + l + 30 + b / 2, y0 + h + 13, x0 + l + 30 + b / 2 + 15, y0 + h + 13) self.form3.text( x0 + l + 30 + b / 2 + 1, y0 + h + 12.5, f"{self._result_dict['1'][0] - 1}x" f"{int(round((b - 2 * a) * self.scale / (self._result_dict['1'][0] - 1), 0))}=" f"{int(round((b - 2 * a) * self.scale, 0))}") else: self._dim_h( x0 + l + 30 + a, y0 + h, b - 2 * a, 0, f"{int(round((b - 2 * a) * self.scale / (self._result_dict['1'][0] - 1), 0))}" ) self._dim_h(x0 + l + 30 - a + b, y0 + h, a, 3.5) self._dim_v(x0 + l + 30, y0, a, 3) self._dim_v(x0 + l + 30, y0 + a, h - 2 * a) self._dim_v(x0 + l + 30, y0 - a + h, a, -3) self.form3.set_line_width(0.05) self.form3.set_font("iso", "", 11) self.form3.line(x0 + l / 2 + 5, y0 + a, x0 + l / 2 + 5, y0 + a + 5) self.form3.line(x0 + l / 2 + 5, y0 + a + 5, x0 + l / 2 + 8, y0 + a + 5) self.form3.text(x0 + l / 2 + 6, y0 + a + 4.5, "2") self.form3.line(x0 + l / 2 - 5, y0 + h - a, x0 + l / 2 - 5, y0 + h - a - 5) self.form3.line(x0 + l / 2 - 5, y0 + h - a - 5, x0 + l / 2 - 2, y0 + h - a - 5) self.form3.text(x0 + l / 2 - 4, y0 + h - a - 5.5, "1") self.form3.line(x0 + 80 / self.scale, y0 + h / 2, x0 + 80 / self.scale + 8, y0 + h / 2) self.form3.text(x0 + 80 / self.scale + 6, y0 + h / 2 - 0.5, "3") self.form3.line( x0 + (80 + pos3_data[1] * 1000) / self.scale, y0 + h / 2, x0 + (80 + pos3_data[1] * 1000) / self.scale - 8, y0 + h / 2 ) self.form3.text(x0 + (80 + pos3_data[1] * 1000) / self.scale - 7, y0 + h / 2 - 0.5, "3") self.form3.line( x0 + (80 + pos3_data[1] * 1000) / self.scale + mid_dist, y0 + h / 2, x0 + (80 + pos3_data[1] * 1000) / self.scale + mid_dist + 8, y0 + h / 2 ) self.form3.text(x0 + (80 + pos3_data[1] * 1000) / self.scale + mid_dist + 6, y0 + h / 2 - 0.5, "3") self.form3.line( x0 + (80 + pos3_data[1] * 1000 + pos3_data[3] * 1000) / self.scale + mid_dist, y0 + h / 2, x0 + (80 + pos3_data[1] * 1000 + pos3_data[3] * 1000) / self.scale + mid_dist - 8, y0 + h / 2 ) self.form3.text(x0 + (80 + pos3_data[1] * 1000 + pos3_data[3] * 1000) / self.scale + mid_dist -7, y0 + h / 2 - 0.5, "3") self.form3.line( x0 + (80 + pos3_data[1] * 1000 + pos3_data[3] * 1000) / self.scale + 2 * mid_dist, y0 + h / 2, x0 + (80 + pos3_data[1] * 1000 + pos3_data[3] * 1000) / self.scale + 2 * mid_dist + 8, y0 + h / 2 ) self.form3.text(x0 + (80 + pos3_data[1] * 1000 + pos3_data[3] * 1000) / self.scale + 2 * mid_dist + 6, y0 + h / 2 - 0.5, "3") self.form3.line( x0 + (80 + 2 * pos3_data[1] * 1000 + pos3_data[3] * 1000) / self.scale + 2 * mid_dist, y0 + h / 2, x0 + (80 + 2 * pos3_data[1] * 1000 + pos3_data[3] * 1000) / self.scale + 2 * mid_dist - 8, y0 + h / 2 ) self.form3.text(x0 + (80 + 2 * pos3_data[1] * 1000 + pos3_data[3] * 1000) / self.scale + 2 * mid_dist - 7, y0 + h / 2 - 0.5, "3") if l > 250: for i in range(self._result_dict["1"][0]): self.form3.line( x0 + l + 16 + a + s * i, y0 + h - a, x0 + l + 16 + a + 2, y0 + h - a - 5 ) self.form3.line( x0 + l + 16 + a + 2, y0 + h - a - 5, x0 + l + 16 + a + 5, y0 + h - a - 5 ) self.form3.text(x0 + l + 16 + a + 3, y0 + h - a - 5.5, "1") self.form3.line( x0 + l + 16 + a - diam_pos2 / 2, y0 + a, x0 + l + 16 + a - diam_pos2 / 2 - 2, y0 + a - 5 ) self.form3.line( x0 + l + 16 + a - diam_pos2 / 2 - 2, y0 + a - 5, x0 + l + 16 + a - diam_pos2 / 2 - 5, y0 + a - 5 ) self.form3.text(x0 + l + 16 + a - diam_pos2 / 2 - 4, y0 + a - 5.5, "2") self.form3.line( x0 + l + 16 - a + b - diam_pos2 / 2 + diam_pos1 / 2, y0 + a, x0 + l + 16 - a + b - diam_pos2 / 2 + diam_pos1 / 2 + 2, y0 + a - 5 ) self.form3.line( x0 + l + 16 - a + b - diam_pos2 / 2 + diam_pos1 / 2 + 2, y0 + a - 5, x0 + l + 16 - a + b - diam_pos2 / 2 + diam_pos1 / 2 + 5, y0 + a - 5 ) self.form3.text(x0 + l + 16 - a + b - diam_pos2 / 2 + diam_pos1 / 2 + 3, y0 + a - 5.5, "2") self.form3.line( x0 + l + 16 + a - (diam_pos3 / 2 + diam_pos1 / 2), y0 + h / 2, x0 + l + 16 + a - (diam_pos3 / 2 + diam_pos1 / 2) - 6, y0 + h / 2 ) self.form3.text(x0 + l + 16 + a - (diam_pos3 / 2 + diam_pos1 / 2) - 5, y0 + h / 2 - 0.5, "3") self.form3.line( x0 + l + 16 - a + (diam_pos3 / 2 + diam_pos1 / 2) + b, y0 + h / 2, x0 + l + 16 - a + (diam_pos3 / 2 + diam_pos1 / 2) + b + 8, y0 + h / 2 ) self.form3.text(x0 + l + 16 - a + (diam_pos3 + diam_pos1) / 2 + b + 6, y0 + h / 2 - 0.5, "3") self.form3.line( x0 + l + 16 + b / 2, y0 + a - (diam_pos4 + diam_pos2) / 2, x0 + l + 16 + b / 2 - 2, y0 + a - (diam_pos4 + diam_pos2) / 2 - 5 ) self.form3.line(x0 + l + 16 + b / 2 - 2, y0 + a - (diam_pos4 + diam_pos2) / 2 - 5, x0 + l + 16 + b / 2 + 1, y0 + a - (diam_pos4 + diam_pos2) / 2 - 5) self.form3.text(x0 + l + 16 + b / 2 - 1, y0 + a - (diam_pos4 + diam_pos2) / 2 - 5.5, "4") self.form3.line( x0 + l + 16 + 3, y0 + h - a + (diam_pos4 + diam_pos1) / 2, x0 + l + 16 - 2, y0 + h - a + (diam_pos4 + diam_pos1) / 2 + 5 ) self.form3.line( x0 + l + 16 - 2, y0 + h - a + (diam_pos4 + diam_pos1) / 2 + 5, x0 + l + 16 - 5, y0 + h - a + (diam_pos4 + diam_pos1) / 2 + 5 ) self.form3.text(x0 + l + 16 - 4, y0 + h - a + (diam_pos4 + diam_pos1) / 2 + 4.5, "4") else: for i in range(self._result_dict["1"][0]): self.form3.line( x0 + l + 30 + a + s * i, y0 + h - a, x0 + l + 30 + a + 2, y0 + h - a - 5 ) self.form3.line( x0 + l + 30 + a + 2, y0 + h - a - 5, x0 + l + 30 + a + 5, y0 + h - a - 5 ) self.form3.text(x0 + l + 30 + a + 3, y0 + h - a - 5.5, "1") self.form3.line( x0 + l + 30 + a - diam_pos2 / 2, y0 + a, x0 + l + 30 + a - diam_pos2 / 2 - 2, y0 + a - 5 ) self.form3.line( x0 + l + 30 + a - diam_pos2 / 2 - 2, y0 + a - 5, x0 + l + 30 + a - diam_pos2 / 2 - 5, y0 + a - 5 ) self.form3.text(x0 + l + 30 + a - diam_pos2 / 2 - 4, y0 + a - 5.5, "2") self.form3.line( x0 + l + 30 - a + b - diam_pos2 / 2 + diam_pos1 / 2, y0 + a, x0 + l + 30 - a + b - diam_pos2 / 2 + diam_pos1 / 2 + 2, y0 + a - 5 ) self.form3.line( x0 + l + 30 - a + b - diam_pos2 / 2 + diam_pos1 / 2 + 2, y0 + a - 5, x0 + l + 30 - a + b - diam_pos2 / 2 + diam_pos1 / 2 + 5, y0 + a - 5 ) self.form3.text(x0 + l + 30 - a + b - diam_pos2 / 2 + diam_pos1 / 2 + 3, y0 + a - 5.5, "2") self.form3.line( x0 + l + 30 + a - (diam_pos3 / 2 + diam_pos1 / 2), y0 + h / 2, x0 + l + 30 + a - (diam_pos3 / 2 + diam_pos1 / 2) - 6, y0 + h / 2 ) self.form3.text(x0 + l + 30 + a - (diam_pos3 / 2 + diam_pos1 / 2) - 5, y0 + h / 2 - 0.5, "3") self.form3.line( x0 + l + 30 - a + (diam_pos3 / 2 + diam_pos1 / 2) + b, y0 + h / 2, x0 + l + 30 - a + (diam_pos3 / 2 + diam_pos1 / 2) + b + 8, y0 + h / 2 ) self.form3.text(x0 + l + 30 - a + (diam_pos3 + diam_pos1) / 2 + b + 6, y0 + h / 2 - 0.5, "3") self.form3.line( x0 + l + 30 + b / 2, y0 + a - (diam_pos4 + diam_pos2) / 2, x0 + l + 30 + b / 2 - 2, y0 + a - (diam_pos4 + diam_pos2) / 2 - 5 ) self.form3.line(x0 + l + 30 + b / 2 - 2, y0 + a - (diam_pos4 + diam_pos2) / 2 - 5, x0 + l + 30 + b / 2 + 1, y0 + a - (diam_pos4 + diam_pos2) / 2 - 5) self.form3.text(x0 + l + 30 + b / 2 - 1, y0 + a - (diam_pos4 + diam_pos2) / 2 - 5.5, "4") self.form3.line( x0 + l + 30 + 3, y0 + h - a + (diam_pos4 + diam_pos1) / 2, x0 + l + 30 - 2, y0 + h - a + (diam_pos4 + diam_pos1) / 2 + 5 ) self.form3.line( x0 + l + 30 - 2, y0 + h - a + (diam_pos4 + diam_pos1) / 2 + 5, x0 + l + 30 - 5, y0 + h - a + (diam_pos4 + diam_pos1) / 2 + 5 ) self.form3.text(x0 + l + 30 - 4, y0 + h - a + (diam_pos4 + diam_pos1) / 2 + 4.5, "4") def _dim_h(self, x, y, l, x_text=0.0, text=""): x0 = x y0 = y x_t = x0 + x_text + l / 2 - 2 if len(text) == 0: dim_text = str(int(l * self.scale)) else: dim_text = text self.form3.set_line_width(0.05) self.form3.line(x0 - 2, y0 + 8, x0 + l + 2, y0 + 8) self.form3.line(x0, y0 + 2, x0, y0 + 10) self.form3.line(x0 + l, y0 + 2, x0 + l, y0 + 10) self.form3.set_line_width(0.5) self.form3.line(x0 - 0.9, y0 + 8.9, x0 + 0.9, y0 + 7.1) self.form3.line(x0 + l - 0.9, y0 + 8.9, x0 + l + 0.9, y0 + 7.1) self.form3.set_font("iso", "", 11) self.form3.text(x_t, y0 + 7.5, dim_text) def _dim_v(self, x, y, l, x_text=0.0, text=""): x0 = x y0 = y x_t = x0 + x_text - l / 2 - 2 self.form3.rotate(90, x0, y0) if len(text) == 0: dim_text = str(int(l * self.scale)) else: dim_text = text self.form3.set_line_width(0.05) self.form3.line(x0 + 2, y0 - 8, x0 - l - 2, y0 - 8) self.form3.line(x0, y0 - 2, x0, y0 - 10) self.form3.line(x0 - l, y0 - 2, x0 - l, y0 - 10) self.form3.set_line_width(0.5) self.form3.line(x0 + 0.9, y0 - 8.9, x0 - 0.9, y0 - 7.1) self.form3.line(x0 - l + 0.9, y0 - 8.9, x0 - l - 0.9, y0 - 7.1) self.form3.set_font("iso", "", 11) self.form3.text(x_t, y0 - 8.5, dim_text) self.form3.rotate(0) def _draw_form_3(self, y=0): y0 = y self.form3.set_line_width(0.5) self.form3.rect(20, y0 + 10, 390, y0 + 277) self.form3.rect(230, y0 + 232, 180, y0 + 55) self.form3.line(240, y0 + 232, 240, y0 + 257) self.form3.line(250, y0 + 232, 250, y0 + 287) self.form3.line(260, y0 + 232, 260, y0 + 257) self.form3.line(270, y0 + 232, 270, y0 + 287) self.form3.line(285, y0 + 232, 285, y0 + 287) self.form3.line(295, y0 + 232, 295, y0 + 287) self.form3.line(365, y0 + 257, 365, y0 + 287) self.form3.line(380, y0 + 257, 380, y0 + 272) self.form3.line(395, y0 + 257, 395, y0 + 272) self.form3.line(295, y0 + 242, 410, y0 + 242) self.form3.line(230, y0 + 252, 295, y0 + 252) self.form3.line(230, y0 + 257, 410, y0 + 257) self.form3.line(365, y0 + 262, 410, y0 + 262) self.form3.line(295, y0 + 272, 410, y0 + 272) self.form3.set_line_width(0.05) self.form3.line(230, y0 + 237, 295, y0 + 237) self.form3.line(230, y0 + 242, 295, y0 + 242) self.form3.line(230, y0 + 247, 295, y0 + 247) self.form3.line(230, y0 + 262, 295, y0 + 262) self.form3.line(230, y0 + 267, 295, y0 + 267) self.form3.line(230, y0 + 272, 295, y0 + 272) self.form3.line(230, y0 + 277, 295, y0 + 277) self.form3.line(230, y0 + 282, 295, y0 + 282) self.form3.set_font("iso", "", 11) self.form3.text(233, y0 + 255.75, "Зм.") self.form3.text(240.75, y0 + 255.75, "Кільк.") self.form3.text(252, y0 + 255.75, "Арк.") self.form3.text(260.5, y0 + 255.75, "№док.") self.form3.text(273, y0 + 255.75, "Підпис") self.form3.text(286, y0 + 255.75, "Дата") self.form3.text(231, y0 + 260.75, "Виконав") self.form3.text(251, y0 + 260.75, "Бережний") self.form3.text(367, y0 + 260.75, "Стадія") self.form3.text(382.5, y0 + 260.75, "Аркуш") self.form3.text(396.25, y0 + 260.75, "Аркушів") self.form3.text(296, y0 + 275.75, self.title1) self.form3.text(296, y0 + 280.75, self.title2) self.form3.text(296, y0 + 285.75, self.title3) self.form3.set_font("iso", "", 14) self.form3.text(370, y0 + 268.75, "ЕП") self.form3.text(386.5, y0 + 268.75, "1") self.form3.text(401.5, y0 + 268.75, "1") self.form3.text(336, y0 + 238.25, str(datetime.utcnow().strftime("%Y—%m—%d %H:%M"))) self.form3.image("static/images/logo_dark.png", 366.25, y0 + 273.25, 42.5, 12.5) def _draw_specification(self, result_dict: dict, x=230, y=30, title: str = "Специфікація"): x0 = x y0 = y self.form3.set_line_width(0.5) self.form3.line(x0 + 0, y0 + 0, x0 + 180, y0 + 0) self.form3.line(x0 + 0, y0 + 15, x0 + 180, y0 + 15) self.form3.line(x0 + 0, y0 + 0, x0 + 0, y0 + 15 + self.count_of_lines * 8) self.form3.line(x0 + 15, y0 + 0, x0 + 15, y0 + 15 + self.count_of_lines * 8) self.form3.line(x0 + 75, y0 + 0, x0 + 75, y0 + 15 + self.count_of_lines * 8) self.form3.line(x0 + 135, y0 + 0, x0 + 135, y0 + 15 + self.count_of_lines * 8) self.form3.line(x0 + 145, y0 + 0, x0 + 145, y0 + 15 + self.count_of_lines * 8) self.form3.line(x0 + 160, y0 + 0, x0 + 160, y0 + 15 + self.count_of_lines * 8) self.form3.line(x0 + 180, y0 + 0, x0 + 180, y0 + 15 + self.count_of_lines * 8) y = y0 + 23 self.form3.set_line_width(0.05) i = 0 while i < self.count_of_lines: self.form3.set_font("iso", "", 11) self.form3.line(x0 + 0, y, x0 + 180, y) i += 1 y += 8 self.form3.set_font("iso", "", 14) self.form3.text(x0 + 85, y0 - 5, title) self.form3.set_font("iso", "", 11) self.form3.text(x0 + 5, y0 + 9.25, "Поз.") self.form3.text(x0 + 35, y0 + 9.25, "Позначення") self.form3.text(x0 + 94, y0 + 9.25, "Найменування") self.form3.text(x0 + 135.5, y0 + 9.25, "Кільк.") self.form3.text(x0 + 145.3, y0 + 7.25, "Маса од.,") self.form3.text(x0 + 151, y0 + 11, "кг") self.form3.text(x0 + 163, y0 + 9.25, "Примітка") self.form3.set_font("iso", "U", 11) self.form3.text(x0 + 88, y0 + 20.25 + 0 * 8, "Залізобетонні вироби") self.form3.text(x0 + 90, y0 + 20.25 + 2 * 8, "Арматурні вироби") self.form3.text(x0 + 96, y0 + 20.25 + 7 * 8, "Матеріали") self.form3.set_font("iso", "", 11) mark = [] for key in result_dict.keys(): mark.append(key) text0 = f"Залізобетонна балка {mark[0]}" mass = (int(self._result_dict[mark[0]][2]) + 500) * int(self._result_dict[mark[0]][3]) * int(self._result_dict[mark[0]][4]) * 2500 / 1e9 self.form3.text(x0 + 4, y0 + 20.25 + 1 * 8, mark[0]) self.form3.text(x0 + 76, y0 + 20.25 + 1 * 8, text0) self.form3.text(x0 + 139, y0 + 20.25 + 1 * 8, '1') self.form3.text(x0 + 148.5, y0 + 20.25 + 1 * 8, str(mass)) i = 3 for p in mark[1:]: diameter = self._result_dict[p][1] cl = self._result_dict[p][2] length = int(self._result_dict[p][3] * 1000) quantity = self._result_dict[p][0] text1 = f"∅{diameter}{cl}; L={length}" mass = round(pi * (diameter / 1000) ** 2 / 4 * 7850 * length / 1000, 3) total_mass = f"{round(mass * quantity, 3)} кг" self.form3.text(x0 + 6.5, y0 + 20.25 + i * 8, p) self.form3.text(x0 + 16, y0 + 20.25 + i * 8, "ДСТУ 3760:2019") self.form3.text(x0 + 76, y0 + 20.25 + i * 8, text1) self.form3.text(x0 + 139, y0 + 20.25 + i * 8, f"{quantity}") self.form3.text(x0 + 148.5, y0 + 20.25 + i * 8, f"{mass}") self.form3.text(x0 + 162.5, y0 + 20.25 + i * 8, f"{total_mass}") i += 1 volume = (int(self._result_dict[mark[0]][2]) + 500) * int(self._result_dict[mark[0]][3]) * int(self._result_dict[mark[0]][4]) / 1e9 self.form3.text(x0 + 16, y0 + 20.25 + 8 * 8, "ДСТУ Б В.2.7-176:2008") self.form3.text(x0 + 76, y0 + 20.25 + 8 * 8, "Бетон класу С20/25") self.form3.text(x0 + 162.5, y0 + 20.25 + 8 * 8, f"{volume}") self.form3.text(x0 + 171, y0 + 20.25 + 8 * 8, f"м") self.form3.set_font("iso", "", 7) self.form3.text(x0 + 173, y0 + 19.25 + 8 * 8, "3")
def process(self, output_file_name=None, dpi=150, offset=0, fps=10, height_mm=50, margins=Margin(10, 10, 10, 10), paper_format='a4'): def draw_raster(): for ix in range(0, nx + 1): xx = x0 + ix * total.width pdf.line(xx, y0, xx, y1) if offset > 0 and ix != nx: pdf.line(xx + offset, y0, xx + offset, y1) for iy in range(0, ny + 1): yy = y0 + iy * total.height pdf.line(x0, yy, x1, yy) height_mm = float(height_mm) tmp_files = [] if self.clip: if fps != self.clip.fps: if self.verbosity > 0: print 'Transcoding from {} fps to {} fps ...'.format(self.clip.fps, fps) self.clip.write_videofile('tmp.mp4', fps=fps, audio=False) tmp_files.append('tmp.mp4') self.clip = VideoFileClip('tmp.mp4') self.fps = self.clip.fps self.frame_count = int(self.clip.duration * self.fps) clip_size = Size.from_tuple(self.clip.size) elif self.frames: clip_size = Size.from_tuple(self.im.size) paper = self.PAPER_SIZES[paper_format.lower()] printable_area = Size(paper.width - margins.left - margins.right, paper.height - margins.top - margins.bottom) frame_mm = Size(height_mm / clip_size.height * clip_size.width, height_mm) total = Size(offset + frame_mm.width, frame_mm.height) frame = Size(int(frame_mm.width / 25.4 * dpi), int(frame_mm.height / 25.4 * dpi)) nx = int(printable_area.width / total.width) ny = int(printable_area.height / total.height) if self.verbosity > 0: print 'Input: {} fps, {}x{}, {} frames'\ '\n from: {}'\ .format( self.fps, clip_size.width, clip_size.height, self.frame_count, self.input_file_name ) print 'Output: {}dpi, {}x{}, {:.2f}mm x {:.2f}mm, {}x{} tiles'\ '\n to: {}'\ .format( dpi, frame.width, frame.height, frame_mm.width, frame_mm.height, nx, ny, output_file_name ) pdf = FPDF(unit='mm', format=paper_format.upper(), orientation='L') pdf.set_compression(True) pdf.set_title('Funny video') pdf.set_author('Oliver Lau <*****@*****.**> - Heise Medien GmbH & Co. KG') pdf.set_creator('flippy') pdf.set_keywords('flip-book, video, animated GIF') pdf.set_draw_color(128, 128, 128) pdf.set_line_width(0.1) pdf.set_font('Helvetica', '', 12) pdf.add_page() i = 0 page = 0 tx, ty = -1, 0 x0, y0 = margins.left, margins.top x1, y1 = x0 + nx * total.width, y0 + ny * total.height if self.clip: all_frames = self.clip.iter_frames() elif self.frames: all_frames = AnimatedGif(self.im) else: all_frames = [] for f in all_frames: ready = float(i + 1) / self.frame_count if self.verbosity: sys.stdout.write('\rProcessing frames |{:30}| {}%' .format('X' * int(30 * ready), int(100 * ready))) sys.stdout.flush() tx += 1 if type(f) == GifImagePlugin.GifImageFile: f.putpalette(self.palette) self.last_im.paste(f) im = self.last_im.convert('RGBA') else: im = Image.fromarray(f) im.thumbnail(frame.to_tuple()) if tx == nx: tx = 0 ty += 1 if ty == ny: ty = 0 draw_raster() pdf.add_page() page += 1 temp_file = 'tmp-{}-{}-{}.jpg'.format(page, tx, ty) im.save(temp_file) tmp_files.append(temp_file) x = x0 + tx * total.width y = y0 + ty * total.height pdf.image(temp_file, x=x + offset, y=y, w=frame_mm.width, h=frame_mm.height) text = Point(x, y + frame_mm.height - 2) if offset > 0: pdf.rotate(90, text.x, text.y) pdf.text(text.x, text.y + 5, '{}'.format(i)) pdf.rotate(0) i += 1 if y != 0 and x != 0: draw_raster() if self.verbosity > 0: print '\nGenerating PDF ...' pdf.output(name=output_file_name) if self.verbosity > 0: print 'Removing temporary files ...' for temp_file in tmp_files: os.remove(temp_file)
def create_pdf(self): pdf = FPDF(orientation='P') # start PDF, set to portrait, add page pdf.add_page() x, y = (5.0, 5.0) pdf.set_xy(x, y) # set x and y coordinates for printing # Set up variables based on layout chosen by user layout = self.file_settings_widget.ids.pdflayout.text # Default values for option: "Default (5x4)" w = 50; h = 50 # set width and height x_change = 50 # set x distance between this code and next y_change = 50 # set y distance between this code and next max_in_row = 3 # set the max # codes in row - 1 max_in_pg = 20 # set the max # codes in pg if layout == "4x1": w = 60; h = 60 # set same vars as above but for diff layout x_change = 60; y_change = 60 max_in_row = 0; max_in_pg = 4 elif layout == "4x2": w = 70; h = 70 x_change = 65; y_change = 65 max_in_row = 1; max_in_pg = 8 elif layout == "4x3": w = 70; h = 70 x_change = 65; y_change = 65 max_in_row = 2; max_in_pg = 12 elif layout == "4x4": w = 50; h = 55 x_change = 50; y_change = 55 max_in_row = 3; max_in_pg = 16 elif layout == "3x2": w = 90; h = 90 x_change = 90; y_change = 90 max_in_row = 1; max_in_pg = 6 elif layout == "3x3": w = 70; h = 70 x_change = 70; y_change = 70 max_in_row = 2; max_in_pg = 9 elif layout == "2x2": w = 100; h = 100 x_change = 100; y_change = 100 max_in_row = 1; max_in_pg = 4 elif layout == "1x2 and 5/8": w = 35; h = 92.20 x_change = 33; y_change = 88 max_in_row = 5; max_in_pg = 18 elif layout == "Landscape Text": w = 35; h = 35 x_change = 33; y_change = 88 max_in_row = 5; max_in_pg = 18 """ Printing of codes usually results in first page being mostly blank, so this method is a work around to that issue, by printing a first page and then reprinting that first page correctly, since the 2nd page onward works fine """ # This first part is just to get rid of the blank page at the beginning by printing a pg of codes arbitrarily if layout == "Landscape Text": row_num = 0 # used to track # of rows for the Landscape Text layout num_in_row = 0 # used to measure how many will fit in a row num_in_page = 0 # used to measure how many will fit in a pg i = 0 # used to get the label for each code num_codes_to_arbitrarily_print = len(self.array_of_codes) if num_codes_to_arbitrarily_print > 18: num_codes_to_arbitrarily_print = 18 # if the num codes greater than 18, keep it to 18 as that's all I need for j in range(num_codes_to_arbitrarily_print): # print qr codes to pdf file code = self.array_of_codes[j] pdf.image(code, w=w, h=h) # print qr code to pdf pdf.set_xy(5.0, 5.0) # the farthest point you can go here is (275, -195) (really 280, -200 but the starting x,y points are also to be taken into account pdf.rotate(-90) # rotate so labels printed sideways pdf.set_font('Arial', '', 14) # set font family, style, and size pdf.text((h + 3) + y_change * row_num, -1 * (w - 15) - (33 * num_in_row), txt=self.code_labels_array[i]) pdf.rotate(0) # undo rotation num_in_page += 1 x += x_change # adjust values of vars for the next code so it is printed correctly if num_in_row == max_in_row: x = 5.0; y += y_change; num_in_row = -1; row_num += 1 # when maxnum codes are printed in a row, move to next row if num_in_page == max_in_pg: y = 5.0; pdf.add_page(); num_in_page = 0; row_num = 0 # when max codes in page are printed in pg, move to nxt pg pdf.set_xy(x, y) num_in_row += 1 i += 1 if i != 18: # if 18 codes not reached, add a page so that this method/work around still works pdf.add_page() # this page would have been added otherwise, as seen above in code x = 5.0; y = 5.0 pdf.set_xy(x, y) # Then we print the actual codes that will be on the PDF row_num = 0 # used to track # of rows for the Landscape Text layout num_in_row = 0 # used to measure how many will fit in a row num_in_page = 0 # used to measure how many will fit in a pg i = 0 # index used to keep track of array_of_codes position for labels for code in self.array_of_codes: # print qr codes to pdf file pdf.image(code, w=w, h=h) # print code to pdf if layout == "Landscape Text": pdf.set_xy(5.0, 5.0) # the farthest point you can go here is (275, -195) (really 280, -200 but the starting x,y points are also to be taken into account pdf.rotate(-90) # rotate so labels printed sideways pdf.set_font('Arial', '', 14) # set font family, style, and size text_to_print1 = self.code_labels_array[i][:20] text_to_print2 = self.code_labels_array[i][20:40] # split up texts so label fits and doesn't get cut off text_to_print3 = self.code_labels_array[i][40:60] text_to_print4 = self.code_labels_array[i][60:80] text_to_print5 = self.code_labels_array[i][80:100] pdf.text((h + 3) + y_change * row_num, -1 * (w - 15) - (33 * num_in_row), txt=text_to_print1) pdf.text((h + 3) + y_change * row_num, -1 * (w - 15) - (33 * num_in_row) + 5, txt=text_to_print2) pdf.text((h + 3) + y_change * row_num, -1 * (w - 15) - (33 * num_in_row) + 10, txt=text_to_print3) pdf.text((h + 3) + y_change * row_num, -1 * (w - 15) - (33 * num_in_row) + 15, txt=text_to_print4) pdf.text((h + 3) + y_change * row_num, -1 * (w - 15) - (33 * num_in_row) + 20, txt=text_to_print5) pdf.rotate(0) # undo rotation num_in_page += 1 x += x_change # update vars so next code printed correctly if num_in_row == max_in_row: x = 5.0; y += y_change; num_in_row = -1; row_num += 1 # when maxnum codes are printed in a row, move to next row if num_in_page == max_in_pg: # when max codes in page are printed in pg, move to nxt pg y = 5.0; num_in_page = 0; row_num = 0 if i + 1 < len(self.array_of_codes): pdf.add_page() # but only if there are more codes to print pdf.set_xy(x, y) num_in_row += 1 i += 1 # Then we remove the first page by moving the values of the array down one and then decrementing total #pgs if layout == "Landscape Text": # only do this if using landscape text for i in range(pdf.page - 1): pdf.pages[i + 1] = pdf.pages[i + 2] pdf.page = pdf.page - 1 if not self.ids.individualcodes.active: # if Individual QR Codes checkbox not checked for code in self.array_of_codes: # Then delete qrcodes try: os.remove(code) except: continue self.array_of_codes = [] # empty the array_of_codes array for the next create t = datetime.now() file_name = f"SQUIRELOutput-{t.year}-{t.month}-{t.day}-{t.hour}_{t.minute}_{t.second}.pdf" if self.save_folder_path is not None and self.save_folder_path is not "": file_name = f"{self.save_folder_path}/{file_name}" pdf.output(file_name, 'F').encode('latin-1') # output final PDF file
def process( self, output_file_name=None, dpi=150, offset=0, fps=10, height_mm=50, margins=Margin(10, 10, 10, 10), paper_format="a4", ): def draw_raster(): for ix in range(0, nx + 1): xx = x0 + ix * total.width pdf.line(xx, y0, xx, y1) if offset > 0 and ix != nx: pdf.line(xx + offset, y0, xx + offset, y1) for iy in range(0, ny + 1): yy = y0 + iy * total.height pdf.line(x0, yy, x1, yy) height_mm = float(height_mm) tmp_files = [] if self.clip: if fps != self.clip.fps: if self.verbosity > 0: print "Transcoding from {} fps to {} fps ...".format(self.clip.fps, fps) self.clip.write_videofile("tmp.mp4", fps=fps, audio=False) tmp_files.append("tmp.mp4") self.clip = VideoFileClip("tmp.mp4") self.fps = self.clip.fps self.frame_count = int(self.clip.duration * self.fps) clip_size = Size.from_tuple(self.clip.size) elif self.frames: clip_size = Size.from_tuple(self.im.size) paper = self.PAPER_SIZES[paper_format.lower()] printable_area = Size(paper.width - margins.left - margins.right, paper.height - margins.top - margins.bottom) frame_mm = Size(height_mm / clip_size.height * clip_size.width, height_mm) total = Size(offset + frame_mm.width, frame_mm.height) frame = Size(int(frame_mm.width / 25.4 * dpi), int(frame_mm.height / 25.4 * dpi)) nx = int(printable_area.width / total.width) ny = int(printable_area.height / total.height) if self.verbosity > 0: print "Input: {} fps, {}x{}, {} frames" "\n from: {}".format( self.fps, clip_size.width, clip_size.height, self.frame_count, self.input_file_name ) print "Output: {}dpi, {}x{}, {:.2f}mm x {:.2f}mm, {}x{} tiles" "\n to: {}".format( dpi, frame.width, frame.height, frame_mm.width, frame_mm.height, nx, ny, output_file_name ) pdf = FPDF(unit="mm", format=paper_format.upper(), orientation="L") pdf.set_compression(True) pdf.set_title("Funny video") pdf.set_author("Oliver Lau <*****@*****.**> - Heise Medien GmbH & Co. KG") pdf.set_creator("flippy") pdf.set_keywords("flip-book, video, animated GIF") pdf.set_draw_color(128, 128, 128) pdf.set_line_width(0.1) pdf.set_font("Helvetica", "", 12) pdf.add_page() i = 0 page = 0 tx, ty = -1, 0 x0, y0 = margins.left, margins.top x1, y1 = x0 + nx * total.width, y0 + ny * total.height if self.clip: all_frames = self.clip.iter_frames() elif self.frames: all_frames = AnimatedGif(self.im) else: all_frames = [] for f in all_frames: ready = float(i + 1) / self.frame_count if self.verbosity: sys.stdout.write("\rProcessing frames |{:30}| {}%".format("X" * int(30 * ready), int(100 * ready))) sys.stdout.flush() tx += 1 if type(f) == GifImagePlugin.GifImageFile: f.putpalette(self.palette) self.last_im.paste(f) im = self.last_im.convert("RGBA") else: im = Image.fromarray(f) im.thumbnail(frame.to_tuple()) if tx == nx: tx = 0 ty += 1 if ty == ny: ty = 0 draw_raster() pdf.add_page() page += 1 temp_file = "tmp-{}-{}-{}.jpg".format(page, tx, ty) im.save(temp_file) tmp_files.append(temp_file) x = x0 + tx * total.width y = y0 + ty * total.height pdf.image(temp_file, x=x + offset, y=y, w=frame_mm.width, h=frame_mm.height) text = Point(x, y + frame_mm.height - 2) if offset > 0: pdf.rotate(90, text.x, text.y) pdf.text(text.x, text.y + 5, "{}".format(i)) pdf.rotate(0) i += 1 if y != 0 and x != 0: draw_raster() if self.verbosity > 0: print "\nGenerating PDF ..." pdf.output(name=output_file_name) if self.verbosity > 0: print "Removing temporary files ..." for temp_file in tmp_files: os.remove(temp_file)
from fpdf import FPDF pdf = FPDF() # imagelist is the list with all image filenames imagelist = ['IMG-0113.JPG', 'IMG-0114.JPG'] for image in imagelist: pdf.add_page() pdf.image(image, w=150, h=200) pdf.rotate(angle=180) pdf.output("newPDF.pdf", "F")