This commit is contained in:
parent
496f3bf334
commit
9bc9c96e14
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 26 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 119 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 117 KiB |
@ -7,9 +7,9 @@ This example demonstrates rendering HTML tables:
|
||||
- Tables with multiple rows and columns
|
||||
- Tables with colspan and borders
|
||||
- Tables with formatted content
|
||||
- Tables parsed from HTML
|
||||
- Tables parsed from HTML using DocumentLayouter
|
||||
|
||||
Shows the TableRenderer system in action.
|
||||
Shows the HTML-first rendering pipeline.
|
||||
"""
|
||||
|
||||
import sys
|
||||
@ -20,8 +20,9 @@ from PIL import Image, ImageDraw
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from pyWebLayout.concrete.page import Page
|
||||
from pyWebLayout.concrete.table import TableRenderer, TableStyle
|
||||
from pyWebLayout.concrete.table import TableStyle
|
||||
from pyWebLayout.style.page_style import PageStyle
|
||||
from pyWebLayout.layout.document_layouter import DocumentLayouter
|
||||
from pyWebLayout.io.readers.html_extraction import parse_html_string
|
||||
from pyWebLayout.style import Font
|
||||
from pyWebLayout.abstract.block import Table
|
||||
@ -179,7 +180,7 @@ def create_data_table_example():
|
||||
|
||||
|
||||
def render_table_example(html: str, title: str, style_variant: int = 0, page_size=(500, 400)):
|
||||
"""Render a table from HTML to an image."""
|
||||
"""Render a table from HTML to an image using DocumentLayouter."""
|
||||
# Create page with varying backgrounds
|
||||
bg_colors = [
|
||||
(255, 255, 255), # White
|
||||
@ -196,17 +197,6 @@ def render_table_example(html: str, title: str, style_variant: int = 0, page_siz
|
||||
)
|
||||
|
||||
page = Page(size=page_size, style=page_style)
|
||||
image = page.render()
|
||||
draw = ImageDraw.Draw(image)
|
||||
|
||||
# Add title
|
||||
from PIL import ImageFont
|
||||
try:
|
||||
title_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 14)
|
||||
except:
|
||||
title_font = ImageFont.load_default()
|
||||
|
||||
draw.text((page.border_size + 10, page.border_size + 10), title, fill=(50, 50, 150), font=title_font)
|
||||
|
||||
# Parse HTML to get table
|
||||
base_font = Font(font_size=12)
|
||||
@ -219,8 +209,7 @@ def render_table_example(html: str, title: str, style_variant: int = 0, page_siz
|
||||
table = block
|
||||
break
|
||||
|
||||
if table:
|
||||
# Create table renderer with different styles
|
||||
# Table styles with different themes
|
||||
table_styles = [
|
||||
# Style 0: Classic blue header
|
||||
TableStyle(
|
||||
@ -262,24 +251,24 @@ def render_table_example(html: str, title: str, style_variant: int = 0, page_siz
|
||||
|
||||
table_style = table_styles[style_variant % len(table_styles)]
|
||||
|
||||
# Position table below title
|
||||
table_origin = (page.border_size + 10, page.border_size + 40)
|
||||
table_width = page.content_size[0] - 20
|
||||
if table:
|
||||
# Create DocumentLayouter
|
||||
layouter = DocumentLayouter(page)
|
||||
|
||||
renderer = TableRenderer(
|
||||
table,
|
||||
table_origin,
|
||||
table_width,
|
||||
draw,
|
||||
table_style
|
||||
)
|
||||
# Use DocumentLayouter to layout the table
|
||||
layouter.layout_table(table, style=table_style)
|
||||
|
||||
renderer.render()
|
||||
# Get the rendered canvas
|
||||
_ = page.draw # Ensure canvas exists
|
||||
image = page._canvas
|
||||
else:
|
||||
# Draw "No table found" message
|
||||
# No table found - create empty page
|
||||
_ = page.draw # Ensure canvas exists
|
||||
draw = ImageDraw.Draw(page._canvas)
|
||||
draw.text((page.border_size + 10, page.border_size + 50),
|
||||
"No table found in HTML",
|
||||
fill=(200, 0, 0), font=title_font)
|
||||
fill=(200, 0, 0))
|
||||
image = page._canvas
|
||||
|
||||
return image
|
||||
|
||||
|
||||
@ -254,7 +254,7 @@ def main():
|
||||
# Save output
|
||||
output_dir = Path("docs/images")
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_path = output_dir / "example_06_html_table_with_images.png"
|
||||
output_path = output_dir / "example_05_html_table_with_images.png"
|
||||
combined.save(output_path)
|
||||
|
||||
print(f"\n✓ Example completed!")
|
||||
@ -1,252 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Table with Images Example
|
||||
|
||||
This example demonstrates rendering tables with images:
|
||||
- Creating tables programmatically
|
||||
- Adding images to table cells
|
||||
- Book catalog / product showcase tables
|
||||
- Mixed content (images and text) in cells
|
||||
|
||||
Uses the cover images from tests/data directory.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
# Add pyWebLayout to path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
from pyWebLayout.concrete.page import Page
|
||||
from pyWebLayout.style.page_style import PageStyle
|
||||
from pyWebLayout.concrete.table import TableRenderer, TableStyle
|
||||
from pyWebLayout.abstract.block import Table, Image as AbstractImage
|
||||
from pyWebLayout.abstract.inline import Word
|
||||
from pyWebLayout.style import Font
|
||||
|
||||
|
||||
def create_book_catalog_table(cover_images: dict):
|
||||
"""Create a book catalog table with cover images and details."""
|
||||
print(" - Creating book catalog table...")
|
||||
|
||||
# Get base path for images
|
||||
data_path = Path(__file__).parent.parent / "tests" / "data"
|
||||
|
||||
# Create table
|
||||
table = Table(caption="Book Catalog", style=Font(font_size=14))
|
||||
|
||||
# Header row
|
||||
header = table.create_row("header")
|
||||
header.create_cell(is_header=True).create_paragraph().add_word(Word("Cover", Font(font_size=12)))
|
||||
header.create_cell(is_header=True).create_paragraph().add_word(Word("Title", Font(font_size=12)))
|
||||
header.create_cell(is_header=True).create_paragraph().add_word(Word("Author", Font(font_size=12)))
|
||||
header.create_cell(is_header=True).create_paragraph().add_word(Word("Price", Font(font_size=12)))
|
||||
|
||||
# Book entries
|
||||
books = [
|
||||
("cover 1.png", "The Great Adventure", "John Smith", "$19.99"),
|
||||
("cover 2.png", "Mystery of the Ages", "Jane Doe", "$24.99"),
|
||||
("cover 3.png", "Science Today", "Dr. Brown", "$29.99"),
|
||||
("cover 4.png", "Art & Design", "M. Artist", "$34.99"),
|
||||
]
|
||||
|
||||
for cover_file, title, author, price in books:
|
||||
row = table.create_row("body")
|
||||
|
||||
# Cover cell with actual Image block
|
||||
cover_cell = row.create_cell()
|
||||
if cover_file in cover_images:
|
||||
cover_path = str(data_path / cover_file)
|
||||
AbstractImage.create_and_add_to(cover_cell, source=cover_path, alt_text=title)
|
||||
|
||||
# Title cell
|
||||
title_cell = row.create_cell()
|
||||
title_para = title_cell.create_paragraph()
|
||||
for word in title.split():
|
||||
title_para.add_word(Word(word, Font(font_size=11)))
|
||||
|
||||
# Author cell
|
||||
author_cell = row.create_cell()
|
||||
author_para = author_cell.create_paragraph()
|
||||
for word in author.split():
|
||||
author_para.add_word(Word(word, Font(font_size=11)))
|
||||
|
||||
# Price cell
|
||||
price_cell = row.create_cell()
|
||||
price_para = price_cell.create_paragraph()
|
||||
price_para.add_word(Word(price, Font(font_size=11, weight="bold")))
|
||||
|
||||
return table
|
||||
|
||||
|
||||
def create_product_showcase_table(cover_images: dict):
|
||||
"""Create a product showcase table."""
|
||||
print(" - Creating product showcase table...")
|
||||
|
||||
# Get base path for images
|
||||
data_path = Path(__file__).parent.parent / "tests" / "data"
|
||||
|
||||
table = Table(caption="Product Showcase", style=Font(font_size=14))
|
||||
|
||||
# Header row
|
||||
header = table.create_row("header")
|
||||
header.create_cell(is_header=True).create_paragraph().add_word(Word("Product", Font(font_size=12)))
|
||||
header.create_cell(is_header=True).create_paragraph().add_word(Word("Description", Font(font_size=12)))
|
||||
|
||||
# Products with covers
|
||||
products = [
|
||||
("cover 1.png", "Premium Edition - Hardcover with gold embossing"),
|
||||
("cover 2.png", "Collector's Item - Limited print run"),
|
||||
]
|
||||
|
||||
for cover_file, description in products:
|
||||
row = table.create_row("body")
|
||||
|
||||
# Product cell with actual Image block
|
||||
product_cell = row.create_cell()
|
||||
if cover_file in cover_images:
|
||||
cover_path = str(data_path / cover_file)
|
||||
AbstractImage.create_and_add_to(product_cell, source=cover_path, alt_text="Product cover")
|
||||
|
||||
# Description cell
|
||||
desc_cell = row.create_cell()
|
||||
desc_para = desc_cell.create_paragraph()
|
||||
for word in description.split():
|
||||
desc_para.add_word(Word(word, Font(font_size=10)))
|
||||
|
||||
return table
|
||||
|
||||
|
||||
def render_table_with_images(table: Table, title: str, style_variant: int = 0,
|
||||
page_size=(600, 500)):
|
||||
"""Render a table with images using the library API."""
|
||||
# Create page
|
||||
page_style = PageStyle(
|
||||
border_width=2,
|
||||
border_color=(180, 180, 180),
|
||||
padding=(20, 20, 20, 20),
|
||||
background_color=(255, 255, 255)
|
||||
)
|
||||
|
||||
page = Page(size=page_size, style=page_style)
|
||||
canvas = page.render()
|
||||
draw = ImageDraw.Draw(canvas)
|
||||
|
||||
# Add title
|
||||
try:
|
||||
title_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 16)
|
||||
except:
|
||||
title_font = ImageFont.load_default()
|
||||
|
||||
draw.text((page.border_size + 10, page.border_size + 10), title, fill=(50, 50, 150), font=title_font)
|
||||
|
||||
# Table styles
|
||||
table_styles = [
|
||||
TableStyle(
|
||||
border_width=1,
|
||||
border_color=(100, 100, 100),
|
||||
cell_padding=(8, 10, 8, 10),
|
||||
header_bg_color=(70, 130, 180),
|
||||
cell_bg_color=(255, 255, 255),
|
||||
alternate_row_color=(245, 248, 250)
|
||||
),
|
||||
TableStyle(
|
||||
border_width=2,
|
||||
border_color=(60, 120, 60),
|
||||
cell_padding=(10, 12, 10, 12),
|
||||
header_bg_color=(144, 238, 144),
|
||||
cell_bg_color=(255, 255, 255),
|
||||
alternate_row_color=(240, 255, 240)
|
||||
),
|
||||
]
|
||||
|
||||
table_style = table_styles[style_variant % len(table_styles)]
|
||||
|
||||
# Position table
|
||||
table_origin = (page.border_size + 10, page.border_size + 45)
|
||||
table_width = page.content_size[0] - 20
|
||||
|
||||
# Render table with canvas support for images
|
||||
renderer = TableRenderer(
|
||||
table,
|
||||
table_origin,
|
||||
table_width,
|
||||
draw,
|
||||
table_style,
|
||||
canvas # Pass canvas to enable image rendering
|
||||
)
|
||||
renderer.render()
|
||||
|
||||
return canvas
|
||||
|
||||
|
||||
def main():
|
||||
"""Demonstrate tables with images."""
|
||||
print("Table with Images Example")
|
||||
print("=" * 50)
|
||||
|
||||
# Load cover images
|
||||
print("\n Loading cover images...")
|
||||
cover_images = {}
|
||||
data_path = Path(__file__).parent.parent / "tests" / "data"
|
||||
|
||||
for i in range(1, 5):
|
||||
cover_path = data_path / f"cover {i}.png"
|
||||
if cover_path.exists():
|
||||
cover_images[f"cover {i}.png"] = Image.open(cover_path)
|
||||
print(f" ✓ Loaded cover {i}.png")
|
||||
|
||||
if not cover_images:
|
||||
print(" ✗ No cover images found!")
|
||||
return
|
||||
|
||||
# Create tables
|
||||
print("\n Creating tables...")
|
||||
book_table = create_book_catalog_table(cover_images)
|
||||
product_table = create_product_showcase_table(cover_images)
|
||||
|
||||
# Render tables
|
||||
print("\n Rendering tables with images...")
|
||||
print(" - Rendering book catalog...")
|
||||
book_image = render_table_with_images(
|
||||
book_table,
|
||||
"Book Catalog with Covers",
|
||||
style_variant=0,
|
||||
page_size=(700, 600)
|
||||
)
|
||||
|
||||
print(" - Rendering product showcase...")
|
||||
product_image = render_table_with_images(
|
||||
product_table,
|
||||
"Product Showcase",
|
||||
style_variant=1,
|
||||
page_size=(600, 350)
|
||||
)
|
||||
|
||||
# Combine images side by side
|
||||
print("\n Combining images...")
|
||||
padding = 20
|
||||
total_width = book_image.size[0] + product_image.size[0] + padding * 3
|
||||
total_height = max(book_image.size[1], product_image.size[1]) + padding * 2
|
||||
|
||||
combined = Image.new('RGB', (total_width, total_height), (240, 240, 240))
|
||||
combined.paste(book_image, (padding, padding))
|
||||
combined.paste(product_image, (book_image.size[0] + padding * 2, padding))
|
||||
|
||||
# Save output
|
||||
output_dir = Path("docs/images")
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_path = output_dir / "example_05_table_with_images.png"
|
||||
combined.save(output_path)
|
||||
|
||||
print(f"\n✓ Example completed!")
|
||||
print(f" Output saved to: {output_path}")
|
||||
print(f" Image size: {combined.size[0]}x{combined.size[1]} pixels")
|
||||
print(f" Used {len(cover_images)} cover images")
|
||||
|
||||
return combined
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -1,318 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Table with Images Example - HTML Output
|
||||
|
||||
This example demonstrates creating HTML tables with images:
|
||||
- Creating HTML tables programmatically
|
||||
- Embedding images in table cells
|
||||
- Book catalog / product showcase tables
|
||||
- Styled tables with CSS
|
||||
- Mixed content (images and text) in cells
|
||||
|
||||
Generates standalone HTML files with embedded images (base64).
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import base64
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
# Add pyWebLayout to path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
|
||||
def image_to_base64(image_path: Path) -> str:
|
||||
"""Convert image file to base64 string for HTML embedding."""
|
||||
with open(image_path, 'rb') as img_file:
|
||||
img_data = img_file.read()
|
||||
return base64.b64encode(img_data).decode('utf-8')
|
||||
|
||||
|
||||
def create_html_header(title: str) -> str:
|
||||
"""Create HTML document header with CSS styles."""
|
||||
return f"""<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{title}</title>
|
||||
<style>
|
||||
body {{
|
||||
font-family: 'DejaVu Sans', Arial, sans-serif;
|
||||
background-color: #f0f0f0;
|
||||
padding: 20px;
|
||||
margin: 0;
|
||||
}}
|
||||
|
||||
.container {{
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
background-color: white;
|
||||
padding: 30px;
|
||||
border: 2px solid #b4b4b4;
|
||||
border-radius: 5px;
|
||||
}}
|
||||
|
||||
h1 {{
|
||||
color: #323296;
|
||||
font-size: 24px;
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
}}
|
||||
|
||||
.table-container {{
|
||||
margin-bottom: 40px;
|
||||
}}
|
||||
|
||||
.table-title {{
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 15px;
|
||||
color: #333;
|
||||
}}
|
||||
|
||||
/* Blue style table */
|
||||
table.style-blue {{
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #646464;
|
||||
margin-bottom: 20px;
|
||||
}}
|
||||
|
||||
table.style-blue th {{
|
||||
background-color: #4682b4;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
border: 1px solid #646464;
|
||||
}}
|
||||
|
||||
table.style-blue td {{
|
||||
padding: 10px;
|
||||
border: 1px solid #646464;
|
||||
font-size: 11px;
|
||||
}}
|
||||
|
||||
table.style-blue tr:nth-child(even) {{
|
||||
background-color: #f5f8fa;
|
||||
}}
|
||||
|
||||
table.style-blue tr:nth-child(odd) {{
|
||||
background-color: white;
|
||||
}}
|
||||
|
||||
/* Green style table */
|
||||
table.style-green {{
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border: 2px solid #3c783c;
|
||||
margin-bottom: 20px;
|
||||
}}
|
||||
|
||||
table.style-green th {{
|
||||
background-color: #90ee90;
|
||||
color: #333;
|
||||
padding: 12px;
|
||||
text-align: left;
|
||||
font-size: 12px;
|
||||
border: 2px solid #3c783c;
|
||||
}}
|
||||
|
||||
table.style-green td {{
|
||||
padding: 12px;
|
||||
border: 2px solid #3c783c;
|
||||
font-size: 10px;
|
||||
}}
|
||||
|
||||
table.style-green tr:nth-child(even) {{
|
||||
background-color: #f0fff0;
|
||||
}}
|
||||
|
||||
table.style-green tr:nth-child(odd) {{
|
||||
background-color: white;
|
||||
}}
|
||||
|
||||
.cover-image {{
|
||||
max-width: 100px;
|
||||
height: auto;
|
||||
display: block;
|
||||
}}
|
||||
|
||||
.product-image {{
|
||||
max-width: 120px;
|
||||
height: auto;
|
||||
display: block;
|
||||
}}
|
||||
|
||||
.price {{
|
||||
font-weight: bold;
|
||||
}}
|
||||
|
||||
.footer {{
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>{title}</h1>
|
||||
"""
|
||||
|
||||
|
||||
def create_html_footer() -> str:
|
||||
"""Create HTML document footer."""
|
||||
return """
|
||||
<div class="footer">
|
||||
Generated by pyWebLayout - Table with Images Example (HTML Version)
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
def create_book_catalog_html(cover_images: Dict[str, str]) -> str:
|
||||
"""Create HTML for book catalog table with cover images."""
|
||||
books = [
|
||||
("cover 1.png", "The Great Adventure", "John Smith", "$19.99"),
|
||||
("cover 2.png", "Mystery of the Ages", "Jane Doe", "$24.99"),
|
||||
("cover 3.png", "Science Today", "Dr. Brown", "$29.99"),
|
||||
("cover 4.png", "Art & Design", "M. Artist", "$34.99"),
|
||||
]
|
||||
|
||||
html = '<div class="table-container">\n'
|
||||
html += ' <div class="table-title">Book Catalog</div>\n'
|
||||
html += ' <table class="style-blue">\n'
|
||||
html += ' <thead>\n'
|
||||
html += ' <tr>\n'
|
||||
html += ' <th>Cover</th>\n'
|
||||
html += ' <th>Title</th>\n'
|
||||
html += ' <th>Author</th>\n'
|
||||
html += ' <th>Price</th>\n'
|
||||
html += ' </tr>\n'
|
||||
html += ' </thead>\n'
|
||||
html += ' <tbody>\n'
|
||||
|
||||
for cover_file, title, author, price in books:
|
||||
html += ' <tr>\n'
|
||||
|
||||
# Cover cell
|
||||
html += ' <td>\n'
|
||||
if cover_file in cover_images:
|
||||
html += f' <img src="data:image/png;base64,{cover_images[cover_file]}" alt="{title}" class="cover-image">\n'
|
||||
html += ' </td>\n'
|
||||
|
||||
# Title cell
|
||||
html += f' <td>{title}</td>\n'
|
||||
|
||||
# Author cell
|
||||
html += f' <td>{author}</td>\n'
|
||||
|
||||
# Price cell
|
||||
html += f' <td class="price">{price}</td>\n'
|
||||
|
||||
html += ' </tr>\n'
|
||||
|
||||
html += ' </tbody>\n'
|
||||
html += ' </table>\n'
|
||||
html += '</div>\n'
|
||||
|
||||
return html
|
||||
|
||||
|
||||
def create_product_showcase_html(cover_images: Dict[str, str]) -> str:
|
||||
"""Create HTML for product showcase table."""
|
||||
products = [
|
||||
("cover 1.png", "Premium Edition - Hardcover with gold embossing"),
|
||||
("cover 2.png", "Collector's Item - Limited print run"),
|
||||
]
|
||||
|
||||
html = '<div class="table-container">\n'
|
||||
html += ' <div class="table-title">Product Showcase</div>\n'
|
||||
html += ' <table class="style-green">\n'
|
||||
html += ' <thead>\n'
|
||||
html += ' <tr>\n'
|
||||
html += ' <th>Product</th>\n'
|
||||
html += ' <th>Description</th>\n'
|
||||
html += ' </tr>\n'
|
||||
html += ' </thead>\n'
|
||||
html += ' <tbody>\n'
|
||||
|
||||
for cover_file, description in products:
|
||||
html += ' <tr>\n'
|
||||
|
||||
# Product cell with image
|
||||
html += ' <td>\n'
|
||||
if cover_file in cover_images:
|
||||
html += f' <img src="data:image/png;base64,{cover_images[cover_file]}" alt="Product cover" class="product-image">\n'
|
||||
html += ' </td>\n'
|
||||
|
||||
# Description cell
|
||||
html += f' <td>{description}</td>\n'
|
||||
|
||||
html += ' </tr>\n'
|
||||
|
||||
html += ' </tbody>\n'
|
||||
html += ' </table>\n'
|
||||
html += '</div>\n'
|
||||
|
||||
return html
|
||||
|
||||
|
||||
def main():
|
||||
"""Generate HTML tables with images."""
|
||||
print("Table with Images Example - HTML Version")
|
||||
print("=" * 50)
|
||||
|
||||
# Load cover images and convert to base64
|
||||
print("\n Loading and encoding cover images...")
|
||||
cover_images = {}
|
||||
data_path = Path(__file__).parent.parent / "tests" / "data"
|
||||
|
||||
for i in range(1, 5):
|
||||
cover_path = data_path / f"cover {i}.png"
|
||||
if cover_path.exists():
|
||||
try:
|
||||
cover_images[f"cover {i}.png"] = image_to_base64(cover_path)
|
||||
print(f" ✓ Loaded and encoded cover {i}.png")
|
||||
except Exception as e:
|
||||
print(f" ✗ Failed to load cover {i}.png: {e}")
|
||||
|
||||
if not cover_images:
|
||||
print(" ✗ No cover images found!")
|
||||
return
|
||||
|
||||
# Generate HTML content
|
||||
print("\n Generating HTML tables...")
|
||||
html_content = create_html_header("Table with Images - HTML Example")
|
||||
|
||||
print(" - Creating book catalog table...")
|
||||
html_content += create_book_catalog_html(cover_images)
|
||||
|
||||
print(" - Creating product showcase table...")
|
||||
html_content += create_product_showcase_html(cover_images)
|
||||
|
||||
html_content += create_html_footer()
|
||||
|
||||
# Save HTML output
|
||||
output_dir = Path("docs/html")
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_path = output_dir / "example_05_table_with_images.html"
|
||||
|
||||
with open(output_path, 'w', encoding='utf-8') as f:
|
||||
f.write(html_content)
|
||||
|
||||
print(f"\n✓ Example completed!")
|
||||
print(f" Output saved to: {output_path}")
|
||||
print(f" Used {len(cover_images)} cover images (embedded as base64)")
|
||||
print(f" Open the file in a web browser to view the tables")
|
||||
|
||||
return output_path
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
x
Reference in New Issue
Block a user