Skip to main content

A Python library for rendering structured tables as high-quality images or HTML.

Project description

Table Renderer 📊

English | 繁體中文

License: MIT Python Version CI codecov

table-renderer is a powerful and lightweight Python library designed to convert structured tables into high-quality images (PNG, JPG, WebP) or HTML. By combining the layout power of CSS with an intuitive Python API, it's perfect for automated reporting, Kubernetes CronJobs, or any data visualization task.

✨ Features

  • Broad Compatibility: Fully supports Python 3.12, 3.13, and 3.14.
  • Business Friendly: Uses pypdfium2 (Apache-2.0) and WeasyPrint for a 100% MIT-compatible dependency chain.
  • High-Quality Rendering: Powered by WeasyPrint (CSS engine), supporting complex text wrapping, alignment, and cell merging.
  • Auto-Crop: Automatically crops images to the actual table area using visual detection, eliminating unnecessary white space.
  • Continuous Long Tables: Automatically stitches multiple PDF pages into a single continuous long image, preventing content from being cut off.
  • Object-Oriented API: Clean Table -> Row/Column -> Cell hierarchy with fluent interface support.
  • Cascading Styles: Manage visual styles effortlessly with logical precedence: Cell > Row > Column > Table.
  • Multi-language Font Support: Support for font stacks (e.g., different fonts for English and Chinese).
  • Customizable Resolution: Adjustable DPI for high-resolution output (e.g., 300 DPI for print).
  • Lightweight Deployment: No heavy browser dependencies (like Chromium), making it ideal for Docker/K8s.

🖼 Visual Example

Here is an example table generated using the code in the Quick Start section:

Example Table


🚀 Quick Start

Installation

If you are developing within this project, use uv:

uv sync

To install it in another project:

pip install .

Basic Usage

from table_renderer import Table

# 1. Initialize a 3x3 table
table = Table(3, 3)
table.set_border(width=1, color="black", style="solid")
table.set_width(400)

# 2. Set header style (Row 0)
header = table.get_row(0)
header.set_background("#333").set_font(color="white", weight="bold", size=16)
header.set_align(horizontal="center")

table.cell(0, 0).set_text("Product")
table.cell(0, 1).set_text("Category")
table.cell(0, 2).set_text("Price")

# 3. Add content and demonstrate merging
table.cell(1, 0).set_text("MacBook Pro").set_span(rows=1, cols=2)
table.cell(1, 2).set_text("$2,000")

table.cell(2, 0).set_text("Magic Mouse")
table.cell(2, 1).set_text("Peripherals")
table.cell(2, 2).set_text("$79")

# 4. Global column styling (align prices to the right)
table.get_column(2).set_align(horizontal="right").set_width(100)

# 5. Export to image with custom DPI, padding, and background color
table.to_image("report.png", dpi=300, padding=20, background_color="white")

🛠 Advanced Features

1. Cell Merging

Use the anchor-based design to merge cells by specifying the starting cell and the span.

# Merge first row, first two columns (1 row, 2 columns)
table.cell(0, 0).set_span(rows=1, cols=2).set_text("Merged Header")

2. Font Management

Load local font files and define font stacks for character-level fallback.

# Load local font files (.ttf / .otf)
table.add_font("./fonts/Roboto-Regular.ttf")
table.add_font("./fonts/NotoSansTC-Medium.otf")

# Define a font stack: English prefers Roboto, Chinese falls back to Noto Sans
table.set_font(family="Roboto-Regular, NotoSansTC-Medium")

3. Embedding Images in Cells

You can embed both local images and remote URLs into any cell.

# Set a local image
table.cell(1, 0).set_image("path/to/logo.png", width=50)

# Set a remote image URL
table.cell(1, 1).set_image("https://example.com/image.jpg", width=100)

4. Layout & Sizing

Mix fixed widths, heights, percentages, and auto-sizing.

table.set_width(800)                  # Total table width
table.get_column(0).set_width(200)    # Fixed column width (200px)
table.get_column(1).set_width("auto") # Distribute remaining space
table.get_row(0).set_height(100)      # Fixed row height (100px)

Handling Extremely Wide Tables: The library dynamically estimates canvas width to prevent clipping. However, if your table contains unbreakable strings (like long URLs) and relies purely on auto-layout, you can manually override the canvas width. The auto-crop feature will automatically trim any excess white space.

# Force a massive canvas width; auto-crop will cleanly trim the excess
table.set_width(15000)
table.to_image("wide_table.png")

5. DPI, Formats & Padding

Fine-tune your output image quality and margins.

# High-res JPG with custom 20px padding
table.to_image("output.jpg", dpi=300, padding=20)

# PNG with a solid white background (instead of the default transparent)
table.to_image("output_white.png", background_color="white")

# Lightweight WebP with tight margins
table.to_image("output.webp", dpi=72, padding=0)

🐳 Docker / Kubernetes Deployment

Since weasyprint relies on system-level C libraries, your Dockerfile should include these dependencies:

FROM python:3.12-slim

# Install system dependencies for WeasyPrint rendering and fonts
RUN apt-get update && apt-get install -y --no-install-recommends \
    libpango-1.0-0 \
    libpangoft2-1.0-0 \
    libharfbuzz-subset0 \
    fonts-noto-cjk \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY . .
RUN pip install .

CMD ["python", "main.py"]

🧪 Development

Running Tests

We use pytest for testing. Ensure you have installed the development dependencies.

uv run pytest --cov=src/table_renderer tests/

Linting & Formatting

We use ruff to maintain code quality.

uv run ruff check .
uv run ruff format .

🤝 Contributing

Contributions are welcome! If you find a bug or have a feature request, please open an issue or submit a pull request.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📜 License

Distributed under the MIT License. See LICENSE for more information.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

table_renderer-0.5.0.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

table_renderer-0.5.0-py3-none-any.whl (19.2 kB view details)

Uploaded Python 3

File details

Details for the file table_renderer-0.5.0.tar.gz.

File metadata

  • Download URL: table_renderer-0.5.0.tar.gz
  • Upload date:
  • Size: 14.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for table_renderer-0.5.0.tar.gz
Algorithm Hash digest
SHA256 771fd49172f61a8547707f5a5be4168627524461da6c3764658b09649d67ef00
MD5 388674a34573804050edcdd3f70543a3
BLAKE2b-256 25deeadd7b35743500970d621dcd01d25821d1d3203d30dcd4d9a9a230602446

See more details on using hashes here.

File details

Details for the file table_renderer-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: table_renderer-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 19.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.20 {"installer":{"name":"uv","version":"0.11.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for table_renderer-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 604b5bb98755165416df10fa62f73d9beddda25e81178d8278f5ea3a65fa441f
MD5 4a26552da78e10825b81324023e8a258
BLAKE2b-256 ff85fb2bfd6b7493c69e920b99c96e0d06ed7f4f1d00629152987f5b4e9a8577

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page