Foros Python

Versión completa: Saltos de línea reportLab
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Buenas:

Sigo aquí con mi app que está adquiriendo unas dimesiones bastante más serias de lo que planeaba pero bueno. Ahora mismo estoy intentando pasar los datos que se escriben en la app a un pdf(Para lo que leí el artículo publicado aquí mismo en esta web sobre ReportLab).

En principio todo va bien, excepto que no tengo muy claro como hacer para que divida el texto cuando este es más largo que el ancho de la página del pdf. (Es decir como añadir un salto de línea (\n) cada vez que el texto supere el márgen de la página). Tal y como lo tengo funciona pero no respeta los márgenes del documento (Es un A4 y si el texto es muy largo simplemente lo saca fuera del documento y no es posible leerlo.

Si necesitais que ponga el ejemplo lo pongo aunque es un poco largo y por alguna razón cuando hago copia y pega, no me respeta aquí la identación.

Uso Tkinter con el widget Text para escribir el texto largo pero como ya digo cuando lo intentó pasar a pdf con reportLab no respeta el tamaño A4 que le tengo asignado.
Hola, ¿cómo estás?

Si estás usando la función drawString() como explica el artículo Crear documentos PDF en Python con ReportLab, efectivamente no se pueden crear saltos de línea. La única forma es dividir manualmente el texto en líneas y por cada una de ellas hacer una llamada a drawString().

El tema es que ReportLab es una librería gigantesca y ese artículo solamente explica una API básica y de muy bajo nivel, aunque en muchos casos suficiente. La forma más sencilla de dibujar textos con saltos de línea es usando reportlab.platypus.Paragraph. Ejemplo:

Código:
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import ParagraphStyle
from reportlab.platypus import SimpleDocTemplate
from reportlab.platypus import Paragraph

doc = SimpleDocTemplate(
    "hola-mundo.pdf",
    pagesize=A4
)
paragraph = Paragraph(
    "Hola mundo.<br />Esto aparece en otra línea.",
    ParagraphStyle(
        "ps1",
        fontName="Times-Roman",
        fontSize=11
    )
)
doc.build([paragraph])

En un Paragraph, como en HTML, los saltos de línea se representan vía <br />.

Si ya tenés el texto en una variable con los saltos de línea incluidos, podés hacer simplemente:

Código:
paragraph = Paragraph(
    texto.replace("
", "&#x3C;br /&#x3E;"),
    ParagraphStyle(
        "ps1",
        fontName="Times-Roman",
        fontSize=11
    )
)

Saludos!
(18-03-2020, 08:17 PM)Francisco escribió: [ -> ]Hola, ¿cómo estás?

Si estás usando la función drawString() como explica el artículo Crear documentos PDF en Python con ReportLab, efectivamente no se pueden crear saltos de línea. La única forma es dividir manualmente el texto en líneas y por cada una de ellas hacer una llamada a drawString().

El tema es que ReportLab es una librería gigantesca y ese artículo solamente explica una API básica y de muy bajo nivel, aunque en muchos casos suficiente. La forma más sencilla de dibujar textos con saltos de línea es usando reportlab.platypus.Paragraph. Ejemplo:

Código:
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import ParagraphStyle
from reportlab.platypus import SimpleDocTemplate
from reportlab.platypus import Paragraph

doc = SimpleDocTemplate(
    "hola-mundo.pdf",
    pagesize=A4
)
paragraph = Paragraph(
    "Hola mundo.&#x3C;br /&#x3E;Esto aparece en otra línea.",
    ParagraphStyle(
        "ps1",
        fontName="Times-Roman",
        fontSize=11
    )
)
doc.build([paragraph])

En un Paragraph, como en HTML, los saltos de línea se representan vía <br />.

Si ya tenés el texto en una variable con los saltos de línea incluidos, podés hacer simplemente:

Código:
paragraph = Paragraph(
    texto.replace("
", "&#x3C;br /&#x3E;"),
    ParagraphStyle(
        "ps1",
        fontName="Times-Roman",
        fontSize=11
    )
)

Saludos!
¡MUCHAS GRACIAS!. Creo que lo que yo busco es un poco más "enrevesado". He simplificado el ejemplo para que lo veas:

Código:
from tkinter import *
from tkinter import ttk
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
import subprocess

class App:
       
        def __init__(self):
           
            self.win = Tk()
            self.win.title("PruebasPdf")
            self.win.geometry('400x400')
            
            def creapdfpau():
               
                self.pdfcanvasab1 = canvas.Canvas("/home/juan/Documents/pruebapdf.pdf", pagesize=A4)
                self.pdfcanvasab1.setFillColorRGB(255,0,0)
                self.pdfcanvasab1.setFont("Helvetica-Bold", 40)
                self.pdfcanvasab1.drawString(240, 800, "PRUEBA")

                def pdfpau():
                   
                    self.pdfcanvasab1.setFillColorRGB(0,0,0)
                    self.pdfcanvasab1.setFont("Helvetica", 10)
                    self.pdfcanvasab1.drawString(30, 760, str(self.text1.get(1.0, END).upper()))

                pdfpau():

                self.pdfcanvasab1.save()

                def abrirpdfpau():
                    p = subprocess.Popen(["evince /home/juan/Documents/pruebapdf.pdf"], shell=True)
                abrirpdfpau()

            self.lab1 = ttk.Label(self.win, text='COMENTARIOS')
            self.lab1.grid(row=0, column=0)

            self.text1 = Text(self.win, height=3, cursor='pencil',font=14, width=30)
            self.text1.grid(row=1, column=0, padx=5, pady=5)

            self.but = ttk.Button(self.win, text= 'Tpdf', command=creapdfpau)
            self.but.grid(row=2, column=0, padx=5)

            self.win.mainloop()

def main():
     my_app = App()

if __name__ == '__main__':
     main()

Cuando llenas el widget Text con un texto que ocupa las tres líneas al pasarlo al pdf se sale por el borde derecho y no se puede leer. Mi idea es que lo divida en varías líneas para que quede dentro del documento pdf y sea legible.

Una vez más he de decir que funcionar, funciona correctamente todo. Ah, ni caso al subprocess. (Lo tengo puesto para poder ver el resultado del programa)

Muchas Gracias.
Hola. Es precisamente lo que decía en el mensaje anterior. En tu código estás usando (línea 26) la función drawString(), que no soporta saltos de línea. Deberías cambiarlo por un Paragraph.

Saludos
Muchas Gracias de nuevo Francisco.

Me he bajado un manual para ReportLab porque lo de Paragrahp es bastante más complejo de lo que parecía (ya que tengo que poner el párrafo en una posición concreta y aún no he visto como hacerlo. (Yo solo buscaba algo sencillito). De momento lo voy solucionando con un tamaño de letra menor y así entra bastante más texto. (Tampoco voy a necesitar mucho más).