table-renderer 0.2.0__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {table_renderer-0.2.0 → table_renderer-0.4.0}/PKG-INFO +7 -5
- {table_renderer-0.2.0 → table_renderer-0.4.0}/README.md +6 -4
- {table_renderer-0.2.0 → table_renderer-0.4.0}/pyproject.toml +1 -1
- {table_renderer-0.2.0 → table_renderer-0.4.0}/src/table_renderer/__init__.py +1 -1
- {table_renderer-0.2.0 → table_renderer-0.4.0}/src/table_renderer/models/__init__.py +1 -2
- {table_renderer-0.2.0 → table_renderer-0.4.0}/src/table_renderer/models/cell.py +1 -1
- {table_renderer-0.2.0 → table_renderer-0.4.0}/src/table_renderer/models/column.py +1 -1
- {table_renderer-0.2.0 → table_renderer-0.4.0}/src/table_renderer/models/row.py +1 -1
- {table_renderer-0.2.0 → table_renderer-0.4.0}/src/table_renderer/models/style.py +91 -1
- {table_renderer-0.2.0 → table_renderer-0.4.0}/src/table_renderer/models/table.py +23 -6
- {table_renderer-0.2.0 → table_renderer-0.4.0}/src/table_renderer/renderer.py +23 -21
- table_renderer-0.2.0/src/table_renderer/models/base.py +0 -93
- {table_renderer-0.2.0 → table_renderer-0.4.0}/src/table_renderer/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: table-renderer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A Python library for rendering structured tables as high-quality images or HTML.
|
|
5
5
|
Keywords: table,renderer,rendering,image,html,weasyprint,pdfium,report
|
|
6
6
|
Author: pTaunium
|
|
@@ -44,7 +44,7 @@ Description-Content-Type: text/markdown
|
|
|
44
44
|
- **Auto-Crop**: Automatically crops images to the actual table area using visual detection, eliminating unnecessary white space.
|
|
45
45
|
- **Continuous Long Tables**: Automatically stitches multiple PDF pages into a single continuous long image, preventing content from being cut off.
|
|
46
46
|
- **Object-Oriented API**: Clean `Table` -> `Row/Column` -> `Cell` hierarchy with fluent interface support.
|
|
47
|
-
- **Cascading Styles**: Manage visual styles effortlessly with
|
|
47
|
+
- **Cascading Styles**: Manage visual styles effortlessly with logical precedence: `Cell` > `Row` > `Column` > `Table`.
|
|
48
48
|
- **Multi-language Font Support**: Support for font stacks (e.g., different fonts for English and Chinese).
|
|
49
49
|
- **Customizable Resolution**: Adjustable DPI for high-resolution output (e.g., 300 DPI for print).
|
|
50
50
|
- **Lightweight Deployment**: No heavy browser dependencies (like Chromium), making it ideal for Docker/K8s.
|
|
@@ -82,7 +82,6 @@ from table_renderer import Table
|
|
|
82
82
|
|
|
83
83
|
# 1. Initialize a 3x3 table
|
|
84
84
|
table = Table(3, 3)
|
|
85
|
-
table.set_width(600)
|
|
86
85
|
table.set_border(width=1, color="black", style="solid")
|
|
87
86
|
|
|
88
87
|
# 2. Set header style (Row 0)
|
|
@@ -105,8 +104,8 @@ table.cell(2, 2).set_text("$79")
|
|
|
105
104
|
# 4. Global column styling (align prices to the right)
|
|
106
105
|
table.get_column(2).set_align(horizontal="right").set_width(100)
|
|
107
106
|
|
|
108
|
-
# 5. Export to image with custom DPI and
|
|
109
|
-
table.to_image("report.png", dpi=300, padding=20)
|
|
107
|
+
# 5. Export to image with custom DPI, padding, and background color
|
|
108
|
+
table.to_image("report.png", dpi=300, padding=20, background_color="white")
|
|
110
109
|
```
|
|
111
110
|
|
|
112
111
|
---
|
|
@@ -174,6 +173,9 @@ Fine-tune your output image quality and margins.
|
|
|
174
173
|
# High-res JPG with custom 20px padding
|
|
175
174
|
table.to_image("output.jpg", dpi=300, padding=20)
|
|
176
175
|
|
|
176
|
+
# PNG with a solid white background (instead of the default transparent)
|
|
177
|
+
table.to_image("output_white.png", background_color="white")
|
|
178
|
+
|
|
177
179
|
# Lightweight WebP with tight margins
|
|
178
180
|
table.to_image("output.webp", dpi=72, padding=0)
|
|
179
181
|
```
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
- **Auto-Crop**: Automatically crops images to the actual table area using visual detection, eliminating unnecessary white space.
|
|
22
22
|
- **Continuous Long Tables**: Automatically stitches multiple PDF pages into a single continuous long image, preventing content from being cut off.
|
|
23
23
|
- **Object-Oriented API**: Clean `Table` -> `Row/Column` -> `Cell` hierarchy with fluent interface support.
|
|
24
|
-
- **Cascading Styles**: Manage visual styles effortlessly with
|
|
24
|
+
- **Cascading Styles**: Manage visual styles effortlessly with logical precedence: `Cell` > `Row` > `Column` > `Table`.
|
|
25
25
|
- **Multi-language Font Support**: Support for font stacks (e.g., different fonts for English and Chinese).
|
|
26
26
|
- **Customizable Resolution**: Adjustable DPI for high-resolution output (e.g., 300 DPI for print).
|
|
27
27
|
- **Lightweight Deployment**: No heavy browser dependencies (like Chromium), making it ideal for Docker/K8s.
|
|
@@ -59,7 +59,6 @@ from table_renderer import Table
|
|
|
59
59
|
|
|
60
60
|
# 1. Initialize a 3x3 table
|
|
61
61
|
table = Table(3, 3)
|
|
62
|
-
table.set_width(600)
|
|
63
62
|
table.set_border(width=1, color="black", style="solid")
|
|
64
63
|
|
|
65
64
|
# 2. Set header style (Row 0)
|
|
@@ -82,8 +81,8 @@ table.cell(2, 2).set_text("$79")
|
|
|
82
81
|
# 4. Global column styling (align prices to the right)
|
|
83
82
|
table.get_column(2).set_align(horizontal="right").set_width(100)
|
|
84
83
|
|
|
85
|
-
# 5. Export to image with custom DPI and
|
|
86
|
-
table.to_image("report.png", dpi=300, padding=20)
|
|
84
|
+
# 5. Export to image with custom DPI, padding, and background color
|
|
85
|
+
table.to_image("report.png", dpi=300, padding=20, background_color="white")
|
|
87
86
|
```
|
|
88
87
|
|
|
89
88
|
---
|
|
@@ -151,6 +150,9 @@ Fine-tune your output image quality and margins.
|
|
|
151
150
|
# High-res JPG with custom 20px padding
|
|
152
151
|
table.to_image("output.jpg", dpi=300, padding=20)
|
|
153
152
|
|
|
153
|
+
# PNG with a solid white background (instead of the default transparent)
|
|
154
|
+
table.to_image("output_white.png", background_color="white")
|
|
155
|
+
|
|
154
156
|
# Lightweight WebP with tight margins
|
|
155
157
|
table.to_image("output.webp", dpi=72, padding=0)
|
|
156
158
|
```
|
|
@@ -6,6 +6,6 @@ try:
|
|
|
6
6
|
__version__ = importlib.metadata.version("table-renderer")
|
|
7
7
|
except importlib.metadata.PackageNotFoundError:
|
|
8
8
|
# Package is not installed (e.g. during local development without pip install -e .)
|
|
9
|
-
__version__ = "0.
|
|
9
|
+
__version__ = "0.4.0"
|
|
10
10
|
|
|
11
11
|
__all__ = ["Cell", "Column", "Row", "Style", "StyledObject", "Table", "__version__"]
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
from .base import StyledObject
|
|
2
1
|
from .cell import Cell
|
|
3
2
|
from .column import Column
|
|
4
3
|
from .row import Row
|
|
5
|
-
from .style import Style
|
|
4
|
+
from .style import Style, StyledObject
|
|
6
5
|
from .table import Table
|
|
7
6
|
|
|
8
7
|
__all__ = ["Cell", "Column", "Row", "Style", "StyledObject", "Table"]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
|
-
from typing import Literal
|
|
2
|
+
from typing import Literal, Self
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
@dataclass
|
|
@@ -105,3 +105,93 @@ class Style:
|
|
|
105
105
|
if style:
|
|
106
106
|
css.append(f"border-{side}-style: {style};")
|
|
107
107
|
return css
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class StyledObject:
|
|
111
|
+
"""Base class for objects that can be styled."""
|
|
112
|
+
|
|
113
|
+
def __init__(self) -> None:
|
|
114
|
+
"""Initialize with a default Style."""
|
|
115
|
+
self.style = Style()
|
|
116
|
+
|
|
117
|
+
def set_font(
|
|
118
|
+
self,
|
|
119
|
+
*,
|
|
120
|
+
size: int | None = None,
|
|
121
|
+
color: str | None = None,
|
|
122
|
+
family: str | None = None,
|
|
123
|
+
weight: Literal["normal", "bold"] | None = None,
|
|
124
|
+
) -> Self:
|
|
125
|
+
"""
|
|
126
|
+
Set font related styles.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
size: Font size in pixels.
|
|
130
|
+
color: Text color (e.g., 'red', '#ff0000').
|
|
131
|
+
family: Font family or font stack.
|
|
132
|
+
weight: 'normal' or 'bold'.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
The object itself for chaining.
|
|
136
|
+
"""
|
|
137
|
+
self.style.font_size = size or self.style.font_size
|
|
138
|
+
self.style.font_color = color or self.style.font_color
|
|
139
|
+
self.style.font_family = family or self.style.font_family
|
|
140
|
+
self.style.font_weight = weight or self.style.font_weight
|
|
141
|
+
return self
|
|
142
|
+
|
|
143
|
+
def set_background(self, color: str) -> Self:
|
|
144
|
+
"""
|
|
145
|
+
Set the background color.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
color: Background color.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
The object itself for chaining.
|
|
152
|
+
"""
|
|
153
|
+
self.style.bg_color = color
|
|
154
|
+
return self
|
|
155
|
+
|
|
156
|
+
def set_align(
|
|
157
|
+
self,
|
|
158
|
+
*,
|
|
159
|
+
horizontal: Literal["left", "center", "right"] | None = None,
|
|
160
|
+
vertical: Literal["top", "middle", "bottom"] | None = None,
|
|
161
|
+
) -> Self:
|
|
162
|
+
"""
|
|
163
|
+
Set text alignment.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
horizontal: Horizontal alignment.
|
|
167
|
+
vertical: Vertical alignment.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
The object itself for chaining.
|
|
171
|
+
"""
|
|
172
|
+
self.style.text_align = horizontal or self.style.text_align
|
|
173
|
+
self.style.vertical_align = vertical or self.style.vertical_align
|
|
174
|
+
return self
|
|
175
|
+
|
|
176
|
+
def set_border(
|
|
177
|
+
self,
|
|
178
|
+
*,
|
|
179
|
+
width: int | None = None,
|
|
180
|
+
color: str | None = None,
|
|
181
|
+
style: Literal["solid", "dashed", "dotted"] | None = None,
|
|
182
|
+
) -> Self:
|
|
183
|
+
"""
|
|
184
|
+
Set border styles.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
width: Border width in pixels.
|
|
188
|
+
color: Border color.
|
|
189
|
+
style: Border style.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
The object itself for chaining.
|
|
193
|
+
"""
|
|
194
|
+
self.style.border_width = width or self.style.border_width
|
|
195
|
+
self.style.border_color = color or self.style.border_color
|
|
196
|
+
self.style.border_style = style or self.style.border_style
|
|
197
|
+
return self
|
|
@@ -2,10 +2,10 @@ from typing import Self
|
|
|
2
2
|
|
|
3
3
|
from table_renderer.renderer import render_to_image, save_html
|
|
4
4
|
|
|
5
|
-
from .base import StyledObject
|
|
6
5
|
from .cell import Cell
|
|
7
6
|
from .column import Column
|
|
8
7
|
from .row import Row
|
|
8
|
+
from .style import StyledObject
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class Table(StyledObject):
|
|
@@ -25,7 +25,7 @@ class Table(StyledObject):
|
|
|
25
25
|
self._cells = [[Cell() for _ in range(cols)] for _ in range(rows)]
|
|
26
26
|
self._row_objects = [Row(i) for i in range(rows)]
|
|
27
27
|
self._col_objects = [Column(i) for i in range(cols)]
|
|
28
|
-
self.width: int | str = "
|
|
28
|
+
self.width: int | str = "auto"
|
|
29
29
|
self.font_files: list[str] = []
|
|
30
30
|
|
|
31
31
|
def cell(self, row_index: int, col_index: int) -> Cell:
|
|
@@ -112,7 +112,14 @@ class Table(StyledObject):
|
|
|
112
112
|
self.font_files.append(font_path)
|
|
113
113
|
return self
|
|
114
114
|
|
|
115
|
-
def to_image(
|
|
115
|
+
def to_image(
|
|
116
|
+
self,
|
|
117
|
+
output_path: str,
|
|
118
|
+
*,
|
|
119
|
+
dpi: int = 144,
|
|
120
|
+
padding: int = 10,
|
|
121
|
+
background_color: str = "transparent",
|
|
122
|
+
) -> None:
|
|
116
123
|
"""
|
|
117
124
|
Render the table to an image file.
|
|
118
125
|
|
|
@@ -120,17 +127,27 @@ class Table(StyledObject):
|
|
|
120
127
|
output_path: Path to the output file (e.g., 'table.png', 'table.webp').
|
|
121
128
|
dpi: Resolution of the output image.
|
|
122
129
|
padding: Padding around the table in pixels.
|
|
130
|
+
background_color: Background color of the image.
|
|
123
131
|
"""
|
|
124
|
-
render_to_image(
|
|
132
|
+
render_to_image(
|
|
133
|
+
self,
|
|
134
|
+
output_path,
|
|
135
|
+
dpi=dpi,
|
|
136
|
+
padding=padding,
|
|
137
|
+
background_color=background_color,
|
|
138
|
+
)
|
|
125
139
|
|
|
126
|
-
def to_html(
|
|
140
|
+
def to_html(
|
|
141
|
+
self, output_path: str, *, background_color: str = "transparent"
|
|
142
|
+
) -> None:
|
|
127
143
|
"""
|
|
128
144
|
Export the table to an HTML file.
|
|
129
145
|
|
|
130
146
|
Args:
|
|
131
147
|
output_path: Path to the output HTML file.
|
|
148
|
+
background_color: Background color of the HTML body.
|
|
132
149
|
"""
|
|
133
|
-
save_html(self, output_path)
|
|
150
|
+
save_html(self, output_path, background_color=background_color)
|
|
134
151
|
|
|
135
152
|
def _prepare_render(self) -> None:
|
|
136
153
|
"""Handle merging logic and cascading styles before rendering."""
|
|
@@ -19,7 +19,7 @@ HTML_TEMPLATE = """
|
|
|
19
19
|
body {
|
|
20
20
|
margin: 0;
|
|
21
21
|
padding: 20px;
|
|
22
|
-
background-color:
|
|
22
|
+
background-color: {{ background_color }};
|
|
23
23
|
}
|
|
24
24
|
{% for font in font_faces %}
|
|
25
25
|
@font-face {
|
|
@@ -37,6 +37,7 @@ table {
|
|
|
37
37
|
td {
|
|
38
38
|
padding: 8px;
|
|
39
39
|
box-sizing: border-box;
|
|
40
|
+
{{ table_style }}
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
{% for col in columns %}
|
|
@@ -60,10 +61,10 @@ td {
|
|
|
60
61
|
{% for c_idx in range(cells[r_idx]|length) %}
|
|
61
62
|
{% set cell = cells[r_idx][c_idx] %}
|
|
62
63
|
{% if not cell.is_merged %}
|
|
63
|
-
<td class="col-{{ c_idx }}"
|
|
64
|
+
<td class="row-{{ r_idx }} col-{{ c_idx }}"
|
|
64
65
|
rowspan="{{ cell.row_span }}"
|
|
65
66
|
colspan="{{ cell.col_span }}"
|
|
66
|
-
style="{{ cell.
|
|
67
|
+
style="{{ cell.style.to_css() }}">
|
|
67
68
|
{% if cell.image_url %}
|
|
68
69
|
<img src="{{ cell.image_url }}"
|
|
69
70
|
style="{% if cell.image_width %}width: {{ cell.image_width }}px;{% endif %}
|
|
@@ -82,12 +83,13 @@ td {
|
|
|
82
83
|
"""
|
|
83
84
|
|
|
84
85
|
|
|
85
|
-
def render_to_html(table: "Table") -> str:
|
|
86
|
+
def render_to_html(table: "Table", *, background_color: str = "transparent") -> str:
|
|
86
87
|
"""
|
|
87
88
|
Generate the HTML representation of the table.
|
|
88
89
|
|
|
89
90
|
Args:
|
|
90
91
|
table: The Table object to render.
|
|
92
|
+
background_color: The background color of the body.
|
|
91
93
|
|
|
92
94
|
Returns:
|
|
93
95
|
A string containing the complete HTML document.
|
|
@@ -107,12 +109,6 @@ def render_to_html(table: "Table") -> str:
|
|
|
107
109
|
row_data = []
|
|
108
110
|
for col_index in range(len(table._cells[0])):
|
|
109
111
|
cell = table._cells[row_index][col_index]
|
|
110
|
-
row = table.get_row(row_index)
|
|
111
|
-
col = table.get_column(col_index)
|
|
112
|
-
|
|
113
|
-
# Cascading: Table -> Row/Col -> Cell
|
|
114
|
-
base_style = table.style.merge(col.style).merge(row.style)
|
|
115
|
-
final_style = base_style.merge(cell.style)
|
|
116
112
|
|
|
117
113
|
# Handle Image URL resolution
|
|
118
114
|
cell.image_url = ""
|
|
@@ -123,8 +119,6 @@ def render_to_html(table: "Table") -> str:
|
|
|
123
119
|
abs_img_path = os.path.abspath(cell.image_path)
|
|
124
120
|
cell.image_url = f"file://{abs_img_path}"
|
|
125
121
|
|
|
126
|
-
# Attach final style string for template
|
|
127
|
-
cell.final_style = final_style.to_css()
|
|
128
122
|
row_data.append(cell)
|
|
129
123
|
cells_data.append(row_data)
|
|
130
124
|
|
|
@@ -151,6 +145,7 @@ def render_to_html(table: "Table") -> str:
|
|
|
151
145
|
return template.render(
|
|
152
146
|
page_width=estimated_width,
|
|
153
147
|
page_height=estimated_height,
|
|
148
|
+
background_color=background_color,
|
|
154
149
|
table_width=f"{table.width}px" if isinstance(table.width, int) else table.width,
|
|
155
150
|
table_style=table.style.to_css(),
|
|
156
151
|
font_faces=font_faces,
|
|
@@ -175,6 +170,7 @@ def render_to_image(
|
|
|
175
170
|
*,
|
|
176
171
|
dpi: int = 144,
|
|
177
172
|
padding: int = 10,
|
|
173
|
+
background_color: str = "transparent",
|
|
178
174
|
) -> None:
|
|
179
175
|
"""
|
|
180
176
|
Render the table to an image file.
|
|
@@ -184,8 +180,9 @@ def render_to_image(
|
|
|
184
180
|
output_path: Destination path for the image.
|
|
185
181
|
dpi: Target resolution.
|
|
186
182
|
padding: Margin around the table.
|
|
183
|
+
background_color: Background color of the image.
|
|
187
184
|
"""
|
|
188
|
-
html_content = render_to_html(table)
|
|
185
|
+
html_content = render_to_html(table, background_color=background_color)
|
|
189
186
|
# WeasyPrint v53+ removed write_png, so we render to PDF then convert to PNG
|
|
190
187
|
pdf_bytes = HTML(string=html_content).write_pdf()
|
|
191
188
|
|
|
@@ -220,17 +217,19 @@ def render_to_image(
|
|
|
220
217
|
y_offset += img.height
|
|
221
218
|
|
|
222
219
|
# Visual Auto-Crop: Find the bounding box of non-white pixels
|
|
223
|
-
#
|
|
224
|
-
bg = Image.new("RGB", pil_image.size, (255, 255, 255))
|
|
220
|
+
# Use 'L' (grayscale) mode to reduce memory usage (1 byte per pixel vs 3)
|
|
225
221
|
if pil_image.mode == "RGBA":
|
|
226
|
-
|
|
222
|
+
# Flatten RGBA onto a white grayscale background
|
|
223
|
+
grayscale = Image.new("L", pil_image.size, 255)
|
|
224
|
+
grayscale.paste(pil_image.convert("L"), mask=pil_image.getchannel("A"))
|
|
227
225
|
else:
|
|
228
|
-
|
|
226
|
+
# For RGB or other modes, just convert to grayscale
|
|
227
|
+
grayscale = pil_image.convert("L")
|
|
229
228
|
|
|
230
|
-
#
|
|
229
|
+
# Invert and find bbox of "ink" (non-white pixels)
|
|
231
230
|
import PIL.ImageOps
|
|
232
231
|
|
|
233
|
-
inverted = PIL.ImageOps.invert(
|
|
232
|
+
inverted = PIL.ImageOps.invert(grayscale)
|
|
234
233
|
bbox = inverted.getbbox()
|
|
235
234
|
|
|
236
235
|
if bbox:
|
|
@@ -252,14 +251,17 @@ def render_to_image(
|
|
|
252
251
|
pil_image.save(output_path)
|
|
253
252
|
|
|
254
253
|
|
|
255
|
-
def save_html(
|
|
254
|
+
def save_html(
|
|
255
|
+
table: "Table", output_path: str, *, background_color: str = "transparent"
|
|
256
|
+
) -> None:
|
|
256
257
|
"""
|
|
257
258
|
Save the table's HTML representation to a file.
|
|
258
259
|
|
|
259
260
|
Args:
|
|
260
261
|
table: The Table object to export.
|
|
261
262
|
output_path: Path to the destination HTML file.
|
|
263
|
+
background_color: Background color of the HTML body.
|
|
262
264
|
"""
|
|
263
|
-
html_content = render_to_html(table)
|
|
265
|
+
html_content = render_to_html(table, background_color=background_color)
|
|
264
266
|
with open(output_path, "w", encoding="utf-8") as f:
|
|
265
267
|
f.write(html_content)
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
from typing import Literal, Self
|
|
2
|
-
|
|
3
|
-
from .style import Style
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class StyledObject:
|
|
7
|
-
"""Base class for objects that can be styled."""
|
|
8
|
-
|
|
9
|
-
def __init__(self) -> None:
|
|
10
|
-
"""Initialize with a default Style."""
|
|
11
|
-
self.style = Style()
|
|
12
|
-
|
|
13
|
-
def set_font(
|
|
14
|
-
self,
|
|
15
|
-
*,
|
|
16
|
-
size: int | None = None,
|
|
17
|
-
color: str | None = None,
|
|
18
|
-
family: str | None = None,
|
|
19
|
-
weight: Literal["normal", "bold"] | None = None,
|
|
20
|
-
) -> Self:
|
|
21
|
-
"""
|
|
22
|
-
Set font related styles.
|
|
23
|
-
|
|
24
|
-
Args:
|
|
25
|
-
size: Font size in pixels.
|
|
26
|
-
color: Text color (e.g., 'red', '#ff0000').
|
|
27
|
-
family: Font family or font stack.
|
|
28
|
-
weight: 'normal' or 'bold'.
|
|
29
|
-
|
|
30
|
-
Returns:
|
|
31
|
-
The object itself for chaining.
|
|
32
|
-
"""
|
|
33
|
-
self.style.font_size = size or self.style.font_size
|
|
34
|
-
self.style.font_color = color or self.style.font_color
|
|
35
|
-
self.style.font_family = family or self.style.font_family
|
|
36
|
-
self.style.font_weight = weight or self.style.font_weight
|
|
37
|
-
return self
|
|
38
|
-
|
|
39
|
-
def set_background(self, color: str) -> Self:
|
|
40
|
-
"""
|
|
41
|
-
Set the background color.
|
|
42
|
-
|
|
43
|
-
Args:
|
|
44
|
-
color: Background color.
|
|
45
|
-
|
|
46
|
-
Returns:
|
|
47
|
-
The object itself for chaining.
|
|
48
|
-
"""
|
|
49
|
-
self.style.bg_color = color
|
|
50
|
-
return self
|
|
51
|
-
|
|
52
|
-
def set_align(
|
|
53
|
-
self,
|
|
54
|
-
*,
|
|
55
|
-
horizontal: Literal["left", "center", "right"] | None = None,
|
|
56
|
-
vertical: Literal["top", "middle", "bottom"] | None = None,
|
|
57
|
-
) -> Self:
|
|
58
|
-
"""
|
|
59
|
-
Set text alignment.
|
|
60
|
-
|
|
61
|
-
Args:
|
|
62
|
-
horizontal: Horizontal alignment.
|
|
63
|
-
vertical: Vertical alignment.
|
|
64
|
-
|
|
65
|
-
Returns:
|
|
66
|
-
The object itself for chaining.
|
|
67
|
-
"""
|
|
68
|
-
self.style.text_align = horizontal or self.style.text_align
|
|
69
|
-
self.style.vertical_align = vertical or self.style.vertical_align
|
|
70
|
-
return self
|
|
71
|
-
|
|
72
|
-
def set_border(
|
|
73
|
-
self,
|
|
74
|
-
*,
|
|
75
|
-
width: int | None = None,
|
|
76
|
-
color: str | None = None,
|
|
77
|
-
style: Literal["solid", "dashed", "dotted"] | None = None,
|
|
78
|
-
) -> Self:
|
|
79
|
-
"""
|
|
80
|
-
Set border styles.
|
|
81
|
-
|
|
82
|
-
Args:
|
|
83
|
-
width: Border width in pixels.
|
|
84
|
-
color: Border color.
|
|
85
|
-
style: Border style.
|
|
86
|
-
|
|
87
|
-
Returns:
|
|
88
|
-
The object itself for chaining.
|
|
89
|
-
"""
|
|
90
|
-
self.style.border_width = width or self.style.border_width
|
|
91
|
-
self.style.border_color = color or self.style.border_color
|
|
92
|
-
self.style.border_style = style or self.style.border_style
|
|
93
|
-
return self
|
|
File without changes
|