def createBarCodes(): """ Create barcode examples and embed in a PDF """ c = canvas.Canvas("barcodes.pdf", pagesize=A4) barcode_value = "1234567890" barcode39 = code39.Extended39(barcode_value) barcode39Std = code39.Standard39(barcode_value, barHeight=20, stop=1) # code93 also has an Extended and MultiWidth version barcode93 = code93.Standard93(barcode_value) barcode128 = code128.Code128(barcode_value) # the multiwidth barcode appears to be broken #barcode128Multi = code128.MultiWidthBarcode(barcode_value) barcode_usps = usps.POSTNET("50158-9999") codes = [barcode39, barcode39Std, barcode93, barcode128, barcode_usps] x = 1 * mm y = 285 * mm x1 = 6.4 * mm for code in codes: code.drawOn(c, x, y) y = y - 15 * mm # draw the eanbc8 code barcode_eanbc8 = eanbc.Ean8BarcodeWidget(barcode_value) bounds = barcode_eanbc8.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(50, 10) d.add(barcode_eanbc8) renderPDF.draw(d, c, 15, 555) # draw the eanbc13 code barcode_eanbc13 = eanbc.Ean13BarcodeWidget(barcode_value) bounds = barcode_eanbc13.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(50, 10) d.add(barcode_eanbc13) renderPDF.draw(d, c, 15, 465) # draw a QR code qr_code = qr.QrCodeWidget( 'https://stackoverflow.com/questions/10147455/how-to-send-an-email-with-gmail-as-provider-using-python' ) bounds = qr_code.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(45, 45, transform=[45. / width, 0, 0, 45. / height, 0, 0]) d.add(qr_code) renderPDF.draw(d, c, 15, 405) c.save()
def invoiceReport(): #this makes a report in PDF with all the invoices c = canvas.Canvas('Invoice Report.pdf') w, h = A4 invoiceQuery = query.selectAll('invoice_id', 'invoice') invoiceQuery = sorted(invoiceQuery) firstList = [] finalList = [] #these two loops clean the list we got by invoiceQuery #in order for it to be good for using on the third loop for item in invoiceQuery: f = str(item) firstList.append(f[1:-2]) for iitem in firstList: finalList.append(int(iitem)) #this loop adds the barcode and the details to the PDF document for invoice in finalList: barcode_value = "111" + "0" * (9 - (len(str(invoice)))) + str(invoice) baarcode = eanbc.Ean13BarcodeWidget(barcode_value, barHeight=.5 * cm, barWidth=1.2) d = Drawing() d.add(baarcode) renderPDF.draw(d, c, 150, h - 65) text = c.beginText(50, h - 55) text.setFont("Times-Roman", 12) prelimInvoice = detail_invoice(invoice).split('\n') for segment in prelimInvoice: text.textLine(segment) c.drawText(text) h -= 100 if h <= 150: c.showPage() h = 741.8897637795277 c.save()
def createBarCodes(): """ Create barcode examples and embed in a PDF """ c = canvas.Canvas("barcodes.pdf", pagesize=letter) barcode_value = "12345678999M" barcode39 = code39.Extended39(barcode_value) barcode39Std = code39.Standard39(barcode_value, barHeight=20, stop=1) # code93 also has an Extended and MultiWidth version barcode93 = code93.Standard93(barcode_value) barcode128 = code128.Code128(barcode_value) # the multiwidth barcode appears to be broken #barcode128Multi = code128.MultiWidthBarcode(barcode_value) barcode_usps = usps.POSTNET("50158-9999") codes = [barcode39, barcode39Std, barcode93, barcode128, barcode_usps] x = 1 * mm y = 260 * mm x1 = 6.4 * mm for code in codes: code.drawOn(c, x, y) y = y - 30 * mm barcode_value = "123456789990" # draw the eanbc8 code barcode_eanbc8 = eanbc.Ean8BarcodeWidget(barcode_value) bounds = barcode_eanbc8.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(50, 10) d.add(barcode_eanbc8) renderPDF.draw(d, c, 150 * mm, 150 * mm) # # draw the eanbc13 code barcode_eanbc13 = eanbc.Ean13BarcodeWidget(barcode_value) bounds = barcode_eanbc13.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(50, 10) d.add(barcode_eanbc13) renderPDF.draw(d, c, 150 * mm, 100 * mm) # # draw a QR code qr_code = qr.QrCodeWidget('www.ghf.com') bounds = qr_code.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(45, 45, transform=[45. / width, 0, 0, 45. / height, 0, 0]) d.add(qr_code) renderPDF.draw(d, c, 150 * mm, 50 * mm) c.save()
def eanbc_demo(barcode_value): c = canvas.Canvas('eanbc_demo.pdf') barcode_eanbc8 = eanbc.Ean8BarcodeWidget(barcode_value) bounds = barcode_eanbc8.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(50, 10) d.add(barcode_eanbc8) renderPDF.draw(d, c, 15, 555) # draw the eanbc13 code barcode_eanbc13 = eanbc.Ean13BarcodeWidget(barcode_value) bounds = barcode_eanbc13.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(50, 10) d.add(barcode_eanbc13) renderPDF.draw(d, c, 15, 465) c.save()
def createBarCodes(c): barcode_value = '0112358' barcode39 = code39.Extended39(barcode_value) barcode39Std = code39.Standard39(barcode_value, barHeight=20, stop=1) barcode93 = code93.Standard93(barcode_value) barcode128 = code128.Code128(barcode_value) # barcode128Multi = code128.MultiWidthBarcode(barcode_value) barcode_usps = usps.POSTNET('50158-9999') codes = [barcode39, barcode39Std, barcode93, barcode128, barcode_usps] x = 1 * mm y = 285 * mm for code in codes: code.drawOn(c, x, y) y = y - 15 * mm barcode_eanbc8 = eanbc.Ean8BarcodeWidget(barcode_value) d = Drawing(50, 10) d.add(barcode_eanbc8) renderPDF.draw(d, c, 15, 555) barcode_eanbc13 = eanbc.Ean13BarcodeWidget(barcode_value) d = Drawing(50, 10) d.add(barcode_eanbc13) renderPDF.draw(d, c, 15, 465) qr_code = qr.QrCodeWidget('http://www.baidu.com') bounds = qr_code.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(45, 45, transform=[45./width, 0,0,45./height, 0, 0]) d.add(qr_code) renderPDF.draw(d, c, 15, 405)
def gen_band_pdf(request): pdfmetrics.registerFont(TTFont('PTAstraSerifBold', os.path.join(FONTS_FOLDER, 'PTAstraSerif-Bold.ttf'))) pdfmetrics.registerFont(TTFont('PTAstraSerifReg', os.path.join(FONTS_FOLDER, 'PTAstraSerif-Regular.ttf'))) pdfmetrics.registerFont(TTFont('Symbola', os.path.join(FONTS_FOLDER, 'Symbola.ttf'))) napr_id = json.loads(request.GET["napr_id"]) direction = Napravleniya.objects.filter(pk=napr_id[0]).first() dir_create = strdate(direction.data_sozdaniya) iss = Issledovaniya.objects.values('research__title').filter(napravleniye=direction).first() individual_birthday = strdate(direction.client.individual.birthday) individual_fio = direction.client.individual.fio() buffer = BytesIO() c = canvas.Canvas(buffer, pagesize=(152 * mm, 25 * mm)) c.setFont('PTAstraSerifBold', 12) c.drawString(3.5 * mm, 18 * mm, '{}, {}'.format(individual_fio, individual_birthday)) c.setFont('PTAstraSerifBold', 13) c.drawString(50 * mm, 12 * mm, '№: {}'.format(napr_id[0])) c.setFont('PTAstraSerifReg', 11) c.drawString(50 * mm, 8 * mm, '{}'.format(iss['research__title'])) c.drawString(50 * mm, 4 * mm, 'поступил: {}'.format(dir_create)) barcodeEAN = eanbc.Ean13BarcodeWidget(napr_id[0] + 460000000000, humanReadable=0, barHeight=11 * mm, barWidth=1.25) d = Drawing() d.add(barcodeEAN) renderPDF.draw(d, c, 0 * mm, 4 * mm) c.showPage() c.save() pdf = buffer.getvalue() buffer.close() response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = 'inline; filename="band.pdf"' response.write(pdf) return response
def run(): c = reportlab.pdfgen.canvas.Canvas('barcodetest.pdf', pagesize=pagesizes.A4) framePage(c, 'Hebi-No-Shisho Barcode Test Page' ) y = 700 yd = 50 xb = 40 xs = 240 y = y-yd mybarcode = code39.Standard39(barWidth=inch * 0.010, value="CD3910", checksum=0) mybarcode.drawOn(c, xb, y) c.drawString(xs, y, '%s - Standard39 10 mil' % mybarcode.encoded) y = y-yd mybarcode = code39.Standard39(barWidth=inch * 0.015, value="CD3915", checksum=0) mybarcode.drawOn(c, xb, y) c.drawString(xs, y, '%s - Standard39 15 mil' % mybarcode.encoded) y = y-yd mybarcode = code39.Standard39(barWidth=inch * 0.020, value="CD3930", checksum=0) mybarcode.drawOn(c, xb, y) c.drawString(xs, y, '%s - Standard39 20 mil' % mybarcode.encoded) y = y-yd mybarcode = code93.Standard93(barWidth=inch * 0.010, value="CD9310") mybarcode.drawOn(c, xb, y) c.drawString(xs, y, '%s - Standard93 10 mil' % mybarcode.encoded) y = y-yd mybarcode = code93.Standard93(barWidth=inch * 0.015, value="CD9315") mybarcode.drawOn(c, xb, y) c.drawString(xs, y, '%s - Standard93 15 mil' % mybarcode.encoded) y = y-yd mybarcode = code93.Standard93(barWidth=inch * 0.020, value="CD9320") mybarcode.drawOn(c, xb, y) c.drawString(xs, y, '%s - Standard93 20 mil' % mybarcode.encoded) y = y-yd mybarcode = code128.Code128(barWidth=inch * 0.010, value="C12810") mybarcode.drawOn(c, xb, y) c.drawString(xs, y, '%s - Standard128 10 mil' % mybarcode.value) y = y-yd mybarcode = code128.Code128(barWidth=inch * 0.015, value="C12815") mybarcode.drawOn(c, xb, y) c.drawString(xs, y, '%s - Standard128 15 mil' % mybarcode.value) y = y-yd mybarcode = code128.Code128(barWidth=inch * 0.020, value="C12820") mybarcode.drawOn(c, xb, y) c.drawString(xs, y, '%s - Standard128 20 mil' % mybarcode.value) y = y-yd-10 mydrawing = Drawing() mybarcode = eanbc.Ean13BarcodeWidget(barHeight=inch * 0.5, barWidth=inch * 0.015, value="123456789012") mydrawing.add(mybarcode) mydrawing.drawOn(c, xb, y) c.drawString(xs, y, 'EAN13') c.save()
def createBarCodes(): """ Create barcode examples and embed in a PDF """ #Taking the filename from the user name = input('enter a filename(.pdf) :') c = canvas.Canvas(name, pagesize=letter) #Setting the 10 digit barcode value barcode_value = str(random_with_N_digits(12)) barcode39 = code39.Extended39(barcode_value) barcode39Std = code39.Standard39(barcode_value, barHeight=20, stop=1) # code93 also has an Extended and MultiWidth version barcode93 = code93.Standard93(barcode_value) barcode128 = code128.Code128(barcode_value) # the multiwidth barcode appears to be broken #barcode128Multi = code128.MultiWidthBarcode(barcode_value) codes = [barcode39, barcode39Std, barcode93, barcode128] x = 1 * mm y = 285 * mm x1 = 6.4 * mm for code in codes: code.drawOn(c, x, y) y = y - 15 * mm # draw the eanbc8 code barcode_eanbc8 = eanbc.Ean8BarcodeWidget(barcode_value) bounds = barcode_eanbc8.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(50, 10) d.add(barcode_eanbc8) renderPDF.draw(d, c, 15, 555) # draw the eanbc13 code barcode_eanbc13 = eanbc.Ean13BarcodeWidget(barcode_value) bounds = barcode_eanbc13.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(50, 10) d.add(barcode_eanbc13) renderPDF.draw(d, c, 15, 465) # draw a QR code qr_code = qr.QrCodeWidget(barcode_value) bounds = qr_code.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(45, 45, transform=[45. / width, 0, 0, 45. / height, 0, 0]) d.add(qr_code) renderPDF.draw(d, c, 15, 405) c.save()
def create_labels_pdf(all_unique_labels_lst, sticker_type, production_date, expiration_date): ####################################################################################### # # 2. File Opening and Formatting variables # ####################################################################################### site_name = get_site_name(frappe.local.site) file_path = f'{site_name}/public/files/pdflabels/' # 2.1 Variables of file and data ot open fileName_w_ext = "salida.csv" accessModeUniv_nl = "rU" accessMode_W = "w" accessMode_WB = "wb" dot_pdf = ".pdf" # 2.2 Register a csv Dialect (can be changed to suit specific csv files) csv.register_dialect('mydialect', delimiter=str(','), quotechar=str('"'), doublequote=True, skipinitialspace=True, lineterminator='\r\n', quoting=csv.QUOTE_MINIMAL) # 2.3 strip filename of extension and store it in a variable fileName_wo_ext = os.path.splitext(os.path.basename(fileName_w_ext))[0] fileName_PDF_w_ext = fileName_wo_ext + dot_pdf # 2.3 Formatting Variables, fonts, locale settings, clear command line #locale.setlocale(locale.LC_ALL, 'en_US') # see python doc 22.2 internationalization guate = Locale('es', 'GT') nl = "\n" dot = "." space = " " colon = ":" dash = "-" # 2.5 Tildes unicode http://www.fileformat.info/info/unicode/char/00f3/index.htm a_acute_unicode = b'\xC3\xA1' e_acute_unicode = b'\xC3\xA9' i_acute_unicode = b'\xC3\xAD' o_acute_unicode = b'\xC3\xB3' u_acute_unicode = b'\xC3\xBA' n_tilde_unicode = b'\xC3\xB1' per_unicode = b'\x25' registered_unicode = b'\xc2\xae' copyright_unicode = b'\xc2\xa9' # 2.6 decoded unicode a_tilde_utf = a_acute_unicode.decode('utf8') e_tilde_utf = e_acute_unicode.decode('utf8') i_tilde_utf = i_acute_unicode.decode('utf8') o_tilde_utf = o_acute_unicode.decode('utf8') u_tilde_utf = u_acute_unicode.decode('utf8') n_enie_utf = n_tilde_unicode.decode('utf8') percent_utf = per_unicode.decode('utf8') registered_utf = registered_unicode.decode('utf8') copyright_utf = copyright_unicode.decode('utf8') html_par_open = "<p>" html_par_close = "</p>" html_br = "<br>" html_div_open = "<div>" html_div_close = "</div>" html_span_open = "<span>" html_span_close = "</span>" font_path = "fonts/" # load_font_roboto = "/assets/labels/fonts/roboto/Roboto-Regular.ttf" load_font_roboto = frappe.get_app_path("labels", "public", "fonts", "Roboto-Regular.ttf") image_logo_filename = frappe.get_app_path("labels", "public", "images", "fogliasana.jpg") # image_logo_filename = frappe.get_app_path("/", "data", "uom_data.json") # clear_command_line = os.system('cls' if os.name == 'nt' else 'clear') # clear_command_line ####################################################################################### # # 3. Page size / label size / margins # ####################################################################################### # 3.1 GENERAL USER MODIFIABLE VARIABLES. # These variables represent the most important properties of the barcode. # We begin with the page or label size in millimeters. #-------------------------------------------------------------------------------------- # IMPORTANT NOTE ABOUT LABEL PRINTING!!! # Label printers use the x axis as the width, same here. # As a general rule, the widest part of the label will be also the x axis. # Do not alter the orientation aspects of labels when printing, print as portrait! # FIXME configure a 105mm x 51mm label height: 51mm, width: 105mm label_height_mm = 38 # default = 38 label_width_mm = 50 # default = 51 lft_mgn = 3 #Left margin in mm (helps to wrap paragraph lines) rgt_mgn = 3 #Right margin in mm (helps to wrap paragraph lines) ####################################################################################### # # 4. Fixed Variables for labels (Days until expiration, field text, etc.) # ####################################################################################### #No extra spaces, the string concatenators will handle that. Just the data. #test_bar_code = "1234567800069" #test_prod_desc = "Pillow Case Large" #test_prod_weight = "20" #test_prod_unit = "Oz." dest_filename = "barcode-labels" line3_produced_date_text = "Cosecha:" line4_expiration_date_text = "Vence:" days_to_expiration = 7 currency_symb = "Q" test_price = 30.05 #Price not larger than Q99,000 below_barcode_string = 'Hidropónico Sostenible. Puro' ####################################################################################### # # 5. Colors # ####################################################################################### # 5.1 Desired colors in RGB value o to 255 rgb_pantone_3005_c_blue = (0, 117, 201) rgb_pantone_360_c_green = (108, 192, 74) rgb_pantone_000_c_white = (255, 255, 255) rgb_pantone_black = (0, 0, 0) # 5.2 Desired colors in HEX hex_pantone_3005_c_blue = "#0075c9" hex_pantone_360_c_green = "#6cc04a" hex_pantone_000_c_white = "#ffffff" hex_pantone_black = "#000000" # 5.3 Convert colors to intensity mode 0- 100% rgb_pantone_black_int_red = rgb_pantone_black[0] / float(255) rgb_pantone_black_int_grn = rgb_pantone_black[1] / float(255) rgb_pantone_black_int_blu = rgb_pantone_black[2] / float(255) rgb_pantone_3005_c_blue_int_red = rgb_pantone_3005_c_blue[0] / float(255) rgb_pantone_3005_c_blue_int_grn = rgb_pantone_3005_c_blue[1] / float(255) rgb_pantone_3005_c_blue_int_blu = rgb_pantone_3005_c_blue[2] / float(255) # 5.3 bar color assignment bar_red = rgb_pantone_black_int_red bar_grn = rgb_pantone_black_int_grn bar_blu = rgb_pantone_black_int_blu # 5.4 text color assignment txt_red = rgb_pantone_black_int_red txt_grn = rgb_pantone_black_int_grn txt_blu = rgb_pantone_black_int_blu # 5.5 bar_stroke_color assignment stk_red = rgb_pantone_black_int_red stk_grn = rgb_pantone_black_int_grn stk_blu = rgb_pantone_black_int_blu ####################################################################################### # # 6. Barcode Style parameters # ####################################################################################### # 6.1 FONTS Available fonts for the barcode human readable text # ,Mac expert, standard, symbol, winansi, zapfdingbats, courier, courier bold corierboldoblique courieroblique, helvetica bold, helvetica bold oblique, symbol, times bold times bold italic times italic timesroman zapfdingbats. barcode_font_name = 'Helvetica' # String. default 'Helvetica' barcode_font_size = 11 # Number. mm. default = 10 # 6.2 Bars # 6.2.1 Color. method. default = colors.black, or colors.Color(R,G,B,1), or colors. bar_fill_color = colors.Color(bar_red, bar_grn, bar_blu, alpha=1) # 6.2.2 Height, Width, stroke width bar_height_mm = 15 # Number. default = 13 bar_width_mm = .41 # Number. default = .41 bar_stroke_width = .05 # Number. default = .05 # 6.2.3 Stroke Color. method. default = colors.black bar_stroke_color = colors.Color(stk_red, stk_grn, stk_blu, alpha=1) # 6.2.4 Human Readable text color. method. default = colors.black barcode_text_color = colors.Color(txt_red, txt_grn, txt_blu, alpha=1) # 6.2.5 Human Readable text switch ON/OFF (TRUE/FALSE) barcode_human_readable = 'TRUE' # Boolean. Default 'TRUE' # 6.3 Code NOT WORKING! barcode_use_quiet_space = 0 # Number integer. 0 = no, 1 = YES. Default = 1 left_quiet_space = 1 # Number integer default = 1 DO NOT CHANGE!! right_quiet_space = 1 # Number integer default = 1 DO NOT CHANGE!! """ #Check this one out! http://pydoc.net/Python/reportlab/3.3.0/reportlab.graphics.barcode/ """ # 6.4 Defining the quiet space value if barcode_use_quiet_space == 'yes': quiet_space = 'TRUE' ####################################################################################### # # 7. Paragraph style parameters for Product Name # ####################################################################################### prod_style_name = 'FSBlue' #name your style: 'Stylename' prod_font_name = 'Helvetica' # default = 'Helvetica' prod_font_size = 12 # default = 12 prod_leading = 12 # default = 12 prod_left_indent = 0 # default = 0 prod_right_indent = 0 # default = 0 prod_first_line_indent = 0 # default = 0 prod_alignment = TA_LEFT # default = TA_LEFT prod_space_before = 0 # default = 0 prod_space_after = 0 # default = 0 prod_bullet_font_name = 'Times-Roman' # default = 'Times-Roman' prod_bullet_font_size = 10 # default = 10 prod_bullet_indent = 0 # default = 0 prod_text_color = hex_pantone_black # default = hex_pantone_3005_c_blue prod_back_color = None # default = None prod_word_wrap = None # default = None prod_border_width = 0 # default = 0 prod_border_padding = 0 # default = 0 prod_border_color = None # default = None prod_border_radius = None # default = None prod_allow_widows = 1 # default = 1 prod_allow_orphans = 0 # default = 0 prod_text_transform = None # 'uppercase' | 'lowercase' | None prod_end_dots = None # default = None prod_split_long_words = 1 # default = 1 ####################################################################################### # # 8. Paragraph style parameters for line below product name # ####################################################################################### line3_style_name = 'line3' #name your style: 'Stylename' line3_font_name = 'Helvetica' # default = 'Helvetica' line3_font_size = 12 # default = 12 line3_leading = 12 # default = 12 line3_left_indent = 0 # default = 0 line3_right_indent = 0 # default = 0 line3_first_line_indent = 0 # default = 0 line3_alignment = TA_LEFT # default = TA_LEFT line3_space_before = 0 # default = 0 line3_space_after = 0 # default = 0 line3_bullet_font_name = 'Times-Roman' # default = 'Times-Roman' line3_bullet_font_size = 10 # default = 10 line3_bullet_indent = 0 # default = 0 line3_text_color = hex_pantone_black # default = hex_pantone_3005_c_blue line3_back_color = None # default = None line3_word_wrap = None # default = None line3_border_width = 0 # default = 0 line3_border_padding = 0 # default = 0 line3_border_color = None # default = None line3_border_radius = None # default = None line3_allow_widows = 1 # default = 1 line3_allow_orphans = 0 # default = 0 line3_text_transform = None # 'uppercase' | 'lowercase' | None line3_end_dots = None # default = None line3_split_long_words = 1 # default = 1 ####################################################################################### # # 9. Paragraph style parameters for second line below product name # ####################################################################################### line4_style_name = 'line4' #name your style: 'Stylename' line4_font_name = 'Helvetica' # default = 'Helvetica' line4_font_size = 12 # default = 12 line4_leading = 12 # default = 12 line4_left_indent = 0 # default = 0 line4_right_indent = 0 # default = 0 line4_first_line_indent = 0 # default = 0 line4_alignment = TA_LEFT # default = TA_LEFT line4_space_before = 0 # default = 0 line4_space_after = 0 # default = 0 line4_bullet_font_name = 'Times-Roman' # default = 'Times-Roman' line4_bullet_font_size = 10 # default = 10 line4_bullet_indent = 0 # default = 0 line4_text_color = hex_pantone_black # default = hex_pantone_3005_c_blue line4_back_color = None # default = None line4_word_wrap = None # default = None line4_border_width = 0 # default = 0 line4_border_padding = 0 # default = 0 line4_border_color = None # default = None line4_border_radius = None # default = None line4_allow_widows = 1 # default = 1 line4_allow_orphans = 0 # default = 0 line4_text_transform = None # 'uppercase' | 'lowercase' | None line4_end_dots = None # default = None line4_split_long_words = 1 # default = 1 ####################################################################################### # # 10. Paragraph style parameters for line below product name # ####################################################################################### below_barcode_style_name = 'below-barcode' # name your style: 'Stylename' below_barcode_font_name = 'Helvetica-bold' # default = 'Helvetica' below_barcode_font_size = 8 # default = 12 below_barcode_leading = 12 # default = 12 below_barcode_left_indent = 0 # default = 0 below_barcode_right_indent = 0 # default = 0 below_barcode_first_line_indent = 0 # default = 0 below_barcode_alignment = TA_LEFT # default = TA_LEFT below_barcode_space_before = 0 # default = 0 below_barcode_space_after = 0 # default = 0 below_barcode_bullet_font_name = 'Times-Roman' # default = 'Times-Roman' below_barcode_bullet_font_size = 10 # default = 10 below_barcode_bullet_indent = 0 # default = 0 below_barcode_text_color = hex_pantone_black # default = hex_pantone_3005_c_blue below_barcode_back_color = None # default = None below_barcode_word_wrap = None # default = None below_barcode_border_width = 0 # default = 0 below_barcode_border_padding = 0 # default = 0 below_barcode_border_color = None # default = None below_barcode_border_radius = None # default = None below_barcode_allow_widows = 1 # default = 1 below_barcode_allow_orphans = 0 # default = 0 below_barcode_text_transform = None # 'uppercase' | 'lowercase' | None below_barcode_end_dots = None # default = None below_barcode_split_long_words = 0 # default = 1 ####################################################################################### # # 11. Move everything by x or y mm # ####################################################################################### # 7.1 This moves everything by the specified mm. Useful for adjustments on the fly! # x axis + moves to right, - moves to left # y axis + moves up, - moves down move_x_mm = 0 move_y_mm = 0 ####################################################################################### # # 12. Rotate everything 90 deg to the right, upside down, 90 to the left TODO: Pending! # ####################################################################################### ####################################################################################### # # 13. Positions of elements on page # ####################################################################################### # 13.1 Element Individual Starting Positions # Elements must be placed, measuring from bottom left of label. # The general structure is # lINE 1= Product name and weight # LINE 2= Product name and wight continued # LINE 3= Produced: (date of production) # LINE 4= Expires: (date of expiration) # BARCODE = EAN-13 Barcode # LINE 5 = Price # TODO: If nothing specified, an IF function should default to CENTERING EVERYTHING # In relation to the chosen page size below # with DEFAULTS! For quick and easy setup. # 13.2 Product Text position prod_x_pos_mm = 1 # 51mm x 38mm default = 3 prod_y_pos_mm = 30 # 51mm x 38mm default = 30 # 13.3 "Date of production" line_3_x_pos_mm = 1 # 51mm x 38mm default = 3 line_3_y_pos_mm = 25 # 51mm x 38mm default = 25 # 13.4 "Expiration date" #This line is set at 12.4mm from x origin to align the ":" for easier reading. line_4_x_pos_mm = 10.4 # 51mm x 38mm default = 12.4 line_4_y_pos_mm = 21 # 51mm x 38mm default = 21 # 13.5 Barcode position barcode_x_pos_mm = 5 # 51mm x 38mm default = 7 barcode_y_pos_mm = 5 # 51mm x 38mm default = 5 # 13.6 Usually the price or another description goes here below_barcode_x_pos_mm = 3 # 51mm x 38mm default = 19 for centered price below_barcode_y_pos_mm = .5 # 51mm x 38mm default = 1 # 13.7 a Small number that returns the label group amount. # If you print 40 labels for a particular code, you can serialize it # for ease of counting. label_series_x_pos_mm = 0 # 51mm x 38mm default = 0 label_series_y_pos_mm = 0 # 51mm x 38mm default = 0 # 13.8 logo position image_logo_x_pos_mm = 16 # 51mm x 38mm default = 0 image_logo_y_pos_mm = 30 # 51mm x 38mm default = 0 image_logo_height_mm = 5 # 51mm x 38mm default = 5 ####################################################################################### # # 9. Element Wrappers. in mm. Creates a "virtual box" so that text doesn't flow out # ####################################################################################### #line_1_2_x_wrap_mm = label_width_mm-lft_mgn-rgt_mgn #line_1_2_y_wrap_mm = label_height_mm-bar_height_mm prod_x_wrap_mm = label_width_mm - lft_mgn - rgt_mgn prod_y_wrap_mm = label_height_mm - bar_height_mm #Create a wrapper for line 3, so text cuts off rather than intrude elsewhere line_3_x_wrap_mm = label_width_mm - lft_mgn - rgt_mgn line_3_y_wrap_mm = label_height_mm - bar_height_mm #Create a wrapper for line 4, so text cuts off rather than intrude elsewhere line_4_x_wrap_mm = label_width_mm - lft_mgn - rgt_mgn line_4_y_wrap_mm = label_height_mm - bar_height_mm #Create a wrapper for line 4, so text cuts off rather than intrude elsewhere below_barcode_x_wrap_mm = label_width_mm - lft_mgn - rgt_mgn below_barcode_y_wrap_mm = label_height_mm - bar_height_mm #Create a wrapper for label series, so text cuts off rather than intrude elsewhere label_series_x_wrap_mm = label_width_mm - lft_mgn - rgt_mgn label_series_y_wrap_mm = label_height_mm - bar_height_mm ####################################################################################### # # 9A. Program variables that involve flow control CAREFUL! # ####################################################################################### # 2.4 THE VALID PREFIX. If you change this, no barcodes will be printed! # This prefix must be the one issued by GS1 or prefix issuing authority in your locality. valid_gs1_prefix = "74011688" # 2.5 Search string used right before product name # PLEASE NOTE: Label must be an Item in ERPNext, part of the Bill of Materials of the sales item, and the name must beign with this string, otherwise, the label will not be counted. desc_search_string = "Etiqueta Normal" desc_ending_html = html_par_close ####################################################################################### # # 10. date calculations (default date is today) # ####################################################################################### # 10.1 Date calculation and formatting. # default= today, or can be specified date(2016, 14, 11) # production_date = datetime.date.today() # production_date_print = format_date(production_date,"dd.LLLyyyy" ,locale='es_GT') production_date_print = production_date # 10.2 Expiration date calculation and formatting #Calculates from the production date stated above. # expiration_date = production_date + datetime.timedelta(days=days_to_expiration) # expiration_date = expiration_date # expiration_date_print = format_date(expiration_date,"dd.LLLyyyy" ,locale='es_GT') expiration_date_print = expiration_date # 10.3 Destination Filename Variable that includes dates file_datetime = format_datetime(datetime.datetime.now(), "yyyy-MM-dd-kk-mm-ss", locale='es_GT') # date_time_fileName_PDF_w_ext = file_datetime + dash + dest_filename + dot_pdf date_time_fileName_PDF_w_ext = 'Label' + file_datetime + dot_pdf ####################################################################################### # # 11. Currency formatting # ####################################################################################### #2.3 Using python string formatting #test_price_str = str("%0.2f" % test_price) # no commas # below format with commas and two decimal points. #test_format_price = locale.format("%0.2f",test_price, grouping=True) format_price_print = format_decimal(test_price, format='#,##0.##;-#', locale='es_GT') ###################################################### # # 12. mm to point converter # ###################################################### """ For our label, the position must be specified in points. Above the user enters the values in mm, and these will convert from mm to points. The move_x_mm and move_y_mm will shift the position of all the items in the label together, when specified by the user. """ prod_x_pos = (prod_x_pos_mm + move_x_mm) * mm #10 prod_y_pos = (prod_y_pos_mm + move_y_mm) * mm #95 line_3_x_pos = (line_3_x_pos_mm + move_x_mm) * mm #10 line_3_y_pos = (line_3_y_pos_mm + move_y_mm) * mm #75 line_4_x_pos = (line_4_x_pos_mm + move_x_mm) * mm #10 line_4_y_pos = (line_4_y_pos_mm + move_y_mm) * mm #65 barcode_x_pos = (barcode_x_pos_mm + move_x_mm) * mm #10 barcode_y_pos = (barcode_y_pos_mm + move_y_mm) * mm #95 bar_width = bar_width_mm * mm bar_height = bar_height_mm * mm below_barcode_x_pos = (below_barcode_x_pos_mm + move_x_mm) * mm below_barcode_y_pos = (below_barcode_y_pos_mm + move_y_mm) * mm label_series_x_pos = (label_series_x_pos_mm + move_x_mm) * mm label_series_y_pos = (label_series_y_pos_mm + move_y_mm) * mm image_logo_x_pos = (image_logo_x_pos_mm + move_x_mm) * mm image_logo_y_pos = (image_logo_y_pos_mm + move_y_mm) * mm prod_x_wrap = (prod_x_wrap_mm + move_x_mm) * mm prod_y_wrap = (prod_y_wrap_mm + move_y_mm) * mm line_3_x_wrap = (line_3_x_wrap_mm + move_x_mm) * mm line_3_y_wrap = (line_3_y_wrap_mm + move_y_mm) * mm line_4_x_wrap = (line_4_x_wrap_mm + move_x_mm) * mm line_4_y_wrap = (line_4_y_wrap_mm + move_y_mm) * mm below_barcode_x_wrap = (below_barcode_x_wrap_mm + move_x_mm) * mm below_barcode_y_wrap = (below_barcode_y_wrap_mm + move_y_mm) * mm label_series_x_wrap = (label_series_x_wrap_mm + move_x_mm) * mm label_series_y_wrap = (label_series_y_wrap_mm + move_y_mm) * mm image_logo_height = (image_logo_height_mm + move_y_mm) * mm ###################################################### # # 12.B Concatenating the text strings # ###################################################### #2.3 Concatenating the Strings required by the label. # line_3_text = line3_produced_date_text + production_date_print line_3_text = line3_produced_date_text + production_date_print line_4_text = line4_expiration_date_text + expiration_date_print below_barcode_text = below_barcode_string #currency_symb + format_price_print ####################################################################################### # # 13. BEGIN DEFINE LABEL CREATION FUNCTION TODO: Create two types of labels. # ####################################################################################### ################################################################################### # # 13.1 Create a drawing object to contain everything # ################################################################################### """ Create a PDFCanvas object where we will deposit all the elements of the PDF. drawing object, and then add the barcode to the drawing. Add styles to platypus style Then using renderPDF, you place the drawing on the PDF. Finally, you save the file. """ PDFcanvas = canvas.Canvas( (str(file_path) + str(date_time_fileName_PDF_w_ext))) PDFcanvas.setPageSize((label_width_mm * mm, label_height_mm * mm)) ################################################################################### # # 13.2 Apply paragraph styles for entire document # ################################################################################### styles = getSampleStyleSheet() styles.add( ParagraphStyle(name=prod_style_name, fontName=prod_font_name, fontSize=prod_font_size, leading=prod_leading, leftIndent=prod_left_indent, rightIndent=prod_right_indent, firstLineIndent=prod_first_line_indent, alignment=prod_alignment, spaceBefore=prod_space_before, spaceAfter=prod_space_after, bulletFontName=prod_bullet_font_name, bulletFontSize=prod_bullet_font_size, bulletIndent=prod_bullet_indent, textColor=prod_text_color, backColor=prod_back_color, wordWrap=prod_word_wrap, borderWidth=prod_border_width, borderPadding=prod_border_padding, borderColor=prod_border_color, borderRadius=prod_border_radius, allowWidows=prod_allow_widows, allowOrphans=prod_allow_orphans, textTransform=prod_text_transform, endDots=prod_end_dots, splitLongWords=prod_split_long_words)) styles.add( ParagraphStyle(name=line3_style_name, fontName=line3_font_name, fontSize=line3_font_size, leading=line3_leading, leftIndent=line3_left_indent, rightIndent=line3_right_indent, firstLineIndent=line3_first_line_indent, alignment=line3_alignment, spaceBefore=line3_space_before, spaceAfter=line3_space_after, bulletFontName=line3_bullet_font_name, bulletFontSize=line3_bullet_font_size, bulletIndent=line3_bullet_indent, textColor=line3_text_color, backColor=line3_back_color, wordWrap=line3_word_wrap, borderWidth=line3_border_width, borderPadding=line3_border_padding, borderColor=line3_border_color, borderRadius=line3_border_radius, allowWidows=line3_allow_widows, allowOrphans=line3_allow_orphans, textTransform=line3_text_transform, endDots=line3_end_dots, splitLongWords=line3_split_long_words)) styles.add( ParagraphStyle(name=line4_style_name, fontName=line4_font_name, fontSize=line4_font_size, leading=line4_leading, leftIndent=line4_left_indent, rightIndent=line4_right_indent, firstLineIndent=line4_first_line_indent, alignment=line4_alignment, spaceBefore=line4_space_before, spaceAfter=line4_space_after, bulletFontName=line4_bullet_font_name, bulletFontSize=line4_bullet_font_size, bulletIndent=line4_bullet_indent, textColor=line4_text_color, backColor=line4_back_color, wordWrap=line4_word_wrap, borderWidth=line4_border_width, borderPadding=line4_border_padding, borderColor=line4_border_color, borderRadius=line4_border_radius, allowWidows=line4_allow_widows, allowOrphans=line4_allow_orphans, textTransform=line4_text_transform, endDots=line4_end_dots, splitLongWords=line4_split_long_words)) styles.add( ParagraphStyle(name=below_barcode_style_name, fontName=below_barcode_font_name, fontSize=below_barcode_font_size, leading=below_barcode_leading, leftIndent=below_barcode_left_indent, rightIndent=below_barcode_right_indent, firstLineIndent=below_barcode_first_line_indent, alignment=below_barcode_alignment, spaceBefore=below_barcode_space_before, spaceAfter=below_barcode_space_after, bulletFontName=below_barcode_bullet_font_name, bulletFontSize=below_barcode_bullet_font_size, bulletIndent=below_barcode_bullet_indent, textColor=below_barcode_text_color, backColor=below_barcode_back_color, wordWrap=below_barcode_word_wrap, borderWidth=below_barcode_border_width, borderPadding=below_barcode_border_padding, borderColor=below_barcode_border_color, borderRadius=below_barcode_border_radius, allowWidows=below_barcode_allow_widows, allowOrphans=below_barcode_allow_orphans, textTransform=below_barcode_text_transform, endDots=below_barcode_end_dots, splitLongWords=below_barcode_split_long_words)) ################################################################################### # # 13.3 Set the FONT load_font_roboto = font_path + "roboto/Roboto-Regular.ttf" # FIXME ################################################################################### #barcode_font = FIXME r"/Users/retina/devtools/python-barcode/EAN13-BarcodePDF/fonts/roboto/RobotoRegular.ttf" #barcode_font = r"/fonts/roboto/RobotoRegular.ttf" #barcode_font = "fonts/roboto/RobotoRegular.ttf" FIXME #pdfmetrics.registerFont(TTFont('vera','RobotoRegular.ttf')) ################################################################################### # # 13.4 Loop through the list creating the individual labels # ################################################################################### #The enumerate function allows access to the list items while the for loop iterates for index, each_label_tuple in enumerate(all_unique_labels_lst): # Index variable is initiated above, and returns the index or position of the list item being iterated. #print("this is the index: " + str(index)) # each_label_tuple is initiated above, and is usedby enumerate to return the # contents of the current list item being iterated. #print("this is the tuple item: " + str(each_label_tuple)) ############################################################################### # # 13.4.1 Obtain the contents of the unique label list tuples # ############################################################################### curr_tuple_label_desc = str(each_label_tuple[0]) curr_tuple_label_barcode = str(each_label_tuple[1]) #print("Current Code from tuple: " + curr_tuple_label_barcode) #print("Current Product from tuple: " + curr_tuple_label_desc) ############################################################################### # # 13.4.2 Draw the EAN-13 Code # ############################################################################### # Pass barcode creation parameters to reportlab, any order, as name=value pairs. # Order may be changed, since reportlab maps name=value pairs automatically. # Source code for ordering # http://pydoc.net/Python/reportlab/3.3.0/reportlab.graphics.barcode.eanbc/ barcode_eanbc13 = eanbc.Ean13BarcodeWidget( value=curr_tuple_label_barcode, fontName=barcode_font_name, fontSize=barcode_font_size, x=barcode_x_pos, y=barcode_y_pos, barFillColor=bar_fill_color, barHeight=bar_height, barWidth=bar_width, barStrokeWidth=bar_stroke_width, barStrokeColor=bar_stroke_color, textColor=barcode_text_color, humanReadable=barcode_human_readable, quiet=barcode_use_quiet_space, lquiet=1, rquiet=1) ############################################################################### # # 13.4.? Create the drawing using the same size as the label indicated above # ############################################################################### #size of drawing? d = Drawing(label_width_mm * mm, label_height_mm * mm) ############################################################################### # # 13.4.? Set the text fill color for strings # ############################################################################### PDFcanvas.setFillColorRGB(txt_red, txt_grn, txt_blu) #choose your font color ############################################################################### # # 13.4.? OPTIONAL. Populate the PDF with strings and images # ############################################################################### #PDFcanvas.drawString(line_1_x_pos,line_1_y_pos,line_1_txt) #PDFcanvas.drawString(line_2_x_pos,line_2_y_pos,line_2_txt) #PDFcanvas.drawString(line_3_x_pos,line_3_y_pos,line_3_txt) #PDFcanvas.drawString(line_4_x_pos,line_4_y_pos,line_4_txt) PDFcanvas.drawString(image_logo_x_pos + 62, image_logo_y_pos, registered_utf) PDFcanvas.drawImage(image_logo_filename, image_logo_x_pos, image_logo_y_pos, width=None, height=image_logo_height, mask=None, preserveAspectRatio=True, anchor='c') ############################################################################### # # 13.4.? Add the barcode and position it on the PDFcanvas # ############################################################################### d.add(barcode_eanbc13) # Place the generated barcode on the page. # (Drawing object, Barcode object, x position, y position) renderPDF.draw(d, PDFcanvas, 0, 0) #PDFcanvas.setFont('vera', 32) #This draws the text strings, gets position numbers from variables at beggining of file. """ OPTIONAL IF YOU REGISTER A BARCODE FONT, THIS IS ANOTHER WAY TO SET IT UP barcode_string = '<font name="Free 3 of 9 Regular" size="12">%s</font>' barcode_string = barcode_string % "1234567890" """ #line_1_and_2 = '<font name="Helvetica" size="12">%s</font>' #line_1_and_2 = line_1_and_2 % line_1_txt ############################################################################### # # 13.4.? Add the Product description as a paragraph # ############################################################################### label_prod_desc_area = Paragraph(curr_tuple_label_desc, style=styles["FSBlue"]) label_prod_desc_area.wrapOn(PDFcanvas, prod_x_wrap, prod_y_wrap) label_prod_desc_area.drawOn(PDFcanvas, prod_x_pos, prod_y_pos, mm) ############################################################################### # # 13.4.? Add line 3 (below Prod description 1 or 2 lines) as a paragraph # ############################################################################### # No Mostrara las fechas if sticker_type == '0': pass # Mostrara unicamente la fecha de cosecha if sticker_type == '1': label_line3_area = Paragraph(line_3_text, style=styles["line3"]) label_line3_area.wrapOn(PDFcanvas, line_3_x_wrap, line_3_y_wrap) label_line3_area.drawOn(PDFcanvas, line_3_x_pos, line_3_y_pos, mm) # Mostrara unicamente la fecha de vencimiento if sticker_type == '2': label_line4_area = Paragraph(line_4_text, style=styles["line4"]) label_line4_area.wrapOn(PDFcanvas, line_4_x_wrap, line_4_y_wrap) label_line4_area.drawOn(PDFcanvas, line_4_x_pos, line_4_y_pos, mm) if sticker_type == '3': label_line3_area = Paragraph(line_3_text, style=styles["line3"]) label_line3_area.wrapOn(PDFcanvas, line_3_x_wrap, line_3_y_wrap) label_line3_area.drawOn(PDFcanvas, line_3_x_pos, line_3_y_pos, mm) label_line4_area = Paragraph(line_4_text, style=styles["line4"]) label_line4_area.wrapOn(PDFcanvas, line_4_x_wrap, line_4_y_wrap) label_line4_area.drawOn(PDFcanvas, line_4_x_pos, line_4_y_pos, mm) ############################################################################### # # 13.4.? Add line 4 (below line 3) as a paragraph # ############################################################################### ############################################################################### # # 13.4.? Add below barcode as a paragraph # NOTE: This is NOT the group of human readable numbers below barcode! ############################################################################### label_below_barcode_area = Paragraph(below_barcode_text, style=styles["below-barcode"]) label_below_barcode_area.wrapOn(PDFcanvas, below_barcode_x_wrap, below_barcode_y_wrap) label_below_barcode_area.drawOn(PDFcanvas, below_barcode_x_pos, below_barcode_y_pos, mm) PDFcanvas.showPage() if os.path.exists(file_path): PDFcanvas.save() else: # This portion creates the folder where the sticker file will be saved to. frappe.create_folder(file_path) # This portion creates the folder and saves it to the sites directory specified. PDFcanvas.save() saved_status = create_file_doctype_and_attach( file_path, str(date_time_fileName_PDF_w_ext)) return saved_status
def box_barcode_label(product): ''' Return barcode pdf for a product barcode on the box including: - ean-code - umbrella product name - colour - size - sku label size: 35x89mm ''' product_ean = product.ean_code product_title = product.umbrella_product.__unicode__() product_colour = product.umbrella_product.colour product_size = product.product_model.size product_sku = product.sku buffer = BytesIO() page_real_height = 35 * mm ## Cheating to fix layout, real value 38 page_real_width = 89 * mm ## Cheating to fix layout, real value 90 page_margin = 5 * mm line_height = 2.8 * mm font_size = 8 p = canvas.Canvas(buffer) p.setPageSize((page_real_width, page_real_height)) p.setLineWidth(.3) col1 = 0 col2 = page_real_width / 2 + page_margin ori_string_top_location = page_real_height - page_margin ## Left col string_top_location = ori_string_top_location - 10 * mm ean = eanbc.Ean13BarcodeWidget(product_ean) ean.height = page_real_height ean.width = page_real_width / 2 d = Drawing() d.add(ean) renderPDF.draw(d, p, page_margin, page_margin) ## Right col info p.setFont('Helvetica', font_size) to_draw_strings = textwrap.fill(product_title, 28).split('\n') to_draw_strings.append(u'Colour: {}'.format(product_colour)) to_draw_strings.append(u'Size: {}'.format(product_size)) to_draw_strings.append(u'{}'.format(product_sku)) for s in to_draw_strings: p.drawString(col2, string_top_location, s) string_top_location -= line_height ## new page p.showPage() p.save() pdf = buffer.getvalue() return pdf
def printForm(): hospital_name = dir.hospital_short_title hospital_address = SettingManager.get("org_address") hospital_kod_ogrn = SettingManager.get("org_ogrn") if sys.platform == 'win32': locale.setlocale(locale.LC_ALL, 'rus_rus') else: locale.setlocale(locale.LC_ALL, 'ru_RU.UTF-8') pdfmetrics.registerFont( TTFont('PTAstraSerifBold', os.path.join(FONTS_FOLDER, 'PTAstraSerif-Bold.ttf'))) pdfmetrics.registerFont( TTFont('PTAstraSerifReg', os.path.join(FONTS_FOLDER, 'PTAstraSerif-Regular.ttf'))) styleSheet = getSampleStyleSheet() style = styleSheet["Normal"] style.fontName = "PTAstraSerifReg" style.fontSize = 10.5 style.leading = 14 style.spaceAfter = 1 * mm styleCenterBold = deepcopy(style) styleCenterBold.alignment = TA_CENTER styleCenterBold.fontSize = 12 styleCenterBold.leading = 15 styleCenterBold.fontName = 'PTAstraSerifBold' styleT = deepcopy(style) styleT.alignment = TA_LEFT styleT.fontSize = 10 styleT.leading = 4.5 * mm styleT.face = 'PTAstraSerifReg' barcode = eanbc.Ean13BarcodeWidget(dir.pk + 460000000000, humanReadable=0, barHeight=8 * mm, barWidth=1.25) dir_code = Drawing() dir_code.add(barcode) renderPDF.draw(dir_code, c, 157 * mm, 259 * mm) objs = [] if dir.hospital: source_hospital = dir.hospital hospital_name = source_hospital.safe_short_title hospital_address = source_hospital.safe_address hospital_kod_ogrn = source_hospital.safe_ogrn opinion = [ [ Paragraph( f'<font size=11>{hospital_name}<br/>Адрес: {hospital_address}<br/>ОГРН: {hospital_kod_ogrn} <br/> </font>', styleT), Paragraph( '<font size=9 >Код формы по ОКУД:<br/>Код организации по ОКПО: <br/>' 'Медицинская документация<br/>Учетная форма № 014/у</font>', styleT), ], ] tbl = Table(opinion, 2 * [100 * mm]) tbl.setStyle( TableStyle([ ('GRID', (0, 0), (-1, -1), 0.75, colors.white), ('LEFTPADDING', (1, 0), (-1, -1), 55 * mm), ('VALIGN', (0, 0), (-1, -1), 'TOP'), ])) objs.append(tbl) objs.append(Spacer(1, 5 * mm)) history_num = '' try: issledovaniye = Issledovaniya.objects.get(napravleniye=dir.pk) except ObjectDoesNotExist: issledovaniye = None short_title = issledovaniye.research.short_title if dir.parent and dir.parent.research.is_hospital: history_num = f"(cтационар-{str(dir.parent.napravleniye_id)})" objs.append( Paragraph(f'НАПРАВЛЕНИЕ № {dir.pk} {history_num} ', styleCenterBold)) objs.append( Paragraph( 'НА ПРИЖИЗНЕННОЕ ПАТОЛОГО-АНАТОМИЧЕСКОЕ<br/> ИССЛЕДОВАНИЕ БИОПСИЙНОГО (ОПЕРАЦИОННОГО) МАТЕРИАЛА', styleCenterBold)) objs.append(Paragraph(f'{short_title.upper()}', styleCenterBold)) objs.append(Spacer(1, 10 * mm)) space_symbol = ' ' direction_params = DirectionParamsResult.objects.filter( napravleniye=dir) descriptive_values = [] patient_locality = "" laboratory_value, purpose, table_value, main_diagnos, mkb10_code, clinical_data, method_get_material, doc_get_material, previous_result = ( None, None, None, None, None, None, None, None, None, ) date_get_material = '_________________________' time_get_material = '______________' is_aqua_material = '(да/нет)___________' purpose = 'Уточнение диагноза' department = "" for param in direction_params: if param.field_type == 24: laboratory_value = param.value elif param.field_type == 27: table_value = param.value elif param.field_type in [26, 25]: descriptive_values.append(param.value) elif param.title == 'Цель': purpose = param.value elif param.title == 'Диагноз основной': main_diagnos = param.value elif param.title == 'результаты предыдущие': previous_result = param.value elif param.title.strip() == 'Код по МКБ': try: value = json.loads(param.value) mkb10_code = value["code"] except: mkb10_code = param.value elif param.title == 'Дополнительные клинические сведения': clinical_data = param.value elif param.title == 'Способ получения биопсийного (операционного) материала': method_get_material = param.value elif param.title == 'Материал помещен в 10%-ный раствор нейтрального формалина': is_aqua_material = param.value elif param.title == 'Дата забора материала': date_get_material = normalize_dash_date(param.value) elif param.title == 'Время забора материала': time_get_material = param.value elif param.title == 'ФИО врача': doc_get_material = param.value elif param.title == 'Вид места жительства': try: value = json.loads(param.value) patient_locality = f'{value.get("title", "")} -{value.get("code", "")}' except: patient_locality = "Городская -1, Сельская -2" elif param.title == 'Отделение': department = param.value if not dir.is_external: department = dir.get_doc_podrazdeleniye_title() objs.append( Paragraph( f'1. Отделение, направившее биопсийный (операционный) материал: {department}', style)) objs.append( Paragraph( f'2. Фамилия, имя, отчество (при наличии) пациента: {dir.client.individual.fio()}', style)) sex = dir.client.individual.sex if sex == "м": sex = f'{sex}-1' else: sex = f'{sex}-2' objs.append( Paragraph( f'3. Пол: {sex}, {space_symbol * 5} 4. Дата рождения: число: {dir.client.individual.bd()}', style)) polis_num = '' polis_issue = '' snils = '' ind_data = dir.client.get_data_individual() if ind_data['oms']['polis_num']: polis_num = ind_data['oms']['polis_num'] if ind_data['oms']['polis_issued']: polis_issue = ind_data['oms']['polis_issued'] objs.append( Paragraph(f'5. Полис ОМС: {polis_num} с/к: {polis_issue}', style)) if ind_data['snils']: snils = ind_data['snils'] objs.append(Paragraph(f'6. СНИЛС: {snils}', style)) address = ind_data['main_address'] objs.append(Paragraph(f'7. Место регистрации: {address}', style)) objs.append(Paragraph(f'8. Местность: {patient_locality}', style)) hosp_operation = None if dir.parent and len( hosp_get_operation_data(dir.parent.napravleniye_id)) > 0: hosp_operation = hosp_get_operation_data( dir.parent.napravleniye_id)[-1] diagnos_after_operation = '' mkb10 = '' if hosp_operation: diagnos_after_operation = hosp_operation['diagnos_after_operation'] mkb10 = hosp_operation['mkb10'] if main_diagnos: diagnos_after_operation = main_diagnos objs.append( Paragraph( f"9. Диагноз основного заболевания (состояния): <font face=\"PTAstraSerifBold\">{diagnos_after_operation}</font>", style)) objs.append( Paragraph( '_______________________________________________________________________________________________________', style)) diagnosis = '' if mkb10_code: mkb10 = mkb10_code if mkb10.strip(): diagnosis = mkb10.strip().split(' ')[0] elif dir.diagnos.strip(): diagnosis = dir.diagnos.strip() objs.append(Paragraph(f'10. Код по МКБ: {diagnosis}', style)) objs.append( Paragraph( '11. Задача прижизненного патолого-анатомического исследования биопсийного (операционного) материала', style)) objs.append(Paragraph(f'<u>{purpose}</u>', style)) objs.append( Paragraph( '12. Дополнительные клинические сведения (основные симптомы, оперативное или гормональное, или лучевое лечение,', style)) objs.append( Paragraph( 'результаты инструментальных и лабораторных исследований)__________________________________________________', style)) if clinical_data: objs.append(Paragraph(f"{clinical_data}", style)) if not laboratory_value: objs.append( Paragraph( '_______________________________________________________________________________________________________', style)) if laboratory_value: lab_values = previous_laboratory_result(laboratory_value) if lab_values: objs.extend(lab_values) if descriptive_values: for v in descriptive_values: objs = previous_doc_refferal_result(v, objs) objs.append( Paragraph( '13. Результаты предыдущих прижизненных патолого-анатомических исследований (наименование медицинской организа-ции, дата, регистрационный номер, заключение)', style)) if not previous_result: previous_result = '_______________________________________________________________________________________________________' objs.append(Paragraph(f'{previous_result}', style)) objs.append( Paragraph( '14. Проведенное предоперационное лечение (вид лечения, его сроки, дозировка лекарственного препарата, доза облучения)', style)) objs.append( Paragraph( '_______________________________________________________________________________________________________', style)) objs.append( Paragraph( '_______________________________________________________________________________________________________', style)) if not method_get_material: objs.append( Paragraph( '15. Способ получения биопсийного (операционного) материала: эндоскопическая биопсия—1, пункционная биопсия—2,', style)) objs.append( Paragraph( 'аспирационная биопсия—3, инцизионная биопсия—4, операционная биопсия—5, операционный материал—6,', style)) objs.append( Paragraph('самопроизвольно отделившиеся фрагменты тканей—7.', style)) else: objs.append( Paragraph( f'15. Способ получения биопсийного (операционного) материала: {method_get_material}', style)) objs.append( Paragraph( f'16. Дата забора материала {date_get_material} время {time_get_material}', style)) objs.append( Paragraph( f'17. Материал помещен в 10%-ный раствор нейтрального формалина {is_aqua_material}', style)) objs.append( Paragraph( '18. Маркировка биопсийного (операционного) материала (расшифровка маркировки флаконов):', style)) if not table_value: opinion = [ [ Paragraph('Номер флакона', styleT), Paragraph( 'Локализация патологического процесса (орган, топография)', styleT), Paragraph( 'Характер патологического процесса (эрозия, язва, полип, пятно, узел, внешне не измененная ткань, отношение к окружающим тканям)', styleT), Paragraph('Количество объектов', styleT), ], [ Paragraph('1', styleT), Paragraph('', styleT), Paragraph('', styleT), Paragraph('', styleT) ], [ Paragraph('2', styleT), Paragraph('', styleT), Paragraph('', styleT), Paragraph('', styleT) ], [ Paragraph('3', styleT), Paragraph('', styleT), Paragraph('', styleT), Paragraph('', styleT) ], [ Paragraph('4', styleT), Paragraph('', styleT), Paragraph('', styleT), Paragraph('', styleT) ], [ Paragraph('5', styleT), Paragraph('', styleT), Paragraph('', styleT), Paragraph('', styleT) ], ] cols_width = [ 20 * mm, 50 * mm, 70 * mm, 25 * mm, ] tbl = Table(opinion, colWidths=cols_width) tbl.setStyle( TableStyle([ ('GRID', (0, 0), (-1, -1), 0.75, colors.black), ('VALIGN', (0, 0), (-1, -1), 'TOP'), ])) objs.append(Spacer(1, 5 * mm)) objs.append(tbl) else: table_value_result = table_part_result(table_value, width_max_table=180) if table_value_result: objs.append(table_value_result) objs.append(Spacer(1, 5 * mm)) if not doc_get_material: doc_get_material = dir.doc.get_fio() objs.append( Paragraph( f'19. Фамилия, инициалы врача: {doc_get_material} {space_symbol * 5} подпись _________', style)) objs.append( Paragraph(f'20. Дата направления: {strdate(dir.data_sozdaniya)}', style)) gistology_frame = Frame(0 * mm, 0 * mm, 210 * mm, 297 * mm, leftPadding=15 * mm, bottomPadding=16 * mm, rightPadding=7 * mm, topPadding=10 * mm, showBoundary=1) gistology_inframe = KeepInFrame(210 * mm, 297 * mm, objs, hAlign='LEFT', vAlign='TOP', fakeWidth=False) gistology_frame.addFromList([gistology_inframe], c)
"size": "Size: XS", "sku": "SKU: ECTPU-B-XS" }) for i, sticker_item in enumerate(sticker_items): new_y = start_y - i * step canvas.drawString(start_x, new_y, sticker_items[sticker_item]) return new_y if __name__ == '__main__': c = canvas.Canvas("sticker.pdf") startX = 100 startY = 750 step = 20 newY = draw_sticker_items(c, startX, startY, step) # draw the eanbc13 code on the Canvas barcode_value = "5602897091007" barcode_eanbc13 = eanbc.Ean13BarcodeWidget(barcode_value) bounds = barcode_eanbc13.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(50, 10) d.add(barcode_eanbc13) renderPDF.draw(d, c, startX, newY - 4 * step) # Save to file c.save()
def print_direction(c: Canvas, n, dir: Napravleniya, format_a6: bool = False): xn, yn = 0, 0 if not format_a6: if n % 2 != 0: xn = 1 if n > 2: yn = 1 barcode = eanbc.Ean13BarcodeWidget(dir.pk + 460000000000, humanReadable=0, barHeight=17) bounds = barcode.getBounds() width = bounds[2] - bounds[0] height = bounds[3] - bounds[1] d = Drawing(width, height) d.add(barcode) paddingx = 15 ac = dir.is_all_confirm() canc = dir.cancel visit = dir.visit_date is not None if ac or canc or visit: c.saveState() c.setFillColorRGB(0, 0, 0, 0.2) c.rotate(45) if xn == 0 and yn == 1: ox = w / 2 + 40 * mm oy = h / 2 - 30 * mm elif xn == 0 and yn == 0: ox = w / 2 - 65 * mm oy = 13.5 * mm elif xn == 1 and yn == 0: ox = w - 95.75 * mm oy = 13.5 * mm - h / 4 else: ox = w + 9.25 * mm oy = h / 2 - 30 * mm - h / 4 c.setFont('OpenSansBold', 50) s = 'ОТМЕНЕНО' if ac: s = 'ИСПОЛНЕНО' elif visit: s = 'ПОСЕЩЕНО' c.drawString(ox, oy, s) c.restoreState() c.setFont('OpenSans', 10) c.drawCentredString(w / 2 - w / 4 + (w / 2 * xn), (h / 2 - height - 5) + (h / 2) * yn, dir.hospital_short_title) c.setFont('OpenSans', 8) c.drawCentredString( w / 2 - w / 4 + (w / 2 * xn), (h / 2 - height - 15) + (h / 2) * yn, "(%s. %s)" % (dir.hospital_address, dir.hospital_phones)) c.setFont('OpenSans', 14) c.drawCentredString( w / 2 - w / 4 + (w / 2 * xn), (h / 2 - height - 30) + (h / 2) * yn, "Направление" + ("" if not dir.imported_from_rmis else " из РМИС")) renderPDF.draw(d, c, w / 2 - width + (w / 2 * xn) - paddingx / 3 - 5 * mm, (h / 2 - height - 57) + (h / 2) * yn) c.setFont('OpenSans', 20) c.drawString(paddingx + (w / 2 * xn), (h / 2 - height) + (h / 2) * yn - 57, "№ " + str(dir.pk)) # Номер направления c.setFont('OpenSans', 9) c.drawString( paddingx + (w / 2 * xn), (h / 2 - height - 70) + (h / 2) * yn, "Создано: " + strdate(dir.data_sozdaniya) + " " + strtime(dir.data_sozdaniya)[:5]) history_num = dir.history_num additional_num = dir.additional_num if history_num and len(history_num) > 0: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 70) + (h / 2) * yn, "№ истории: " + history_num) elif additional_num and len(additional_num) > 0: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 70) + (h / 2) * yn, f"({str(additional_num).strip()})") elif dir.client.number_poliklinika and len( dir.client.number_poliklinika) > 0: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 70) + (h / 2) * yn, f"({str(dir.client.number_poliklinika).strip()})") if dir.history_num and len(dir.history_num) > 0: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 70) + (h / 2) * yn, "№ истории: " + dir.history_num) c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 80) + (h / 2) * yn, "ФИО: " + dir.client.individual.fio()) c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 80) + (h / 2) * yn, "Пол: " + dir.client.individual.sex) c.drawRightString( w / 2 * (xn + 1) - paddingx, (h / 2 - height - 90) + (h / 2) * yn, "Д/р: {} ({})".format(dir.client.individual.bd(), dir.client.individual.age_s(direction=dir))) c.drawString( paddingx + (w / 2 * xn), (h / 2 - height - 90) + (h / 2) * yn, "{}: {}".format("ID" if dir.client.base.is_rmis else "Номер карты", dir.client.number_with_type())) diagnosis = dir.diagnos.strip()[:35] if not dir.imported_from_rmis: if diagnosis != "": c.drawString( paddingx + (w / 2 * xn), (h / 2 - height - 100) + (h / 2) * yn, ("" if dir.vich_code == "" else ("Код: " + dir.vich_code + " ")) + "Диагноз (МКБ 10): " + ("не указан" if diagnosis == "-" else diagnosis), ) elif dir.vich_code != "": c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 100) + (h / 2) * yn, "Код: " + dir.vich_code) if dir.istochnik_f: c.drawString( paddingx + (w / 2 * xn), (h / 2 - height - 110) + (h / 2) * yn, "Источник финансирования: " + dir.client.base.title + " - " + dir.istochnik_f.title) else: c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 110) + (h / 2) * yn, "Источник финансирования: ") else: nds = 0 if diagnosis != "": c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 100) + (h / 2) * yn, "Диагноз (МКБ 10): " + diagnosis) nds = 5 if dir.imported_org: c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 105 - nds) + (h / 2) * yn, "Организация: " + dir.imported_org.title) issledovaniya = dir.issledovaniya_set.all() vid = [] has_descriptive = False has_doc_refferal = False need_qr_code = False for i in issledovaniya: rtp = i.research.reversed_type if rtp < -1: has_doc_refferal = True rt = { -2: 'Консультации', -3: 'Лечение', -4: 'Стоматология', -5: 'Стационар', -6: 'Микробиология', -9998: 'Морфология', -9: 'Формы', -11: 'Заявления', -12: 'Мониторинги', }[rtp] # if rtp == -6: # has_micro = True else: rt = i.research.podrazdeleniye.get_title() if rt not in vid: vid.append(rt) if i.research.podrazdeleniye and i.research.podrazdeleniye.p_type == Podrazdeleniya.PARACLINIC: has_descriptive = True if i.research.podrazdeleniye.can_has_pacs: need_qr_code = True c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 120) + (h / 2) * yn, "Вид: " + ", ".join(vid)) if dir.purpose: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 120) + (h / 2) * yn, "Цель: " + dir.get_purpose_display()) if dir.external_organization: c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 134) + (h / 2) * yn, dir.external_organization.title) if dir.parent and dir.parent.research.is_hospital: c.setFont('OpenSansBold', 8) c.drawRightString(w / 2 * (xn + 1) - paddingx, (h / 2 - height - 129) + (h / 2) * yn, ("Стационар-" + str(dir.parent.napravleniye_id))) c.setFont('OpenSans', 9) styleSheet = getSampleStyleSheet() all_iss = issledovaniya.count() max_f = 9 min_f = 7 max_res = 36 max_off = max_f - min_f font_size = max_f - (max_off * (all_iss / max_res)) styleSheet["BodyText"].leading = font_size + 0.5 data = [] values = [] service_locations = {} n = 0 for v in issledovaniya: n += 1 service_location_title = "" if not v.service_location else v.service_location.title if service_location_title: if service_location_title not in service_locations: service_locations[service_location_title] = [] service_locations[service_location_title].append(n) values.append({ "title": v.research.get_title(), "full_title": v.research.title, "sw": v.research.sort_weight, "count": v.how_many, "comment": v.localization.title if v.localization else v.comment, "n": n, "g": -1 if not v.research.fractions_set.exists() else v.research.fractions_set.first().relation_id, "info": v.research.paraclinic_info, "hospital_department_replaced_title": v.hospital_department_replaced_title, }) one_sl = len(service_locations) <= 1 tw = w / 2 - paddingx * 2 m = 0 ns = {} if has_descriptive or has_doc_refferal: tmp = [ Paragraph( '<font face="OpenSansBold" size="8">%s</font>' % ("Исследование" if not has_doc_refferal else "Назначение"), styleSheet["BodyText"]), Paragraph('<font face="OpenSansBold" size="8">Информация</font>', styleSheet["BodyText"]), ] data.append(tmp) colWidths = [int(tw * 0.5), int(tw * 0.5)] values.sort(key=lambda l: l["full_title"]) for v in values: ns[v["n"]] = v["n"] tmp = [ Paragraph( '<font face="OpenSans" size="8">' + ("" if one_sl else "№{}: ".format(v["n"])) + xh.fix(v["full_title"]) + ("" if not v["comment"] else " <font face=\"OpenSans\" size=\"" + str(font_size * 0.8) + "\">[{}]</font>".format(v["comment"])) + ("" if not v["hospital_department_replaced_title"] else f"<br/>Направлен в: {v['hospital_department_replaced_title']}" ) + "</font>", styleSheet["BodyText"], ), Paragraph( '<font face="OpenSans" size="8">' + xh.fix(v["info"]) + "</font>", styleSheet["BodyText"]), ] data.append(tmp) m = 8 else: colWidths = [int(tw / 2), int(tw / 2)] c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 134) + (h / 2) * yn, "Назначения: ") c.setStrokeColorRGB(0, 0, 0) c.setLineWidth(1) values.sort(key=lambda l: (l["g"], l["sw"])) n_rows = int(len(values) / 2) normvars = [] c_cnt = nc_cnt = 0 for i in range(0, len(values) + 1): if (i + 1) % 2 == 0: nc_cnt += 1 if nc_cnt + n_rows < len(values): normvars.append(values[nc_cnt + n_rows]) else: normvars.append(values[c_cnt]) c_cnt += 1 p = Paginator(normvars, 2) n = 1 for pg_num in p.page_range: pg = p.page(pg_num) tmp = [] for obj in pg.object_list: ns[obj["n"]] = n tmp.append( Paragraph( '<font face="OpenSans" size="' + str(font_size) + '">' + ("" if one_sl else "№{}: ".format(n)) + obj["title"] + ("" if not obj["count"] or obj["count"] == 1 else " ({}шт.)".format(str(obj["count"]))) + ("" if not obj["comment"] else " <font face=\"OpenSans\" size=\"" + str(font_size * 0.8) + "\">[{}]</font>".format(obj["comment"])) + "</font>", styleSheet["BodyText"], )) n += 1 if len(pg.object_list) < 2: tmp.append( Paragraph( '<font face="OpenSans" size="' + str(font_size) + '"></font>', styleSheet["BodyText"])) data.append(tmp) t = Table(data, colWidths=colWidths) t.setStyle( TableStyle([ ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('TEXTCOLOR', (0, -1), (-1, -1), colors.black), ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.black), ('BOX', (0, 0), (-1, -1), 0.25, colors.black), ('LEFTPADDING', (0, 0), (-1, -1), 4), ('TOPPADDING', (0, 0), (-1, -1), 0.5), ('RIGHTPADDING', (0, 0), (-1, -1), 2), ('BOTTOMPADDING', (0, 0), (-1, -1), 2), ])) t.canv = c wt, ht = t.wrap(0, 0) t.drawOn(c, paddingx + (w / 2 * xn), ((h / 2 - height - 138 + m) + (h / 2) * yn - ht)) c.setFont('OpenSans', 8) if not has_descriptive and not has_doc_refferal: c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 138 + m) + (h / 2) * yn - ht - 10, "Всего назначено: " + str(len(issledovaniya))) if service_locations: n = 0 if has_descriptive or has_doc_refferal else 1 if one_sl: c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 138 + m) + (h / 2) * yn - ht - 14 - n * 10, "Место: " + list(service_locations)[0]) else: c.drawString(paddingx + (w / 2 * xn), (h / 2 - height - 138 + m) + (h / 2) * yn - ht - 14 - n * 10, "Места оказания услуг:") for title in service_locations: n += 1 c.drawString( paddingx + (w / 2 * xn), (h / 2 - height - 138 + m) + (h / 2) * yn - ht - 14 - n * 10, title + " – услуги " + ', '.join( map(lambda x: "№{}".format(ns[x]), service_locations[title])), ) if need_qr_code: qr_value = translit(dir.client.individual.fio(), 'ru', reversed=True) qr_code = qr.QrCodeWidget(qr_value) qr_code.barWidth = 70 qr_code.barHeight = 70 qr_code.qrVersion = 1 d = Drawing() d.add(qr_code) renderPDF.draw(d, c, paddingx + (w / 2 * xn) + 200, 32 + (h / 2) * yn) nn = 0 if not dir.imported_from_rmis: if dir.doc_who_create and dir.doc_who_create != dir.doc: nn = 9 c.drawString( paddingx + (w / 2 * xn), 13 + (h / 2) * yn, Truncator("Выписал: %s, %s" % (dir.doc_who_create.get_fio(), dir.doc_who_create.podrazdeleniye.title)).chars(63)) if dir.doc: c.drawString( paddingx + (w / 2 * xn), 22 + (h / 2) * yn + nn, "Отделение: " + Truncator(dir.get_doc_podrazdeleniye_title()).chars(50)) c.drawString(paddingx + (w / 2 * xn), 13 + (h / 2) * yn + nn, "Л/врач: " + dir.doc.get_fio()) else: c.drawString(paddingx + (w / 2 * xn), 31 + (h / 2) * yn + nn, "РМИС#" + dir.rmis_number) c.drawString(paddingx + (w / 2 * xn), 22 + (h / 2) * yn + nn, "Создал направление: " + dir.doc_who_create.get_fio()) c.drawString(paddingx + (w / 2 * xn), 13 + (h / 2) * yn + nn, dir.doc_who_create.podrazdeleniye.title) c.setFont('OpenSans', 7) c.setLineWidth(0.25)