def cuadritos_en_ruta(): """ Devuelve dos flowables: Un texto centrado con el texto de "ENVASES VACÍOS..." y una tabla con el texto y los cuadraditos que se rellenan a mano durante la ruta del transportista. """ estilo_centrado = ParagraphStyle("Alineado centrado", parent=estilos["Normal"]) estilo_centrado.alignment = enums.TA_CENTER cab = Paragraph(escribe("ENVASES VACÍOS SIN LIMPIAR, 3 A.D.R."), estilo_centrado) datos = [["G.R.G. 1.000L", "", "", "BIDONES 100L", ""], ["", "", "", "", ""], ["DEPÓSITO 600L", "", "", "BIDONES 50L", ""], ["", "", "", "", ""], ["BIDONES 200L", "", "", "GARRAFAS 60L", ""], ["", "", "", "", ""], ["BIDONES 25L", "", "", "BIDONES 10L", ""]] datos = [[escribe(c) for c in fila] for fila in datos] tabla = Table(datos, colWidths = (3*cm, 0.75*cm, 5*cm, 3*cm, 0.75*cm)) tabla.setStyle(TableStyle([ ("BOX", (1, 0), (1, 0), 1.0, colors.black), ("BOX", (4, 0), (4, 0), 1.0, colors.black), ("BOX", (1, 2), (1, 2), 1.0, colors.black), ("BOX", (4, 2), (4, 2), 1.0, colors.black), ("BOX", (1, 4), (1, 4), 1.0, colors.black), ("BOX", (4, 4), (4, 4), 1.0, colors.black), ("BOX", (1, 6), (1, 6), 1.0, colors.black), ("BOX", (4, 6), (4, 6), 1.0, colors.black), ])) return KeepTogether([Spacer(1, 0.3*cm), cab, Spacer(1, 0.5*cm), tabla])
def build_tabla_cabecera(canvas, datos_albaran, y1): # Cabecera. canvas.saveState() x1 = 1.0 * cm + 1 limite = x1 + 0.9 * PAGE_WIDTH incremento = (limite - x1) / 3 #y1 = 22.5 * cm y2 = y1 - 18 for texto, clave in (("Código cliente", "codcliente"), ("Nº Albarán", "número"), ("Fecha", "fecha")): x2 = x1 + incremento canvas.setFont("Times-Roman", 12) dato_albaran = escribe(datos_albaran[clave]) rectangulo(canvas, (x1, y1), (x2, y2), texto = dato_albaran, alinTxtX = "centro", alinTxtY = "centro") canvas.setFont("Times-Roman", 10) canvas.drawString(x1+0.2*cm, y1 + 3, texto) x1 += incremento canvas.restoreState() # Página x de y. canvas.saveState() canvas.setFont("Times-Italic", 9) canvas.drawRightString(0.9 * PAGE_WIDTH - 0.5 * cm, 1.0 * cm, escribe("Página %d de " % canvas.getPageNumber())) canvas.doForm("lastPageNumber") canvas.restoreState()
def rellenar_datos(c, numalbaran, fecha, nombre_cliente, direccion, ciudad, cif, matricula, medidas, fuente, tamanno): c.drawString(medidas["N.º"][0] + 0.1*cm, medidas["N.º"][1] + 0.1*cm, geninformes.escribe(numalbaran)) c.drawString(medidas["Fecha"][0] + 0.1*cm, medidas["Fecha"][1] + 0.1*cm, geninformes.escribe(fecha)) c.drawString(medidas["Cliente"][0] + 0.1*cm, medidas["Cliente"][1] + 0.1*cm, geninformes.escribe(nombre_cliente)) c.drawString(medidas["Domicilio"][0] + 0.1*cm, medidas["Domicilio"][1] + 0.1*cm, geninformes.escribe(direccion)) c.drawString(medidas["Población"][0] + 0.1*cm, medidas["Población"][1] + 0.1*cm, geninformes.escribe(ciudad)) c.drawString(medidas["N.I.F."][0] + 0.1*cm, medidas["N.I.F."][1] + 0.1*cm, geninformes.escribe(cif)) c.drawString(medidas["Matrícula"][0] + 0.1*cm, medidas["Matrícula"][1] + 0.1*cm, geninformes.escribe(matricula)) c.saveState() c.setFillColorRGB(0.8, 0, 0) c.setFont(fuente, tamanno + 4) numalbaran = ("%5s" % numalbaran).replace(" ", "0") c.drawString(medidas["Albarán"][0] + c.stringWidth(geninformes.escribe("Albarán"), fuente, tamanno) + 0.5 * cm, medidas["Albarán"][1], geninformes.escribe(numalbaran)) c.restoreState()
def build_tabla_contenido(data): """ Construye la tabla del contenido del albaranSalida. Los datos deben venir en listas. Cada línea de la tabla, una tupla o lista con el código, descripción, cantidad, precio unitario (con dto. si lo lleva e IVA) y número de pedido. El precio y cantidad deben ser flotantes para poder calcular el subtotal. """ estilo_cabecera_tabla = ParagraphStyle("Cabecera tabla", parent=estilos["Heading3"]) estilo_cabecera_tabla.fontName = "Times-Bold" estilo_cabecera_tabla.alignment = enums.TA_CENTER estilo_numeros_tabla = ParagraphStyle("Números tabla", parent=estilos["Normal"]) estilo_numeros_tabla.alignment = enums.TA_RIGHT datos = [(Paragraph(escribe("Código"), estilo_cabecera_tabla), Paragraph(escribe("Descripción"), estilo_cabecera_tabla), Paragraph("Cantidad", estilo_cabecera_tabla), Paragraph("Precio/U", estilo_cabecera_tabla), #Paragraph("Total c/IVA", estilo_cabecera_tabla), # CWT: Prefiere la carta de portes sin IVA. Paragraph("Total", estilo_cabecera_tabla), Paragraph(escribe("Nº Pedido"), estilo_cabecera_tabla)) ] for d in data: fila = (escribe(d[0]), Paragraph(escribe(d[1]),estilos["Normal"]), Paragraph(escribe(utils.float2str(d[2])),estilo_numeros_tabla), Paragraph(escribe(utils.float2str(d[3])),estilo_numeros_tabla), Paragraph(escribe(utils.float2str(d[2] * d[3])), estilo_numeros_tabla), escribe(d[4]) ) datos.append(fila) tabla = Table(datos, colWidths = (PAGE_WIDTH * 0.13, PAGE_WIDTH * 0.35, PAGE_WIDTH * 0.09, PAGE_WIDTH * 0.09, PAGE_WIDTH * 0.13, PAGE_WIDTH * 0.11), repeatRows = 1) tabla.setStyle(TableStyle([ ("BACKGROUND", (0, 0), (-1, 0), colors.lightgrey), ("LINEBEFORE", (0, 0), (-1, -1), 0.25, colors.black), ("LINEBELOW", (0, 0), (-1, 0), 1.0, colors.black), ("LINEBELOW", (0, "splitlast"), (-1, "splitlast"), 1.0, colors.black), ("BOX", (0, 0), (-1, -1), 1.0, colors.black), ("INNERGRID", (0, 0), (-1, -1), 0.25, colors.black), ("VALIGN", (0, 0), (-1, 0), "CENTER"), ("VALIGN", (0, 0), (0, -1), "TOP"), ("ALIGN", (0, 0), (-1, 0), "CENTER"), ("ALIGN", (-3, 1), (-1, -1), "RIGHT"), #("ALIGN", (0, 1), (0, -1), "DECIMAL"), <- No puedo cambiar # el pivotChar de "." a ",". No me vale. ("ALIGN", (-1, 1), (-1, -1), "CENTER"), ("ALIGN", (0, 1), (0, -1), "CENTER"), #("RIGHTPADDING", (0, 1), (0, -1), 0.75 * cm), ])) return tabla
def escribir_texto(c, txt, x1, x2, y, fuente, tamanno): if x2: geninformes.agregarFila(x1, y, x2, geninformes.escribe(txt), c, fuente, tamanno, centrado = True, altura_linea = 0.25*cm) else: c.drawString(x1, y, geninformes.escribe(txt))
def rellenar_datos(c, numfactura, fecha, nombre_cliente, direccion, ciudad, cif, medidas, fuente, tamanno): c.saveState() c.setFont(fuente, tamanno + 4) c.drawString(medidas["numfactura"][0], medidas["numfactura"][1], geninformes.escribe(numfactura)) c.drawString(medidas["fecha"][0], medidas["fecha"][1], geninformes.escribe("Fecha: " + fecha)) c.drawString( medidas["cliente"][0] + 0.7 * cm, medidas["cliente"][1] - 1.0 * cm, geninformes.escribe(nombre_cliente) ) c.drawString(medidas["cliente"][0] + 0.7 * cm, medidas["cliente"][1] - 1.75 * cm, geninformes.escribe(direccion)) c.drawString(medidas["cliente"][0] + 0.7 * cm, medidas["cliente"][1] - 2.50 * cm, geninformes.escribe(ciudad)) c.drawString( medidas["cliente"][0] + 0.7 * cm, medidas["cliente"][1] - 3.25 * cm, geninformes.escribe("CIF/NIF: " + cif) ) c.restoreState()
def print_datos_empresa(c, dde, medidas): linea_datos = "%s %s C.P. %s" % (dde.direccion, dde.ciudad, dde.cp) if dde.ciudad != dde.provincia: linea_datos += " (" + dde.provincia + ")" linea_datos += " Teléfono %s" % dde.telefono c.saveState() c.setFont("Helvetica", 8) c.rotate(90) c.drawCentredString(medidas["dde"][0], medidas["dde"][1], geninformes.escribe(linea_datos)) c.rotate(-90) c.drawCentredString( medidas["regmercantil"][0], medidas["regmercantil"][1], geninformes.escribe(dde.registroMercantil) ) c.restoreState()
def build_datos_cliente(datos_cliente = []): """ Devuelve una lista de Flowables con las líneas recibidas como texto. """ datos_c = [Spacer(1, 1*cm)] estilo_datos_c = ParagraphStyle("Cliente", parent = estilos["Heading3"]) estilo_datos_c.alignment = enums.TA_LEFT estilo_datos_c.spaceAfter = estilo_datos_c.spaceBefore = 2 #estilo_datos_c.leftIndent = 0.5*cm if datos_cliente: try: datos_cliente[0] = "<strong>%s</strong>" % datos_cliente[0] except TypeError: datos_cliente = ["<strong>%s</strong>" % datos_cliente[0]] \ + list(datos_cliente[1:]) tamanno_predeterminado = estilo_datos_c.fontSize for linea in datos_cliente: # ¡Esto debería hacerlo ReportLab, pero no sé por qué el markup # sólo funciona con el estilo normal! if "<strong>" in linea: estilo_datos_c.fontSize += 4 else: estilo_datos_c.fontSize = tamanno_predeterminado p = Paragraph(escribe(linea), estilo_datos_c) datos_c.append(p) datos_c.append(Spacer(1, 1*cm)) return datos_c
def build_encabezado(datos_empresa = []): """ Devuelve una lista de "Flowables" de reportlab con los datos de la empresa. Los datos de la empresa se reciben como una lista de textos. """ cabecera = [] estilo_encabezado = ParagraphStyle("Encabezado", parent = estilos["Heading2"]) estilo_encabezado.rightIndent = PAGE_WIDTH * 0.25 estilo_encabezado.alignment = enums.TA_JUSTIFY estilo_encabezado.spaceAfter = 0 estilo_encabezado.spaceBefore = 4 datos_empresa[0] = datos_empresa[0].upper() for linea in datos_empresa: if linea is datos_empresa[0]: estilo_encabezado.fontSize += 3 p = Paragraph(escribe(linea), estilo_encabezado) #cabecera.append(p) cabecera.append(Spacer(1, 10)) estilo_encabezado.fontSize -= 1 if estilo_encabezado.spaceAfter > -4: estilo_encabezado.spaceAfter -= 1 estilo_encabezado.spaceBefore = estilo_encabezado.spaceAfter if linea is datos_empresa[0]: estilo_encabezado.fontSize -= 3 return cabecera
def build_encabezado(datos_albaran): """ Devuelve una tabla de dos líneas con los datos del albarán, que es un diccionario de: fecha -como texto-, número (de albarán), kilos, bultos. """ datos_albaran = sanitize(datos_albaran) datos = [["Fecha", escribe("Nº Albarán"), "Kilos", "Bultos"], [datos_albaran["fecha"], datos_albaran["número"], datos_albaran["kilos"], datos_albaran["bultos"]]] estilo_centrado = ParagraphStyle("Alineado centrado", parent=estilos["Normal"]) estilo_centrado.alignment = enums.TA_CENTER estilo_centrado.fontSize += 2 datos = [[Paragraph(celda, estilos["Normal"]) for celda in datos[0]] , [Paragraph(celda, estilo_centrado) for celda in datos[1]]] tabla = Table(datos, colWidths = (PAGE_WIDTH * 0.9/4,)*4) tabla.setStyle(TableStyle([ ("BOX", (0, 1), (-1, -1), 1.0, colors.black), ("INNERGRID", (0, 1), (-1, -1), 0.25, colors.black), ("ALIGN", (0, 0), (-1, 0), "LEFT"), ("ALIGN", (0, 1), (-1, 1), "CENTER"), ])) return tabla
def dibujar_logo(canvas, doc, ruta_logo, lineas_datos_empresa, datos_fiscales, logo_marcado = None, idioma = "es"): """ Dibuja el logotipo de la empresa en la página de «canvas». También dibuja el pie porque se hace con onLaterPages, que no es llamada en la primera página. Así que aquí hay que hacer las dos cosas. """ try: from framework.pclases import DatosDeLaEmpresa datos_empresa = DatosDeLaEmpresa.select()[0] dibujar_logo_prns(canvas, 1*cm, PAGE_HEIGHT, datos_empresa) dibujar_domicilio_fiscal_prns(canvas, 1*cm, PAGE_HEIGHT - 2.7*cm, datos_empresa) dibujar_domicilio_fabrica_prns(canvas, 1*cm, PAGE_HEIGHT - 3.5*cm, datos_empresa) dibujar_cif_prns(canvas, 1*cm, PAGE_HEIGHT - 4.2*cm, datos_empresa) if idioma == "en": strcarta = "Letter of commitment" else: strcarta = "Carta compromiso" dibujar_bvqi_prns(canvas, PAGE_WIDTH - 1*cm, PAGE_HEIGHT - 3*cm, datos_empresa, strcarta) canvas.saveState() canvas.setStrokeColorRGB(*VERDE_GTX) canvas.line(0, PAGE_HEIGHT - 4.5*cm, PAGE_WIDTH, PAGE_HEIGHT - 4.5*cm) canvas.restoreState() except Exception, e: # OLD CODE IS OLD if ruta_logo: im = Image.open(ruta_logo) ancho, alto = im.size nuevo_alto = min(5 * cm, alto) ancho_proporcional = ancho * (nuevo_alto / alto) canvas.drawImage(ruta_logo, (PAGE_WIDTH - ancho_proporcional) / 2, PAGE_HEIGHT - 2 * cm - nuevo_alto, ancho_proporcional, nuevo_alto) if logo_marcado: im = Image.open(logo_marcado) ancho, alto = im.size nuevo_alto = min(2.5 * cm, alto) ancho_proporcional = ancho * (nuevo_alto / alto) canvas.drawImage(logo_marcado, PAGE_WIDTH - 6 * cm, PAGE_HEIGHT - 2 * cm - nuevo_alto, ancho_proporcional, nuevo_alto) canvas.saveState() canvas.setFont("Helvetica", 8) # OJO: HARCODED (como en todos los PDF que llevan marcado CE) texto_marcado = 'CE 1035-CPD-ES033858' # Ojito: el de rollos, que es # el que tenía puesto José Manuel Hurtado. Todas las críticas al # formato, a él. He copiado tal cual su carta de compromiso. canvas.drawCentredString(PAGE_WIDTH - 6*cm + (ancho_proporcional / 2), PAGE_HEIGHT - 2*cm - nuevo_alto - 8, escribe(texto_marcado)) canvas.restoreState()
def rellenar_ldvs(c, ldvs, total, medidas_tabla, hlin): y = medidas_tabla["y1"] for ldv in ldvs: y -= hlin c.drawRightString(medidas_tabla["xconcepto"] - 0.1*cm, y + 0.15 *cm, geninformes.escribe(ldv[0])) c.drawString(medidas_tabla["xconcepto"] + 0.1*cm, y + 0.15 *cm, geninformes.escribe(ldv[1])) c.drawCentredString( (medidas_tabla["xcateg"] + medidas_tabla["xkgs"])/2, y + 0.15 *cm, geninformes.escribe(ldv[2])) c.drawRightString(medidas_tabla["xprecio"] - 0.1*cm, y + 0.15 *cm, geninformes.escribe(ldv[3])) c.drawRightString(medidas_tabla["ximporte"] - 0.1*cm, y + 0.15 *cm, geninformes.escribe(ldv[4])) c.drawRightString(medidas_tabla["xfinal"] - 0.1*cm, y + 0.15 *cm, geninformes.escribe(ldv[5])) c.drawRightString(medidas_tabla["xfinal"] - 0.1*cm, medidas_tabla["ytotal"] + 0.15 *cm, geninformes.escribe(total))
def solo_cabecera(canvas, doc, datos_de_la_empresa, datos_factura): """ Escribe el texto "FACTURA" y los datos del cliente. Los datos del cliente vienen en un diccionario con: código (de cliente), cif, razón social, dirección, población, provincia. """ fuente = "Helvetica" tamanno = 24 # XXX CWT: Para poder taladrar y archivar sin comerse el cuerpo. canvas.translate(0.6*cm, 0) # XXX canvas.saveState() canvas.setFont(fuente, tamanno) canvas.drawString(PAGE_WIDTH - canvas.stringWidth(escribe("FACTURA"),fuente,tamanno) - 1.0*cm, PAGE_HEIGHT - 1.5*cm, escribe("FACTURA")) canvas.restoreState() # Datos de la empresa dibujar_datos_empresa(canvas, datos_de_la_empresa) #logo, empresa = build_logo_y_empresa_por_separado(datos_de_la_empresa) ##LineaHorizontal(0.9 * PAGE_WIDTH).drawOn(canvas, 78.0, 12.5*cm) ##LineaHorizontal(0.9 * PAGE_WIDTH).drawOn(canvas, 78.0, 12.4 *cm) #logo.drawOn(canvas, 1*cm, PAGE_HEIGHT - 2.8 * cm) #fuente = "Helvetica" #tamanno = 10 #for i in range(len(empresa)): # linea = PAGE_HEIGHT - 1.5 * cm # el_encogedor_de_fuentes_de_doraemon(canvas, # fuente, # tamanno, # 3.25*cm, # PAGE_WIDTH - 1*cm, # linea - (i*0.5*cm), # escribe(empresa[i])) # Cabecera. build_tabla_cabecera(canvas, datos_factura, 26.0*cm)
def print_datos_empresa(c, dde, tm, lm, tampag): linea_datos = "%s %s C.P. %s" % (dde.direccion, dde.ciudad, dde.cp) if dde.ciudad != dde.provincia: linea_datos += " (" + dde.provincia + ")" linea_datos += " Teléfono %s" % dde.telefono c.saveState() c.setFont("Helvetica", 8) c.rotate(90) c.drawString(tm, -lm, geninformes.escribe(linea_datos)) c.rotate(-90) c.restoreState()
def build_datos_obra(obra, idioma = "es"): """ Un cuadro con la referencia recibida de la obra dentro. """ res = None if obra: if idioma == "en": strobra = "WORK REF." strobralo = "Building site" else: strobra = "REF. OBRA:" strobralo = "Obra" estilo_texto = ParagraphStyle(strobralo, parent = estilos["Heading2"]) tabla = Table([[Paragraph(escribe(obra), estilo_texto)]]) tabla.setStyle(TableStyle([ ("BOX", (0, 0), (-1, -1), 1.0, colors.black) ])) res = [Paragraph(escribe(strobra), estilos["Heading2"]), #XBox(PAGE_WIDTH, 2*cm, text = escribe(obra))] tabla] return res
def build_head2(texto, ancho_linea = PAGE_WIDTH - 5.5*cm, offset_linea = 0.0): """ Devuelve el texto con el estilo de encabezado de 2º. nivel y el subrayado. """ estilo_head2 = ParagraphStyle("Header2", parent = estilos["Normal"]) estilo_head2.fontSize = 14 estilo_head2.fontName = "Times-Italic" estilo_head2.textColor = colors.gray texto = Paragraph(escribe(texto), estilo_head2) linea = LineaHorizontal(ancho_linea, offset = offset_linea, color = colors.green) return KeepTogether([texto, Spacer(1, 0.1*cm), linea, Spacer(1, 0.15*cm)])
def build_texto(titular): """ Construye el texto genérico de la carta de portes. """ estilo_texto = ParagraphStyle("Texto", parent = estilos["Normal"]) estilo_texto.alignment = enums.TA_JUSTIFY estilo_texto.firstLineIndent = 24 estilo_texto.fontSize = 8 estilo_texto.leading = 9 texto = """%s hace constar que esta materia se admite al transporte por carretera de acuerdo con las disposiciones del proyecto europeo del transporte de mercancías peligrosas por carretera (ADR) y del reglamento nacional para el transporte de mercancías peligrosas por carretera (TPC). El abajo firmante (conductor y/o transportista) declara: 1.- Que el vehículo cargado cumple las condiciones que establece el reglamento nacional para el transporte de mercancías peligrosas por carretera (ADR/TPC). 2.- Que se ha efectuado correctamente la carga y/o estiba de la mercancía de acuerdo con el citado reglamento. 3.- Que ha recibido la hoja de instrucciones escritas respecto a: - Naturaleza del peligro de la mercancía a transportar. - Medidas de seguridad y otras a tener en cuenta en caso de accidentes, incendio, derrame y otros, todas las cuales ha leído y conoce. 4.- Conocer las disposiciones generales y especiales sobre vehículos, carga, descarga y manipulación de la mercancía, circulación y otras que se establecen para este transporte en el citado reglamento. 5.- El transportista asume la responsabilidad por cualquier accidente ocurrido durante el transporte, sea cual fuere el lugar del siniestro una vez que la mercancía le haya sido entregada. """ % titular p = [Paragraph(escribe(t), estilo_texto) for t in texto.split("\n")] estilo_texto2 = ParagraphStyle("Texto2", parent = estilo_texto) estilo_texto2.alignment = enums.TA_CENTER estilo_texto2.firstLineIndent = 0 #estilo_texto2.fontSize = 8 texto2 = """<b><font size=12>UN 1263, PINTURAS O PRODUCTOS PARA LA PINTURA, 3, II, ADR</b></font>""" texto3 = """ GRG DEPÓSITO 600L BIDÓN 200L BIDÓN 100L ENVASES METÁLICOS GARRAFAS 60L GARRAFAS 25L LEY 11/79 (ART.18.1 DEL REGLAMENTO) el responsable de la entrega del envase usado será el poseedor final Fdo. Conductor Matrícula: Fdo. El expedidor Fdo. El cliente Fdo. Central de carga """ p.append(XPreformatted(escribe(texto2), estilo_texto2)) p.append(XPreformatted(escribe(texto3), estilo_texto2)) return KeepTogether(p)
def print_totales(c, totales, medidas_tabla, hlin): """ Escribe cada línea de la lista de totales en la parte baja de la tabla. Las líneas son a su vez una lista cuyo último elemento es el número que va en la columna Importe y el resto se concatenan y alinean a la derecha en la columna Precio. """ c.saveState() c.setFont("Courier-Bold", 14) y = medidas_tabla["yfinal"] for linea in totales[::-1]: txt = " ".join([str(i) for i in linea[:-1]]) tot = linea[-1] if not isinstance(tot, str): try: tot = utils.float2str(tot) except (TypeError, ValueError): tot = str(tot) c.drawRightString(medidas_tabla["ximporte"] - 0.2 * cm, y + 0.2 * cm, geninformes.escribe(txt)) c.drawRightString(medidas_tabla["xfinal"] - 0.2 * cm, y + 0.2 * cm, geninformes.escribe(tot)) y += medidas_tabla["h"] c.restoreState()
def build_texto(datos_de_la_empresa): """ Construye el texto genérico de la carta de portes. """ estilo_texto = ParagraphStyle("Texto", parent = estilos["Normal"]) estilo_texto.alignment = enums.TA_JUSTIFY estilo_texto.firstLineIndent = 24 estilo_texto.fontSize = 8 estilo_texto.leading = 9 texto = """Norma UNE EN 13249:2001 y UNE EN 13249:2001/A1:2005, Norma UNE EN 13250:2001 y UNE EN 13250:2001/A1:2005, Norma UNE EN 13251:2001 y UNE EN 13251:2001/A1:2005, Norma UNE EN 13252:2001, UNE EN 13252/Erratum:2002 y UNE EN 13252:2001/A1:2005, Norma UNE EN 13253:2001 y UNE EN 13253:2001/A1:2005, Norma UNE EN 13254:2001, UNE EN 13254/AC:2003 y UNE EN 13254:2001/A1:2005, Norma UNE EN 13255:2001, UNE EN 13255/AC:2003 y UNE EN 13255:2001/A1:2005, Norma UNE EN 13256:2001, UNE EN 13256/AC:2003 y UNE EN 13256:2001/A1:2005,Norma UNE EN 13257:2001, UNE EN 13257/AC:2003 y UNE EN 13257:2001/A1:2005, Norma UNE EN 13265:2001, UNE EN 13265/AC:2003 y UNE EN 13265:2001/A1:2005. Geotextil no tejido formado por fibras vírgenes <b>100% de polipropileno</b>, unidas mecánicamente por un proceso de agujado con posterior termofijado. Campo de aplicación: en carreteras y otras zonas de tráfico, construcciones ferroviarias, movimientos de tierras, cimentaciones y estructuras de contención, sistemas de drenaje, control de la erosión (protección costera y revestimiento de taludes), construcción de embalses y presas, construcción de canales, construcción de túneles y estructuras subterráneas, vertederos de residuos sólidos, proyectos de contenedores de residuos sólidos. """ p = [Paragraph(escribe(t), estilo_texto) for t in texto.split("\n") if t] p.insert(1, Spacer(1, 0.25*cm)) logo_ce = Image(os.path.join("..", "imagenes", "CE.png")) logo_ce.drawHeight = 0.75*cm logo_ce.drawWidth = 1*cm p.insert(0, logo_ce) p.insert(1, Spacer(1, 0.15*cm)) estilo_numero_marcado = ParagraphStyle("NumeroMarcado", parent = estilos["Normal"]) estilo_numero_marcado.alignment = enums.TA_CENTER estilo_numero_marcado.fontSize = 7 estilo_numero_marcado.fontName = "Courier" p.insert(2, Paragraph(escribe("1035-CPD-ES033858"), estilo_numero_marcado)) estilo_nombre_empresa = ParagraphStyle("NombreEmpresa", parent = estilos["Normal"]) estilo_nombre_empresa.alignment = enums.TA_CENTER estilo_nombre_empresa.fontSize = 7 estilo_nombre_empresa.fontName = "Courier-Bold" nombre_empresa = datos_de_la_empresa.nombre p.insert(3, Paragraph(escribe(nombre_empresa.upper()), estilo_nombre_empresa)) p.insert(4, Spacer(1, 0.15*cm)) return KeepTogether(p)
def build_mas_texto(titular): """ Construye más texto genérico de la carta de portes. """ estilo_texto = ParagraphStyle("Texto", parent = estilos["Normal"]) estilo_texto.alignment = enums.TA_JUSTIFY estilo_texto.firstLineIndent = 24 estilo_texto.fontSize = 8 texto = """%s hace constar que esta materia se admite al transporte por carretera, de acuerdo con las disposiciones del proyecto europeo del transporte de mercancías peligrosas por carretera (ADR) y del reglamento nacional para el transporte de mercancías peligrosas por carretera (TPC). El abajo firmante (conductor y/o transportista) declara: 6.- Que el vehículo cargado cumple las condiciones que establece el Reglamento Nacional para el Transporte de Mercancías Peligrosas por carretera (ADR/TPC). 7.- Que se ha efectuado correctamente la carga y/o estiba de la mercancía de acuerdo con el citado Reglamento. 8.- Que ha recibido la hoja de instrucciones escrita respecto a: - Naturaleza del peligro de la mercancía a transportar. - Medidas de seguridad y otras a tener en cuenta en caso de accidentes, incendio, derrame y otros, todas las cuales ha leído y conoce. 9.- Conocer las disposiciones generales y especiales sobre vehículos, carga, descarga y manipulación de la mercancía, circulación y otras que se establecen para este transporte en el citado Reglamento. 10.- El transportista asume la responsabilidad por cualquier accidente ocurrido durante el transporte, sea cual fuere el lugar del siniestro una vez que la mercancía le haya sido entregada. """ % titular p = [Paragraph(escribe(t), estilo_texto) for t in texto.split("\n")] estilo_texto2 = ParagraphStyle("Texto2", parent = estilo_texto) estilo_texto2.alignment = enums.TA_CENTER estilo_texto2.firstLineIndent = 0 #estilo_texto2.fontSize = 8 texto2 = """<b><font size=12>UN 1263, PINTURAS O PRODUCTOS PARA LA PINTURA, 3, II, ADR</b></font> GRG DEPÓSITO 600L BIDÓN 200L BIDÓN 100L ENVASES METÁLICOS GARRAFAS 60L GARRAFAS 25L LEY 11/79 (ART.18.1 DEL REGLAMENTO) EL RESPONSABLE DE LA ENTREGA DEL ENVASE USADO SERÁ EL POSEEDOR FINAL FDO. CONDUCTOR MATRÍCULA: FDO. EL EXPEDIDOR FDO. EL CLIENTE """ p.append(XPreformatted(escribe(texto2), estilo_texto2)) p.append(XPreformatted(" FECHA:", estilo_texto)) return p
def pie(canvas, datos_de_la_empresa): canvas.saveState() tamanno = 8 fuente = "Times-Bold" canvas.setFont(fuente, tamanno) canvas.drawString(2*cm, 2.2*cm, escribe(datos_de_la_empresa.nombre.upper())) fuente = "Times-Roman" canvas.setFont(fuente, tamanno) canvas.drawString(2*cm, 1.9*cm, escribe(datos_de_la_empresa.direccion)) canvas.drawString(2*cm, 1.6*cm, escribe("%s - %s (%s), %s" % ( datos_de_la_empresa.cp, datos_de_la_empresa.ciudad, datos_de_la_empresa.provincia, datos_de_la_empresa.pais))) canvas.drawString(2*cm, 1.3*cm, escribe("Tel.: %s Fax: %s" % ( datos_de_la_empresa.telefono, datos_de_la_empresa.fax))) # FIXME: Está un poco chungaleta esto, pero para no meter más datos en # la tabla ahora mismo y por no perder mucho tiempo con chequeos lo dejo # de momento así hasta que llegue a pruebas. canvas.drawString(2*cm, 1*cm, escribe("Web: www.%s Correo-e: %s" % ( datos_de_la_empresa.email.split("@")[1], datos_de_la_empresa.email))) canvas.restoreState()
def build_texto(texto): """ El texto que encabeza la tabla. """ res = None if texto: estilo_texto = ParagraphStyle("Texto", parent = estilos["Normal"]) estilo_texto.alignment = enums.TA_JUSTIFY estilo_texto.firstLineIndent = 24 _res = [Paragraph(escribe(i), estilo_texto) for i in texto.split("\n")] espacio = Spacer(1, 0.25*cm) res = [_res[0]] for i in _res[1:]: res.extend([espacio, i]) return res
def build_fecha(fecha, idioma): res = None if fecha: estilo_texto = ParagraphStyle("Texto", parent = estilos["Normal"]) estilo_texto.alignment = enums.TA_RIGHT estilo_texto.fontSize += 2 if not isinstance(fecha, str): fecha = utils.str_fecha(fecha) if idioma == "en": strdate = "Date: %s" else: strdate = "Fecha: %s" res = Paragraph(escribe(strdate % fecha), estilo_texto) return res
def build_todavia_mas_texto(): """ Construye más texto genérico de la carta de portes. """ estilo_texto = ParagraphStyle("Texto", parent = estilos["Normal"]) estilo_texto.alignment = enums.TA_JUSTIFY estilo_texto.firstLineIndent = 24 estilo_texto.fontSize = 12 texto = """ Transporte que no excede de los límites establecidos en el capítulo 1.1.3.6. """ estilo_texto2 = ParagraphStyle("Texto2", parent = estilo_texto) estilo_texto2.alignment = enums.TA_CENTER estilo_texto2.firstLineIndent = 0 #estilo_texto2.fontSize = 8 p = Paragraph(escribe(texto), estilo_texto2) return p
def build_encabezado(datos_empresa = []): """ Devuelve una lista de "Flowables" de reportlab con los datos de la empresa. Los datos de la empresa se reciben como una lista de textos. """ cabecera = [] estilo_encabezado = ParagraphStyle("Encabezado", parent = estilos["Heading2"]) estilo_encabezado.rightIndent = PAGE_WIDTH * 0.4 estilo_encabezado.alignment = enums.TA_CENTER estilo_encabezado.spaceAfter = estilo_encabezado.spaceBefore = 6 for linea in datos_empresa: p = Paragraph(escribe(linea), estilo_encabezado) cabecera.append(p) estilo_encabezado.fontSize -= 1 if estilo_encabezado.spaceAfter > 0: estilo_encabezado.spaceAfter -= 1 estilo_encabezado.spaceBefore = estilo_encabezado.spaceAfter return cabecera
def dibujar_datos_empresa(canvas, datos_de_la_empresa): """ Dibuja los datos de la empresa en la parte superior. """ logo, empresa = build_logo_y_empresa_por_separado(datos_de_la_empresa) logo.drawOn(canvas, 1*cm, PAGE_HEIGHT - 2.8 * cm) fuente = "Helvetica" tamanno = 16 for i in range(len(empresa)): if i == 1: tamanno -= 4 # Primera línea (nombre empresa) un poco más grande. linea = PAGE_HEIGHT - 1.5 * cm el_encogedor_de_fuentes_de_doraemon(canvas, fuente, tamanno, 3.25*cm, PAGE_WIDTH - 5*cm, linea - (i*0.55*cm), escribe(empresa[i]))
def cabecera(canvas, datos_de_la_empresa): """ Escribe el texto «CERTIFICADO DE CALIDAD», el logotipo de la empresa, una imagen de geotextiles y un par de rayajos de adorno. """ fuente = "Helvetica-Bold" tamanno = 12 canvas.saveState() canvas.setFont(fuente, tamanno) canvas.drawCentredString(PAGE_WIDTH / 2.0 + 1*cm, PAGE_HEIGHT - 2 * cm, escribe("CERTIFICADO DE CALIDAD")) canvas.restoreState() rutalogo = datos_de_la_empresa.logo if rutalogo: rutalogo = os.path.join("..", "imagenes", rutalogo) logo = Image(rutalogo) logo.drawHeight = 2*cm * logo.drawHeight / logo.drawWidth logo.drawWidth = 2*cm logo.drawOn(canvas, 2.75*cm, PAGE_HEIGHT - 1*cm - 2*cm) # OJO: Foto de geotextiles HARCODED. rutafoto = os.path.join("..", "imagenes", "foto_geotextiles.jpg") foto = Image(rutafoto) foto.drawHeight = 2*cm * foto.drawHeight / foto.drawWidth foto.drawWidth = 2*cm foto.drawOn(canvas, PAGE_WIDTH - 5*cm, PAGE_HEIGHT - 2.75*cm - 2*cm) canvas.saveState() canvas.setStrokeColor(colors.green) canvas.rect(PAGE_WIDTH - 5*cm, PAGE_HEIGHT - 2.75*cm - 2*cm, 2*cm, 2*cm) ## XXX: Esto de ahora es un poco chapuza, y como cambie algún margen se va ## al carajo este trocito de línea que se supone que debería ser parte de ## la sección Denominación. canvas.line(PAGE_WIDTH - 5*cm + 2*cm, PAGE_HEIGHT - 3.25*cm, PAGE_WIDTH - 5*cm + 2.25*cm, PAGE_HEIGHT - 3.25*cm) ## XXX: EOChapuza canvas.restoreState() canvas.line(5*cm, PAGE_HEIGHT - 1*cm, # (x1, y1) 5*cm, PAGE_HEIGHT - 2.5*cm) # (x2, y2) canvas.line(PAGE_WIDTH - 3*cm, PAGE_HEIGHT - 1*cm, # (x1, y1) PAGE_WIDTH - 3*cm, PAGE_HEIGHT - 2.5*cm) # (x2, y2) # En la primera página también debe ir el pie pie(canvas, datos_de_la_empresa)
def rellenar_ldvs(c, ldvs, totales, medidas_tabla, hlin): y = medidas_tabla["y1"] for ldv in ldvs: y -= hlin c.drawCentredString( (medidas_tabla["xnumalb"] + medidas_tabla["xdesc"]) / 2, y + 0.15 * cm, geninformes.escribe(ldv[0]) ) c.drawString(medidas_tabla["xdesc"] + 0.1 * cm, y + 0.15 * cm, geninformes.escribe(ldv[1])) c.drawCentredString( (medidas_tabla["xfecha"] + medidas_tabla["xkgs"]) / 2, y + 0.15 * cm, geninformes.escribe(ldv[2]) ) c.drawRightString(medidas_tabla["xprecio"] - 0.1 * cm, y + 0.15 * cm, geninformes.escribe(ldv[3])) c.drawRightString(medidas_tabla["ximporte"] - 0.1 * cm, y + 0.15 * cm, geninformes.escribe(ldv[4])) c.drawRightString(medidas_tabla["xfinal"] - 0.1 * cm, y + 0.15 * cm, geninformes.escribe(ldv[5])) if totales: print_totales(c, totales, medidas_tabla, hlin)
def build_datos_cliente(datos_cliente = [], idioma = "es"): """ Devuelve una lista de Flowables con las líneas recibidas como texto. """ if idioma == "en": strclienteup = "CUSTOMER:" strcliente = "Customer" else: strclienteup = "CLIENTE:" strcliente = "Cliente" datos_c = [Spacer(1, 1*cm), Paragraph(strclienteup, estilos["Heading2"])] estilo_datos_c = ParagraphStyle(strcliente, parent = estilos["Heading2"]) estilo_datos_c.alignment = enums.TA_LEFT estilo_datos_c.spaceAfter = estilo_datos_c.spaceBefore = 2 #estilo_datos_c.leftIndent = 0.5*cm filas_cliente = [] if datos_cliente: try: datos_cliente[0] = "<strong>%s</strong>" % datos_cliente[0] except TypeError: datos_cliente = ["<strong>%s</strong>" % datos_cliente[0]] \ + list(datos_cliente[1:]) tamanno_predeterminado = estilo_datos_c.fontSize for linea in datos_cliente: # ¡Esto debería hacerlo ReportLab, pero no sé por qué el markup # sólo funciona con el estilo normal! if "<strong>" in linea: estilo_datos_c.fontSize += 4 else: estilo_datos_c.fontSize = tamanno_predeterminado p = Paragraph(escribe(linea), estilo_datos_c) filas_cliente.append([p]) tabla = Table(filas_cliente) tabla.setStyle(TableStyle([ ("BOX", (0, 0), (-1, -1), 1.0, colors.black) ])) datos_c.append(tabla) datos_c.append(Spacer(1, 1*cm)) return datos_c
def print_tabla(c, medidas, medidas_tabla): y0 = medidas["ldvs"][1] y1 = y0 - medidas_tabla["hcab"] # Cabecera c.saveState() c.setFillColorRGB(1, 1, 1) geninformes.rectangulo( c, (medidas_tabla["xnumalb"], y0), (medidas_tabla["xdesc"], y1), geninformes.escribe("Nº Albarán"), alinTxtX="centro", alinTxtY="centro", color_relleno=(0, 0.5, 0), ) geninformes.rectangulo( c, (medidas_tabla["xdesc"], y0), (medidas_tabla["xfecha"], y1), geninformes.escribe("Descripción"), alinTxtX="centro", alinTxtY="centro", color_relleno=(0, 0.5, 0), ) geninformes.rectangulo( c, (medidas_tabla["xfecha"], y0), (medidas_tabla["xkgs"], y1), geninformes.escribe("Fecha"), alinTxtX="centro", alinTxtY="centro", color_relleno=(0, 0.5, 0), ) geninformes.rectangulo( c, (medidas_tabla["xkgs"], y0), (medidas_tabla["ximporte"], y1), geninformes.escribe("Kg y Precio"), alinTxtX="centro", alinTxtY="centro", color_relleno=(0, 0.5, 0), ) geninformes.rectangulo( c, (medidas_tabla["ximporte"], y0), (medidas["ldvs"][2], y1), geninformes.escribe("Importe"), alinTxtX="centro", alinTxtY="centro", color_relleno=(0, 0.5, 0), ) c.restoreState() # Líneas verticales c.line(medidas["ldvs"][0], medidas["ldvs"][1], medidas["ldvs"][0], medidas["ldvs"][3]) c.line(medidas["ldvs"][2], medidas["ldvs"][1], medidas["ldvs"][2], medidas["ldvs"][3]) # Líneas horizontales c.line(medidas["ldvs"][0], medidas["ldvs"][3], medidas["ldvs"][2], medidas["ldvs"][3]) # Total c.saveState() c.setFont("Helvetica-Bold", 12) c.restoreState()