xlsxturbo 0.4.1__tar.gz → 0.7.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.
@@ -5,6 +5,49 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.7.0] - 2025-12-28
9
+
10
+ ### Added
11
+ - **Column formatting with wildcards** - `column_formats` parameter for styling columns by pattern
12
+ - Wildcard patterns: `prefix*`, `*suffix`, `*contains*`, or exact match
13
+ - Format options: `bg_color`, `font_color`, `num_format`, `bold`, `italic`, `underline`, `border`
14
+ - Example: `column_formats={'mcpt_*': {'bg_color': '#D6EAF8', 'num_format': '0.00000', 'border': True}}`
15
+ - Available in both `df_to_xlsx()` and `dfs_to_xlsx()`
16
+ - Per-sheet column formats via options dict in `dfs_to_xlsx()`
17
+
18
+ ## [0.6.0] - 2025-12-08
19
+
20
+ ### Added
21
+ - **Global column width cap** - `column_widths={'_all': 50}` to cap all columns at a maximum width
22
+ - Can be combined with specific column widths: `{0: 20, '_all': 50}` (specific overrides '_all')
23
+ - Works with autofit as a cap: `autofit=True, column_widths={'_all': 30}` fits then caps
24
+ - **Table name parameter** - `table_name="MyTable"` to set custom Excel table names
25
+ - Invalid characters are automatically sanitized (spaces/special chars become underscores)
26
+ - Names starting with digits get underscore prefix (Excel requirement)
27
+ - Per-sheet table names in `dfs_to_xlsx()` via options dict
28
+ - **Header styling** - `header_format={'bold': True, 'bg_color': '#4F81BD', 'font_color': 'white'}`
29
+ - Supported options: `bold`, `italic`, `font_color`, `bg_color`, `font_size`, `underline`
30
+ - Colors accept hex (`#RRGGBB`) or named colors (white, black, red, blue, etc.)
31
+ - Per-sheet header formats in `dfs_to_xlsx()` via options dict
32
+ - Per-sheet options now support: `table_name`, `header_format`, `column_widths` with '_all'
33
+
34
+ ### Changed
35
+ - `column_widths` parameter now accepts both integer keys (`{0: 20}`) and string keys (`{"_all": 50}`)
36
+
37
+ ## [0.5.0] - 2025-12-08
38
+
39
+ ### Added
40
+ - **Per-sheet options for `dfs_to_xlsx()`** - override global settings per sheet
41
+ - Each sheet can now be a 3-tuple: `(df, sheet_name, options_dict)`
42
+ - Options dict supports: `header`, `autofit`, `table_style`, `freeze_panes`, `column_widths`, `row_heights`
43
+ - Old 2-tuple API `(df, sheet_name)` still works (backward compatible)
44
+ - Example: `[(df1, "Data", {"table_style": "Medium2"}), (df2, "Instructions", {"header": False})]`
45
+ - `SheetOptions` TypedDict for type hints
46
+
47
+ ### Changed
48
+ - `dfs_to_xlsx()` signature now accepts mixed tuple formats internally
49
+ - Updated type stubs with new `SheetOptions` class and updated `dfs_to_xlsx` signature
50
+
8
51
  ## [0.4.1] - 2025-12-07
9
52
 
10
53
  ### Fixed
@@ -78,6 +121,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
78
121
  - Support for custom sheet names
79
122
  - Verbose mode for progress reporting
80
123
 
124
+ [0.7.0]: https://github.com/tstone-1/xlsxturbo/releases/tag/v0.7.0
125
+ [0.6.0]: https://github.com/tstone-1/xlsxturbo/releases/tag/v0.6.0
126
+ [0.5.0]: https://github.com/tstone-1/xlsxturbo/releases/tag/v0.5.0
81
127
  [0.4.1]: https://github.com/tstone-1/xlsxturbo/releases/tag/v0.4.1
82
128
  [0.4.0]: https://github.com/tstone-1/xlsxturbo/releases/tag/v0.4.0
83
129
  [0.3.0]: https://github.com/tstone-1/xlsxturbo/releases/tag/v0.3.0
@@ -90,15 +90,15 @@ checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
90
90
 
91
91
  [[package]]
92
92
  name = "bumpalo"
93
- version = "3.19.0"
93
+ version = "3.19.1"
94
94
  source = "registry+https://github.com/rust-lang/crates.io-index"
