B4J Question [PyBridge] Dynamic use؟؟؟

behnam_tr

Active Member
Licensed User
Longtime User
**Hello,**

For example, I want to generate a PDF file:
1. I create an object.
2. I add a page.
3. I add text to the page.
4. I add a table.
5. I add another line of text.
6. I generate the file.

I want the code to be dynamic and I can run it wherever needed, not a fixed code to generate the file.

In fact, what I mean is that in one report there may be only one table in the report or in another report there may be a table + chart and in another report there may be only empty text with a logo in the report.
How to use a Python code dynamically
I hope you understand what I mean

I don't want to write a fixed code to generate each report. I'll probably create 100 different types of reports within the program.Each report has different content and structure.

Python:
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors

# --- Function 1: Create a new PDF object ---
def create_pdf_object(filename):
    """Initialize a PDF canvas with Letter page size."""
    pdf = canvas.Canvas(filename, pagesize=letter)
    return pdf

# --- Function 2: Add a new page with a title ---
def add_page(pdf, title="New Page"):
    """Add a title to the current page."""
    pdf.setFont("Helvetica-Bold", 14)
    pdf.drawString(100, 750, title)  # Position (x=100, y=750)
    pdf.setFont("Helvetica", 12)  # Reset font for content
    return pdf

# --- Function 3: Add text to the page ---
def add_text(pdf, text, x=100, y=700):
    """Draw text at specified coordinates."""
    pdf.drawString(x, y, text)
    return pdf

# --- Function 4: Add a table ---
def add_table(pdf, data, x=100, y=600):
    """Create a table from a 2D list and style it."""
    table = Table(data)
    table.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, 0), colors.grey),  # Header row
        ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
        ('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # Center-align all cells
        ('GRID', (0, 0), (-1, -1), 1, colors.black)  # Add borders
    ]))
    table.wrapOn(pdf, 400, 200)  # Set table dimensions
    table.drawOn(pdf, x, y)  # Position the table
    return pdf

# --- Function 5: Save the PDF ---
def save_pdf(pdf):
    """Save and close the PDF file."""
    pdf.save()
    print("✅ PDF generated successfully!")
 
Last edited:

behnam_tr

Active Member
Licensed User
Longtime User
The only solution that comes to my mind is to create a pdf object in this example and save it on the b4j side, then call any function from Python, pass the object to it, and then perform the operation and return it to b4j until I finally reach the savepdf function.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Maybe have global dictionary for the pdf files, then you just add to it when you create, and remove when you save (or better when you save_finished) in case you want to save part way through.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
something like (not tested and needs error checking for names etc in dict)

Python:
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle
from reportlab.lib import colors

pdf_files = {}

# --- Function 1: Create a new PDF object ---
def create_pdf_object(filename):
    """Initialize a PDF canvas with Letter page size."""
    global pdf_files
    pdf = canvas.Canvas(filename, pagesize=letter)
    pdf_files[filename] = pdf
    return pdf

# --- Function 2: Add a new page with a title ---
def add_page(filename, title="New Page"):
    """Add a title to the current page."""
    global pdf_files
    pdf = pdf_files[filename]
    pdf.setFont("Helvetica-Bold", 14)
    pdf.drawString(100, 750, title)  # Position (x=100, y=750)
    pdf.setFont("Helvetica", 12)  # Reset font for content
    return pdf

# --- Function 3: Add text to the page ---
def add_text(filename, text, x=100, y=700):
    """Draw text at specified coordinates."""
    global pdf_files
    pdf = pdf_files[filename]
    pdf.drawString(x, y, text)
    return pdf

# --- Function 4: Add a table ---
def add_table(filename, data, x=100, y=600):
    """Create a table from a 2D list and style it."""
    global pdf_files
    pdf = pdf_files[filename]
    table = Table(data)
    table.setStyle(TableStyle([
        ('BACKGROUND', (0, 0), (-1, 0), colors.grey),  # Header row
        ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
        ('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # Center-align all cells
        ('GRID', (0, 0), (-1, -1), 1, colors.black)  # Add borders
    ]))
    table.wrapOn(pdf, 400, 200)  # Set table dimensions
    table.drawOn(pdf, x, y)  # Position the table
    return pdf

# --- Function 5: Save the PDF ---
def save_pdf(filename):
    """Save and close the PDF file."""
    global pdf_files
    pdf = pdf_files[filename]
    pdf.save()
    print("✅ PDF generated successfully!")
    del pdf_files[filename]
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
The only solution that comes to my mind is to create a pdf object in this example and save it on the b4j side, then call any function from Python, pass the object to it, and then perform the operation and return it to b4j until I finally reach the savepdf function.
This is a good solution. It is also quite simple.
 
Upvote 0
Top