319 lines
8.8 KiB
Python
319 lines
8.8 KiB
Python
#!/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()
|