95
- checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
95
+ checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
96
96
 
97
97
  [[package]]
98
98
  name = "cc"
99
- version = "1.2.49"
99
+ version = "1.2.51"
100
100
  source = "registry+https://github.com/rust-lang/crates.io-index"
101
- checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215"
101
+ checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
102
102
  dependencies = [
103
103
  "find-msvc-tools",
104
104
  "shlex",
@@ -282,9 +282,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
282
282
 
283
283
  [[package]]
284
284
  name = "find-msvc-tools"
285
- version = "0.1.5"
285
+ version = "0.1.6"
286
286
  source = "registry+https://github.com/rust-lang/crates.io-index"
287
- checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
287
+ checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff"
288
288
 
289
289
  [[package]]
290
290
  name = "flate2"
@@ -371,9 +371,9 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
371
371
 
372
372
  [[package]]
373
373
  name = "itoa"
374
- version = "1.0.15"
374
+ version = "1.0.17"
375
375
  source = "registry+https://github.com/rust-lang/crates.io-index"
376
- checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
376
+ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
377
377
 
378
378
  [[package]]
379
379
  name = "js-sys"
@@ -451,15 +451,15 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
451
451
 
452
452
  [[package]]
453
453
  name = "portable-atomic"
454
- version = "1.11.1"
454
+ version = "1.13.0"
455
455
  source = "registry+https://github.com/rust-lang/crates.io-index"
456
- checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
456
+ checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950"
457
457
 
458
458
  [[package]]
459
459
  name = "proc-macro2"
460
- version = "1.0.103"
460
+ version = "1.0.104"
461
461
  source = "registry+https://github.com/rust-lang/crates.io-index"
462
- checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
462
+ checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0"
463
463
  dependencies = [
464
464
  "unicode-ident",
465
465
  ]
@@ -574,9 +574,9 @@ dependencies = [
574
574
 
575
575
  [[package]]
576
576
  name = "rustix"
577
- version = "1.1.2"
577
+ version = "1.1.3"
578
578
  source = "registry+https://github.com/rust-lang/crates.io-index"
579
- checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
579
+ checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
580
580
  dependencies = [
581
581
  "bitflags",
582
582
  "errno",
@@ -593,9 +593,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
593
593
 
594
594
  [[package]]
595
595
  name = "ryu"
596
- version = "1.0.20"
596
+ version = "1.0.22"
597
597
  source = "registry+https://github.com/rust-lang/crates.io-index"
598
- checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
598
+ checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"
599
599
 
600
600
  [[package]]
601
601
  name = "serde_core"
@@ -625,9 +625,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
625
625
 
626
626
  [[package]]
627
627
  name = "simd-adler32"
628
- version = "0.3.7"
628
+ version = "0.3.8"
629
629
  source = "registry+https://github.com/rust-lang/crates.io-index"
630
- checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
630
+ checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
631
631
 
632
632
  [[package]]
633
633
  name = "strsim"
@@ -654,9 +654,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
654
654
 
655
655
  [[package]]
656
656
  name = "tempfile"
657
- version = "3.23.0"
657
+ version = "3.24.0"
658
658
  source = "registry+https://github.com/rust-lang/crates.io-index"
659
- checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
659
+ checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c"
660
660
  dependencies = [
661
661
  "fastrand",
662
662
  "getrandom",
@@ -833,7 +833,7 @@ checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
833
833
 
834
834
  [[package]]
835
835
  name = "xlsxturbo"
836
- version = "0.4.1"
836
+ version = "0.7.0"
837
837
  dependencies = [
838
838
  "chrono",
839
839
  "clap",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "xlsxturbo"
3
- version = "0.4.1"
3
+ version = "0.7.0"
4
4
  edition = "2021"
5
5
  description = "High-performance Excel writer with automatic type detection (pandas, polars, CSV)"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xlsxturbo
3
- Version: 0.4.1
3
+ Version: 0.7.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: Intended Audience :: Science/Research
@@ -40,10 +40,13 @@ High-performance Excel writer with automatic type detection. Written in Rust, us
40
40
  - **Direct DataFrame support** for pandas and polars
41
41
  - **Excel tables** - filterable tables with 61 built-in styles (banded rows, autofilter)
42
42
  - **Auto-fit columns** - automatically adjust column widths to fit content
43
- - **Custom column widths** - set specific widths per column
43
+ - **Custom column widths** - set specific widths per column or cap all with _all
44
+ - **Header styling** - bold, colors, font size for header row
45
+ - **Named tables** - set custom table names
44
46
  - **Custom row heights** - set specific heights per row
45
47
  - **Freeze panes** - freeze header row for easier scrolling
46
48
  - **Multi-sheet workbooks** - write multiple DataFrames to one file
49
+ - **Per-sheet options** - override settings per sheet in multi-sheet workbooks
47
50
  - **Constant memory mode** - minimize RAM usage for very large files
48
51
  - **Parallel CSV processing** - optional multi-core parsing for large files
49
52
  - **Automatic type detection** from CSV strings and Python objects:
@@ -150,6 +153,83 @@ xlsxturbo.df_to_xlsx(df, "styled.xlsx",
150
153
  )
151
154
  ```
152
155
 
156
+ ### Global Column Width Cap
157
+
158
+ Use `column_widths={'_all': value}` to cap all columns at a maximum width:
159
+
160
+ ```python
161
+ import xlsxturbo
162
+ import pandas as pd
163
+
164
+ df = pd.DataFrame({
165
+ 'Name': ['Alice', 'Bob'],
166
+ 'VeryLongDescription': ['A' * 100, 'B' * 100],
167
+ 'Score': [95, 87]
168
+ })
169
+
170
+ # Cap all columns at 30 characters
171
+ xlsxturbo.df_to_xlsx(df, "capped.xlsx", column_widths={'_all': 30})
172
+
173
+ # Mix specific widths with global cap (specific overrides '_all')
174
+ xlsxturbo.df_to_xlsx(df, "mixed.xlsx", column_widths={0: 15, '_all': 30})
175
+
176
+ # Autofit with cap: fit content, but never exceed 25 characters
177
+ xlsxturbo.df_to_xlsx(df, "fitted.xlsx", autofit=True, column_widths={'_all': 25})
178
+ ```
179
+
180
+ ### Named Excel Tables
181
+
182
+ Set custom names for Excel tables:
183
+
184
+ ```python
185
+ import xlsxturbo
186
+ import pandas as pd
187
+
188
+ df = pd.DataFrame({'Product': ['A', 'B'], 'Price': [10, 20]})
189
+
190
+ # Name the Excel table
191
+ xlsxturbo.df_to_xlsx(df, "report.xlsx",
192
+ table_style="Medium2",
193
+ table_name="ProductPrices"
194
+ )
195
+
196
+ # Invalid characters are auto-sanitized, digits get underscore prefix
197
+ xlsxturbo.df_to_xlsx(df, "report.xlsx",
198
+ table_style="Medium2",
199
+ table_name="2024 Sales Data!" # Becomes "_2024_Sales_Data_"
200
+ )
201
+ ```
202
+
203
+ ### Header Styling
204
+
205
+ Apply custom formatting to header cells:
206
+
207
+ ```python
208
+ import xlsxturbo
209
+ import pandas as pd
210
+
211
+ df = pd.DataFrame({'Name': ['Alice', 'Bob'], 'Score': [95, 87]})
212
+
213
+ # Bold headers
214
+ xlsxturbo.df_to_xlsx(df, "bold.xlsx", header_format={'bold': True})
215
+
216
+ # Full styling with colors
217
+ xlsxturbo.df_to_xlsx(df, "styled.xlsx", header_format={
218
+ 'bold': True,
219
+ 'bg_color': '#4F81BD', # Blue background
220
+ 'font_color': 'white' # White text
221
+ })
222
+
223
+ # Available options:
224
+ # - bold (bool): Bold text
225
+ # - italic (bool): Italic text
226
+ # - font_color (str): '#RRGGBB' or named color (white, black, red, blue, etc.)
227
+ # - bg_color (str): Background color
228
+ # - font_size (float): Font size in points
229
+ # - underline (bool): Underlined text
230
+ ```
231
+
232
+
153
233
  ### Multi-Sheet Workbooks
154
234
 
155
235
  ```python
@@ -178,6 +258,42 @@ xlsxturbo.dfs_to_xlsx([
178
258
  ], "report.xlsx", column_widths={0: 20, 1: 15})
179
259
  ```
180
260
 
261
+ ### Per-Sheet Options
262
+
263
+ Override global settings for individual sheets using a 3-tuple with options dict:
264
+
265
+ ```python
266
+ import xlsxturbo
267
+ import pandas as pd
268
+
269
+ df_data = pd.DataFrame({'Product': ['A', 'B'], 'Price': [10, 20]})
270
+ df_instructions = pd.DataFrame({'Step': [1, 2], 'Action': ['Open file', 'Review data']})
271
+
272
+ # Different settings per sheet:
273
+ # - "Data" sheet: has header, table style, autofit
274
+ # - "Instructions" sheet: no header (raw data), no table style
275
+ xlsxturbo.dfs_to_xlsx([
276
+ (df_data, "Data", {"header": True, "table_style": "Medium2"}),
277
+ (df_instructions, "Instructions", {"header": False, "table_style": None})
278
+ ], "report.xlsx", autofit=True)
279
+
280
+ # Old 2-tuple API still works - uses global defaults
281
+ xlsxturbo.dfs_to_xlsx([
282
+ (df_data, "Sheet1"), # Uses global header=True, table_style=None
283
+ (df_instructions, "Sheet2", {"header": False}) # Override just header
284
+ ], "mixed.xlsx", header=True, autofit=True)
285
+ ```
286
+
287
+ Available per-sheet options:
288
+ - `header` (bool): Include column names as header row
289
+ - `autofit` (bool): Automatically adjust column widths
290
+ - `table_style` (str|None): Excel table style or None to disable
291
+ - `freeze_panes` (bool): Freeze header row
292
+ - `column_widths` (dict): Custom column widths
293
+ - `row_heights` (dict): Custom row heights
294
+ - `table_name` (str): Custom Excel table name
295
+ - `header_format` (dict): Header cell styling
296
+
181
297
  ### Constant Memory Mode (Large Files)
182
298
 
183
299
  For very large files (millions of rows), use `constant_memory=True` to minimize RAM usage:
@@ -7,10 +7,13 @@ High-performance Excel writer with automatic type detection. Written in Rust, us
7
7
  - **Direct DataFrame support** for pandas and polars
8
8
  - **Excel tables** - filterable tables with 61 built-in styles (banded rows, autofilter)
9
9
  - **Auto-fit columns** - automatically adjust column widths to fit content
10
- - **Custom column widths** - set specific widths per column
10
+ - **Custom column widths** - set specific widths per column or cap all with _all
11
+ - **Header styling** - bold, colors, font size for header row
12
+ - **Named tables** - set custom table names
11
13
  - **Custom row heights** - set specific heights per row
12
14
  - **Freeze panes** - freeze header row for easier scrolling
13
15
  - **Multi-sheet workbooks** - write multiple DataFrames to one file
16
+ - **Per-sheet options** - override settings per sheet in multi-sheet workbooks
14
17
  - **Constant memory mode** - minimize RAM usage for very large files
15
18
  - **Parallel CSV processing** - optional multi-core parsing for large files
16
19
  - **Automatic type detection** from CSV strings and Python objects:
@@ -117,6 +120,83 @@ xlsxturbo.df_to_xlsx(df, "styled.xlsx",
117
120
  )
118
121
  ```
119
122
 
123
+ ### Global Column Width Cap
124
+
125
+ Use `column_widths={'_all': value}` to cap all columns at a maximum width:
126
+
127
+ ```python
128
+ import xlsxturbo
129
+ import pandas as pd
130
+
131
+ df = pd.DataFrame({
132
+ 'Name': ['Alice', 'Bob'],
133
+ 'VeryLongDescription': ['A' * 100, 'B' * 100],
134
+ 'Score': [95, 87]
135
+ })
136
+
137
+ # Cap all columns at 30 characters
138
+ xlsxturbo.df_to_xlsx(df, "capped.xlsx", column_widths={'_all': 30})
139
+
140
+ # Mix specific widths with global cap (specific overrides '_all')
141
+ xlsxturbo.df_to_xlsx(df, "mixed.xlsx", column_widths={0: 15, '_all': 30})
142
+
143
+ # Autofit with cap: fit content, but never exceed 25 characters
144
+ xlsxturbo.df_to_xlsx(df, "fitted.xlsx", autofit=True, column_widths={'_all': 25})
145
+ ```
146
+
147
+ ### Named Excel Tables
148
+
149
+ Set custom names for Excel tables:
150
+
151
+ ```python
152
+ import xlsxturbo
153
+ import pandas as pd
154
+
155
+ df = pd.DataFrame({'Product': ['A', 'B'], 'Price': [10, 20]})
156
+
157
+ # Name the Excel table
158
+ xlsxturbo.df_to_xlsx(df, "report.xlsx",
159
+ table_style="Medium2",
160
+ table_name="ProductPrices"
161
+ )
162
+
163
+ # Invalid characters are auto-sanitized, digits get underscore prefix
164
+ xlsxturbo.df_to_xlsx(df, "report.xlsx",
165
+ table_style="Medium2",
166
+ table_name="2024 Sales Data!" # Becomes "_2024_Sales_Data_"
167
+ )
168
+ ```
169
+
170
+ ### Header Styling
171
+
172
+ Apply custom formatting to header cells:
173
+
174
+ ```python
175
+ import xlsxturbo
176
+ import pandas as pd
177
+
178
+ df = pd.DataFrame({'Name': ['Alice', 'Bob'], 'Score': [95, 87]})
179
+
180
+ # Bold headers
181
+ xlsxturbo.df_to_xlsx(df, "bold.xlsx", header_format={'bold': True})
182
+
183
+ # Full styling with colors
184
+ xlsxturbo.df_to_xlsx(df, "styled.xlsx", header_format={
185
+ 'bold': True,
186
+ 'bg_color': '#4F81BD', # Blue background
187
+ 'font_color': 'white' # White text
188
+ })
189
+
190
+ # Available options:
191
+ # - bold (bool): Bold text
192
+ # - italic (bool): Italic text
193
+ # - font_color (str): '#RRGGBB' or named color (white, black, red, blue, etc.)
194
+ # - bg_color (str): Background color
195
+ # - font_size (float): Font size in points
196
+ # - underline (bool): Underlined text
197
+ ```
198
+
199
+
120
200
  ### Multi-Sheet Workbooks
121
201
 
122
202
  ```python
@@ -145,6 +225,42 @@ xlsxturbo.dfs_to_xlsx([
145
225
  ], "report.xlsx", column_widths={0: 20, 1: 15})
146
226
  ```
147
227
 
228
+ ### Per-Sheet Options
229
+
230
+ Override global settings for individual sheets using a 3-tuple with options dict:
231
+
232
+ ```python
233
+ import xlsxturbo
234
+ import pandas as pd
235
+
236
+ df_data = pd.DataFrame({'Product': ['A', 'B'], 'Price': [10, 20]})
237
+ df_instructions = pd.DataFrame({'Step': [1, 2], 'Action': ['Open file', 'Review data']})
238
+
239
+ # Different settings per sheet:
240
+ # - "Data" sheet: has header, table style, autofit
241
+ # - "Instructions" sheet: no header (raw data), no table style
242
+ xlsxturbo.dfs_to_xlsx([
243
+ (df_data, "Data", {"header": True, "table_style": "Medium2"}),
244
+ (df_instructions, "Instructions", {"header": False, "table_style": None})
245
+ ], "report.xlsx", autofit=True)
246
+
247
+ # Old 2-tuple API still works - uses global defaults
248
+ xlsxturbo.dfs_to_xlsx([
249
+ (df_data, "Sheet1"), # Uses global header=True, table_style=None
250
+ (df_instructions, "Sheet2", {"header": False}) # Override just header
251
+ ], "mixed.xlsx", header=True, autofit=True)
252
+ ```
253
+
254
+ Available per-sheet options:
255
+ - `header` (bool): Include column names as header row
256
+ - `autofit` (bool): Automatically adjust column widths
257
+ - `table_style` (str|None): Excel table style or None to disable
258
+ - `freeze_panes` (bool): Freeze header row
259
+ - `column_widths` (dict): Custom column widths
260
+ - `row_heights` (dict): Custom row heights
261
+ - `table_name` (str): Custom Excel table name
262
+ - `header_format` (dict): Header cell styling
263
+
148
264
  ### Constant Memory Mode (Large Files)
149
265
 
150
266
  For very large files (millions of rows), use `constant_memory=True` to minimize RAM usage:
@@ -9,21 +9,21 @@ Features that would enable more migrations from pandas/polars write_excel.
9
9
  - [x] **Column auto-width** - Automatically fit column widths to content (v0.3.0)
10
10
  - [x] **Custom column widths** - Set specific widths per column (v0.4.0)
11
11
  - [x] **Custom row heights** - Set specific heights per row (v0.4.0)
12
- - [ ] **Per-sheet options in dfs_to_xlsx** - Allow different settings per sheet
13
- - Currently all sheets share the same header/autofit/table_style/freeze_panes
14
- - API idea: `sheets=[(df1, "Sheet1", {"header": True}), (df2, "Sheet2", {"header": False})]`
15
- - [ ] **Header styling** - Option for bold/colored headers (`header_format` parameter)
12
+ - [x] **Per-sheet options in dfs_to_xlsx** - Allow different settings per sheet (v0.5.0)
13
+ - [x] **Header styling** - Option for bold/colored headers (`header_format` parameter) (v0.6.0)
16
14
  - [x] **Freeze panes** - Freeze header row for easier scrolling (v0.3.0)
17
- - [ ] **Global column width cap** - `column_widths={'_all': value}` to limit all column widths
18
- - [ ] **Table name** - `table_name` parameter for named Excel tables
15
+ - [x] **Global column width cap** - `column_widths={'_all': value}` to limit all column widths (v0.6.0)
16
+ - [x] **Table name** - `table_name` parameter for named Excel tables (v0.6.0)
19
17
 
20
18
  ## Medium Priority
21
19
 
22
20
  Power user features for more control over output.
23
21
 
24
22
  - [x] **Multi-core support** - Parallel CSV parsing with rayon (~7% speedup for large files)
25
- - [ ] **Cell formatting options** - Custom number/date formats per column
26
- - [ ] **Cell styling** - Background color, font color, bold, borders per cell/column
23
+ - [x] **Column formatting with wildcards** - `column_formats` with pattern matching (v0.7.0)
24
+ - Supports: `prefix*`, `*suffix`, `*contains*`, exact match
25
+ - Format options: bg_color, font_color, num_format, bold, italic, underline, border
26
+ - [ ] **Row-level cell formatting** - Conditional styling based on cell values
27
27
  - [ ] **Merged cells** - Merge cell ranges for headers/documentation sheets
28
28
  - [ ] **Conditional formatting** - Color scales, data bars, icon sets
29
29
  - [x] **Table styles** - Create Excel tables with auto-filters and 61 built-in styles (v0.3.0)
@@ -40,6 +40,10 @@ Niche features for specific use cases.
40
40
 
41
41
  ## Completed
42
42
 
43
+ - [x] Column formatting with wildcards via `column_formats` parameter (v0.7.0)
44
+ - [x] Global column width cap with `column_widths={'_all': value}` (v0.6.0)
45
+ - [x] Table name parameter with `table_name` (v0.6.0)
46
+ - [x] Header styling with `header_format` (v0.6.0)
43
47
  - [x] CSV to XLSX conversion with type detection (v0.1.0)
44
48
  - [x] pandas DataFrame support (v0.2.0)
45
49
  - [x] polars DataFrame support (v0.2.0)
@@ -50,3 +54,4 @@ Niche features for specific use cases.
50
54
  - [x] Custom column widths with `column_widths` parameter (v0.4.0)
51
55
  - [x] Custom row heights with `row_heights` parameter (v0.4.0)
52
56
  - [x] Constant memory mode with `constant_memory` parameter (v0.4.0)
57
+ - [x] Per-sheet options in `dfs_to_xlsx()` (v0.5.0)
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "xlsxturbo"
7
- version = "0.4.1"
7
+ version = "0.7.0"
8
8
  description = "High-performance Excel writer with automatic type detection (pandas, polars, CSV)"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -0,0 +1,118 @@
1
+ """Type stubs for xlsxturbo"""
2
+
3
+ from typing import TypedDict
4
+
5
+ class HeaderFormat(TypedDict, total=False):
6
+ """Header cell formatting options. All fields are optional."""
7
+ bold: bool
8
+ italic: bool
9
+ font_color: str # '#RRGGBB' or named color (white, black, red, blue, etc.)
10
+ bg_color: str # '#RRGGBB' or named color
11
+ font_size: float
12
+ underline: bool
13
+
14
+ class SheetOptions(TypedDict, total=False):
15
+ """Per-sheet options for dfs_to_xlsx. All fields are optional."""
16
+ header: bool
17
+ autofit: bool
18
+ table_style: str | None
19
+ freeze_panes: bool
20
+ column_widths: dict[int | str, float] | None # Keys: int index or '_all'
21
+ row_heights: dict[int, float] | None
22
+ table_name: str | None
23
+ header_format: HeaderFormat | None
24
+
25
+ def csv_to_xlsx(
26
+ input_path: str,
27
+ output_path: str,
28
+ sheet_name: str = "Sheet1",
29
+ parallel: bool = False,
30
+ ) -> tuple[int, int]:
31
+ """
32
+ Convert a CSV file to XLSX format with automatic type detection.
33
+
34
+ Args:
35
+ input_path: Path to the input CSV file
36
+ output_path: Path for the output XLSX file
37
+ sheet_name: Name of the worksheet (default: "Sheet1")
38
+ parallel: Use multi-core parallel processing (default: False).
39
+ Faster for large files (100K+ rows) but uses more memory.
40
+
41
+ Returns:
42
+ Tuple of (rows, columns) written to the Excel file
43
+
44
+ Raises:
45
+ ValueError: If the conversion fails
46
+ """
47
+ ...
48
+
49
+ def df_to_xlsx(
50
+ df: object,
51
+ output_path: str,
52
+ sheet_name: str = "Sheet1",
53
+ header: bool = True,
54
+ autofit: bool = False,
55
+ table_style: str | None = None,
56
+ freeze_panes: bool = False,
57
+ column_widths: dict[int | str, float] | None = None,
58
+ row_heights: dict[int, float] | None = None,
59
+ constant_memory: bool = False,
60
+ table_name: str | None = None,
61
+ header_format: HeaderFormat | None = None,
62
+ ) -> tuple[int, int]:
63
+ """
64
+ Convert a pandas or polars DataFrame to XLSX format.
65
+
66
+ Args:
67
+ df: pandas DataFrame or polars DataFrame to export
68
+ output_path: Path for the output XLSX file
69
+ sheet_name: Name of the worksheet (default: "Sheet1")
70
+ header: Include column names as header row (default: True)
71
+ autofit: Automatically adjust column widths to fit content (default: False)
72
+ table_style: Apply Excel table formatting (default: None).
73
+ Styles: "Light1"-"Light21", "Medium1"-"Medium28", "Dark1"-"Dark11", "None".
74
+ freeze_panes: Freeze the header row for easier scrolling (default: False)
75
+ column_widths: Dict mapping column index to width. Use '_all' to cap all columns.
76
+ row_heights: Dict mapping row index to height in points.
77
+ constant_memory: Use streaming mode for minimal RAM usage (default: False).
78
+ table_name: Custom name for the Excel table (requires table_style).
79
+ header_format: Dict of header cell formatting options.
80
+ """
81
+ ...
82
+
83
+ def dfs_to_xlsx(
84
+ sheets: list[tuple[object, str] | tuple[object, str, SheetOptions]],
85
+ output_path: str,
86
+ header: bool = True,
87
+ autofit: bool = False,
88
+ table_style: str | None = None,
89
+ freeze_panes: bool = False,
90
+ column_widths: dict[int | str, float] | None = None,
91
+ row_heights: dict[int, float] | None = None,
92
+ constant_memory: bool = False,
93
+ table_name: str | None = None,
94
+ header_format: HeaderFormat | None = None,
95
+ ) -> list[tuple[int, int]]:
96
+ """
97
+ Write multiple DataFrames to separate sheets in a single workbook.
98
+
99
+ Args:
100
+ sheets: List of (DataFrame, sheet_name) or (DataFrame, sheet_name, options) tuples.
101
+ output_path: Path for the output XLSX file
102
+ header: Include column names as header row (default: True)
103
+ autofit: Automatically adjust column widths (default: False)
104
+ table_style: Apply Excel table formatting (default: None).
105
+ freeze_panes: Freeze the header row (default: False)
106
+ column_widths: Dict mapping column index to width. Use '_all' to cap all columns.
107
+ row_heights: Dict mapping row index to height in points.
108
+ constant_memory: Use streaming mode (default: False).
109
+ table_name: Custom name for Excel tables (requires table_style).
110
+ header_format: Dict of header cell formatting options.
111
+ """
112
+ ...
113
+
114
+ def version() -> str:
115
+ """Get the version of the xlsxturbo library."""
116
+ ...
117
+
118
+ __version__: str