Skip to content

Instantly share code, notes, and snippets.

@spinningcat
Created March 4, 2026 09:34
Show Gist options
  • Select an option

  • Save spinningcat/91c2155addf215bfe189009c54086046 to your computer and use it in GitHub Desktop.

Select an option

Save spinningcat/91c2155addf215bfe189009c54086046 to your computer and use it in GitHub Desktop.
html_lines.append('<!DOCTYPE html><html><body style="margin: 0; padding: 15px; background-color: #ffffff;">')
# 1. Targets (Wrapped for Outlook Compatibility)
target_pill_style = "display: inline-block; padding: 4px 12px; margin-right: 8px; border: 1px solid #ddd; font-family: 'Segoe UI', sans-serif;"
html_lines.append('<div style="margin-bottom: 15px;">')
html_lines.append(f'')
html_lines.append(f'<div style="{target_pill_style}"><b>Daily:</b> {daily_t}</div>')
html_lines.append(f'')
html_lines.append(f'<div style="{target_pill_style}"><b>Monthly:</b> {monthly_t}</div>')
html_lines.append(f'')
html_lines.append(f'<div style="{target_pill_style}"><b>Yearly:</b> {yearly_t}</div>')
html_lines.append('')
html_lines.append('</div>')
# 2. The Scrolling Table (Bella's Scroll Pattern)
# Capped at 600px for Outlook safety; horizontal scroll for modern clients
html_lines.append('<div class="scroll-container" style="width: 100%; max-width: 1500px; overflow-x: auto; -ms-overflow-style: none;">')
# table-layout: fixed is critical for the "Squares" to stay square
html_lines.append('<table border="0" cellspacing="0" cellpadding="0" width="1000" style="table-layout: fixed; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt;">')
# Headers
html_lines.append('<tr style="background-color: #fcfcfc;">')
name_h = ws.cell(header_row, 2).value or "Name"
html_lines.append(f'<td style="{base_td_style} {name_col_style} text-align:left; color:#0078d4; font-weight: bold;">{name_h}</td>')
for col in range(3, max_col + 1):
v = ws.cell(header_row, col).value or ""
html_lines.append(f'<td style="{base_td_style} width: 70px; text-align: center; font-weight: bold; color: #0078d4;">{v}</td>')
html_lines.append('</tr>')
# Data Rows
for row in range(data_start, data_end + 1):
if not ws.cell(row, 2).value: continue
html_lines.append('<tr>')
val, style = get_cell_attrs(row, 2, is_name_col=True)
html_lines.append(f'<td style="{style}">{val}</td>')
for col in range(3, max_col + 1):
val, style = get_cell_attrs(row, col)
html_lines.append(f'<td style="{style}">{val}</td>')
html_lines.append('</tr>')
# Total Row
if total_row:
html_lines.append('<tr>')
val, style = get_cell_attrs(total_row, 2, is_name_col=True)
total_style = f"{style} font-weight:bold; border-top: 2px solid #0078d4;"
html_lines.append(f'<td style="{total_style}">{val}</td>')
for col in range(3, max_col + 1):
val, style = get_cell_attrs(total_row, col)
total_data_style = f"{style} font-weight:bold; border-top: 2px solid #0078d4;"
html_lines.append(f'<td style="{total_data_style}">{val}</td>')
html_lines.append('</tr>')
html_lines.append('</table>')
html_lines.append('</div></body></html>')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment