xlsxturbo 0.8.0__tar.gz → 0.9.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.
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/CHANGELOG.md +29 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/Cargo.lock +1 -1
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/Cargo.toml +1 -1
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/PKG-INFO +182 -1
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/README.md +181 -0
- xlsxturbo-0.9.0/ROADMAP.md +106 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/pyproject.toml +1 -1
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/python/xlsxturbo/__init__.pyi +60 -4
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/src/lib.rs +823 -6
- xlsxturbo-0.8.0/ROADMAP.md +0 -57
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/.github/dependabot.yml +0 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/.github/workflows/ci.yml +0 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/.github/workflows/release.yml +0 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/.gitignore +0 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/BUILD.md +0 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/LICENSE +0 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/benchmark.py +0 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/benchmark_parallel.py +0 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/python/xlsxturbo/__init__.py +0 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/src/main.rs +0 -0
- {xlsxturbo-0.8.0 → xlsxturbo-0.9.0}/tests/test_features.py +0 -0
|
@@ -5,6 +5,34 @@ 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.9.0] - 2026-01-15
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Conditional formatting** - Visual formatting based on cell values
|
|
12
|
+
- `2_color_scale`: Gradient from min_color to max_color
|
|
13
|
+
- `3_color_scale`: Three-color gradient with min/mid/max colors
|
|
14
|
+
- `data_bar`: In-cell bar chart with customizable color, direction, solid fill
|
|
15
|
+
- `icon_set`: Traffic lights, arrows, flags (3/4/5 icons), with reverse and icons_only options
|
|
16
|
+
- Supports column name patterns: `'price_*': {'type': 'data_bar', ...}`
|
|
17
|
+
- Available in both `df_to_xlsx()` and `dfs_to_xlsx()` with per-sheet overrides
|
|
18
|
+
- Example: `conditional_formats={'score': {'type': '2_color_scale', 'min_color': '#FF0000', 'max_color': '#00FF00'}}`
|
|
19
|
+
- **Formula columns** - Add calculated columns with Excel formulas
|
|
20
|
+
- Use `{row}` placeholder for row numbers (1-based)
|
|
21
|
+
- Columns appear after data columns
|
|
22
|
+
- Order preserved (first formula = first new column)
|
|
23
|
+
- Available in both `df_to_xlsx()` and `dfs_to_xlsx()` with per-sheet overrides
|
|
24
|
+
- Example: `formula_columns={'Total': '=A{row}+B{row}', 'Percentage': '=C{row}/D{row}*100'}`
|
|
25
|
+
- **Merged cells** - Merge cell ranges for headers, titles, and grouped labels
|
|
26
|
+
- Uses Excel notation for ranges (e.g., 'A1:D1')
|
|
27
|
+
- Optional formatting with HeaderFormat options (bold, colors, etc.)
|
|
28
|
+
- Available in both `df_to_xlsx()` and `dfs_to_xlsx()` with per-sheet overrides
|
|
29
|
+
- Example: `merged_ranges=[('A1:C1', 'Title'), ('A2:C2', 'Subtitle', {'bold': True})]`
|
|
30
|
+
- **Hyperlinks** - Add clickable links to cells
|
|
31
|
+
- Uses Excel notation for cell reference (e.g., 'A1', 'B5')
|
|
32
|
+
- Optional display text (defaults to URL if not provided)
|
|
33
|
+
- Available in both `df_to_xlsx()` and `dfs_to_xlsx()` with per-sheet overrides
|
|
34
|
+
- Example: `hyperlinks=[('A2', 'https://example.com'), ('B2', 'https://google.com', 'Google')]`
|
|
35
|
+
|
|
8
36
|
## [0.8.0] - 2026-01-15
|
|
9
37
|
|
|
10
38
|
### Added
|
|
@@ -143,6 +171,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
143
171
|
- Support for custom sheet names
|
|
144
172
|
- Verbose mode for progress reporting
|
|
145
173
|
|
|
174
|
+
[0.9.0]: https://github.com/tstone-1/xlsxturbo/releases/tag/v0.9.0
|
|
146
175
|
[0.8.0]: https://github.com/tstone-1/xlsxturbo/releases/tag/v0.8.0
|
|
147
176
|
[0.7.0]: https://github.com/tstone-1/xlsxturbo/releases/tag/v0.7.0
|
|
148
177
|
[0.6.0]: https://github.com/tstone-1/xlsxturbo/releases/tag/v0.6.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xlsxturbo
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: Intended Audience :: Science/Research
|
|
@@ -39,6 +39,10 @@ High-performance Excel writer with automatic type detection. Written in Rust, us
|
|
|
39
39
|
|
|
40
40
|
- **Direct DataFrame support** for pandas and polars
|
|
41
41
|
- **Excel tables** - filterable tables with 61 built-in styles (banded rows, autofilter)
|
|
42
|
+
- **Conditional formatting** - color scales, data bars, icon sets for visual data analysis
|
|
43
|
+
- **Formula columns** - add calculated columns with Excel formulas
|
|
44
|
+
- **Merged cells** - merge cell ranges for headers and titles
|
|
45
|
+
- **Hyperlinks** - add clickable links to cells
|
|
42
46
|
- **Auto-fit columns** - automatically adjust column widths to fit content
|
|
43
47
|
- **Custom column widths** - set specific widths per column or cap all with _all
|
|
44
48
|
- **Header styling** - bold, colors, font size for header row
|
|
@@ -337,6 +341,179 @@ Available per-sheet options:
|
|
|
337
341
|
- `table_name` (str): Custom Excel table name
|
|
338
342
|
- `header_format` (dict): Header cell styling
|
|
339
343
|
- `column_formats` (dict): Column formatting with pattern matching
|
|
344
|
+
- `conditional_formats` (dict): Conditional formatting (color scales, data bars, icons)
|
|
345
|
+
- `formula_columns` (dict): Calculated columns with Excel formulas (column name -> formula template)
|
|
346
|
+
- `merged_ranges` (list): List of (range, text) or (range, text, format) tuples to merge cells
|
|
347
|
+
- `hyperlinks` (list): List of (cell, url) or (cell, url, display_text) tuples to add clickable links
|
|
348
|
+
|
|
349
|
+
### Conditional Formatting
|
|
350
|
+
|
|
351
|
+
Apply visual formatting based on cell values:
|
|
352
|
+
|
|
353
|
+
```python
|
|
354
|
+
import xlsxturbo
|
|
355
|
+
import pandas as pd
|
|
356
|
+
|
|
357
|
+
df = pd.DataFrame({
|
|
358
|
+
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
|
|
359
|
+
'score': [95, 72, 88, 45],
|
|
360
|
+
'progress': [0.9, 0.5, 0.75, 0.3],
|
|
361
|
+
'status': [3, 2, 3, 1]
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
xlsxturbo.df_to_xlsx(df, "report.xlsx",
|
|
365
|
+
autofit=True,
|
|
366
|
+
conditional_formats={
|
|
367
|
+
# 2-color gradient: red (low) to green (high)
|
|
368
|
+
'score': {
|
|
369
|
+
'type': '2_color_scale',
|
|
370
|
+
'min_color': '#FF6B6B',
|
|
371
|
+
'max_color': '#51CF66'
|
|
372
|
+
},
|
|
373
|
+
# Data bars: in-cell bar chart
|
|
374
|
+
'progress': {
|
|
375
|
+
'type': 'data_bar',
|
|
376
|
+
'bar_color': '#339AF0',
|
|
377
|
+
'solid': True # Solid fill instead of gradient
|
|
378
|
+
},
|
|
379
|
+
# Icon set: traffic lights
|
|
380
|
+
'status': {
|
|
381
|
+
'type': 'icon_set',
|
|
382
|
+
'icon_type': '3_traffic_lights'
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
)
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Supported conditional format types:**
|
|
389
|
+
|
|
390
|
+
| Type | Options |
|
|
391
|
+
|------|---------|
|
|
392
|
+
| `2_color_scale` | `min_color`, `max_color` |
|
|
393
|
+
| `3_color_scale` | `min_color`, `mid_color`, `max_color` |
|
|
394
|
+
| `data_bar` | `bar_color`, `border_color`, `solid`, `direction` |
|
|
395
|
+
| `icon_set` | `icon_type`, `reverse`, `icons_only` |
|
|
396
|
+
|
|
397
|
+
**Available icon types:**
|
|
398
|
+
- 3 icons: `3_arrows`, `3_arrows_gray`, `3_flags`, `3_traffic_lights`, `3_traffic_lights_rimmed`, `3_signs`, `3_symbols`, `3_symbols_uncircled`
|
|
399
|
+
- 4 icons: `4_arrows`, `4_arrows_gray`, `4_traffic_lights`, `4_rating`
|
|
400
|
+
- 5 icons: `5_arrows`, `5_arrows_gray`, `5_quarters`, `5_rating`
|
|
401
|
+
|
|
402
|
+
Column patterns work with conditional formats:
|
|
403
|
+
```python
|
|
404
|
+
# Apply data bars to all columns starting with "price_"
|
|
405
|
+
conditional_formats={'price_*': {'type': 'data_bar', 'bar_color': '#9B59B6'}}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
### Formula Columns
|
|
409
|
+
|
|
410
|
+
Add calculated columns to your Excel output. Formulas are written after data columns and use `{row}` as a placeholder for the row number:
|
|
411
|
+
|
|
412
|
+
```python
|
|
413
|
+
import xlsxturbo
|
|
414
|
+
import pandas as pd
|
|
415
|
+
|
|
416
|
+
df = pd.DataFrame({
|
|
417
|
+
'price': [100, 200, 150],
|
|
418
|
+
'quantity': [5, 3, 8],
|
|
419
|
+
'tax_rate': [0.1, 0.1, 0.2]
|
|
420
|
+
})
|
|
421
|
+
|
|
422
|
+
xlsxturbo.df_to_xlsx(df, "sales.xlsx",
|
|
423
|
+
autofit=True,
|
|
424
|
+
formula_columns={
|
|
425
|
+
'Subtotal': '=A{row}*B{row}', # price * quantity
|
|
426
|
+
'Tax': '=D{row}*C{row}', # subtotal * tax_rate
|
|
427
|
+
'Total': '=D{row}+E{row}' # subtotal + tax
|
|
428
|
+
}
|
|
429
|
+
)
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
Formula columns appear after data columns (A=price, B=quantity, C=tax_rate, D=Subtotal, E=Tax, F=Total).
|
|
433
|
+
|
|
434
|
+
**Notes:**
|
|
435
|
+
- `{row}` is replaced with the Excel row number (1-based, starting at 2 for data rows when header=True)
|
|
436
|
+
- Formula columns inherit header formatting if specified
|
|
437
|
+
- Column order is preserved (first formula = first new column)
|
|
438
|
+
- Works with both `df_to_xlsx` and `dfs_to_xlsx` (global or per-sheet)
|
|
439
|
+
|
|
440
|
+
### Merged Cells
|
|
441
|
+
|
|
442
|
+
Merge cell ranges to create headers, titles, or grouped labels:
|
|
443
|
+
|
|
444
|
+
```python
|
|
445
|
+
import xlsxturbo
|
|
446
|
+
import pandas as pd
|
|
447
|
+
|
|
448
|
+
df = pd.DataFrame({
|
|
449
|
+
'product': ['Widget A', 'Widget B'],
|
|
450
|
+
'sales': [1500, 2300],
|
|
451
|
+
'revenue': [7500, 11500]
|
|
452
|
+
})
|
|
453
|
+
|
|
454
|
+
# Merge cells for a title above the data
|
|
455
|
+
xlsxturbo.df_to_xlsx(df, "report.xlsx",
|
|
456
|
+
header=True,
|
|
457
|
+
merged_ranges=[
|
|
458
|
+
# Simple merge with text (auto-centered)
|
|
459
|
+
('A1:C1', 'Q4 Sales Report'),
|
|
460
|
+
# Merge with custom formatting
|
|
461
|
+
('A2:C2', 'Regional Data', {
|
|
462
|
+
'bold': True,
|
|
463
|
+
'bg_color': '#4F81BD',
|
|
464
|
+
'font_color': 'white'
|
|
465
|
+
})
|
|
466
|
+
]
|
|
467
|
+
)
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
**Merged range format:**
|
|
471
|
+
- Tuple of `(range, text)` or `(range, text, format_dict)`
|
|
472
|
+
- Range uses Excel notation: `'A1:D1'`, `'B3:B10'`, etc.
|
|
473
|
+
- Format options same as `header_format`: bold, italic, font_color, bg_color, font_size, underline
|
|
474
|
+
|
|
475
|
+
**Notes:**
|
|
476
|
+
- Merged cells are applied after data is written, so plan row positions accordingly
|
|
477
|
+
- When using with `header=True`, data starts at row 2 (Excel row 2)
|
|
478
|
+
- Works with both `df_to_xlsx` and `dfs_to_xlsx` (global or per-sheet)
|
|
479
|
+
|
|
480
|
+
### Hyperlinks
|
|
481
|
+
|
|
482
|
+
Add clickable links to cells:
|
|
483
|
+
|
|
484
|
+
```python
|
|
485
|
+
import xlsxturbo
|
|
486
|
+
import pandas as pd
|
|
487
|
+
|
|
488
|
+
df = pd.DataFrame({
|
|
489
|
+
'company': ['Anthropic', 'Google', 'Microsoft'],
|
|
490
|
+
'product': ['Claude', 'Gemini', 'Copilot'],
|
|
491
|
+
})
|
|
492
|
+
|
|
493
|
+
# Add hyperlinks to a new column (D) after the data columns (A, B, C with header)
|
|
494
|
+
xlsxturbo.df_to_xlsx(df, "companies.xlsx",
|
|
495
|
+
autofit=True,
|
|
496
|
+
hyperlinks=[
|
|
497
|
+
# Header for the links column
|
|
498
|
+
('C1', 'https://example.com', 'Website'),
|
|
499
|
+
# Links with company names as display text
|
|
500
|
+
('C2', 'https://anthropic.com', 'anthropic.com'),
|
|
501
|
+
('C3', 'https://google.com', 'google.com'),
|
|
502
|
+
('C4', 'https://microsoft.com', 'microsoft.com'),
|
|
503
|
+
]
|
|
504
|
+
)
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
**Hyperlink format:**
|
|
508
|
+
- Tuple of `(cell, url)` or `(cell, url, display_text)`
|
|
509
|
+
- Cell uses Excel notation: `'A1'`, `'B5'`, etc.
|
|
510
|
+
- Display text is optional; if omitted, the URL is shown
|
|
511
|
+
|
|
512
|
+
**Notes:**
|
|
513
|
+
- Hyperlinks write to the specified cell position (overwrites existing content)
|
|
514
|
+
- To add a "links column", target cells beyond your DataFrame columns (as shown above)
|
|
515
|
+
- Works with both `df_to_xlsx` and `dfs_to_xlsx` (global or per-sheet)
|
|
516
|
+
- Not available in constant memory mode
|
|
340
517
|
|
|
341
518
|
### Constant Memory Mode (Large Files)
|
|
342
519
|
|
|
@@ -366,6 +543,10 @@ xlsxturbo.dfs_to_xlsx([
|
|
|
366
543
|
- `freeze_panes`
|
|
367
544
|
- `row_heights`
|
|
368
545
|
- `autofit`
|
|
546
|
+
- `conditional_formats`
|
|
547
|
+
- `formula_columns`
|
|
548
|
+
- `merged_ranges`
|
|
549
|
+
- `hyperlinks`
|
|
369
550
|
|
|
370
551
|
Column widths still work in constant memory mode.
|
|
371
552
|
|
|
@@ -6,6 +6,10 @@ High-performance Excel writer with automatic type detection. Written in Rust, us
|
|
|
6
6
|
|
|
7
7
|
- **Direct DataFrame support** for pandas and polars
|
|
8
8
|
- **Excel tables** - filterable tables with 61 built-in styles (banded rows, autofilter)
|
|
9
|
+
- **Conditional formatting** - color scales, data bars, icon sets for visual data analysis
|
|
10
|
+
- **Formula columns** - add calculated columns with Excel formulas
|
|
11
|
+
- **Merged cells** - merge cell ranges for headers and titles
|
|
12
|
+
- **Hyperlinks** - add clickable links to cells
|
|
9
13
|
- **Auto-fit columns** - automatically adjust column widths to fit content
|
|
10
14
|
- **Custom column widths** - set specific widths per column or cap all with _all
|
|
11
15
|
- **Header styling** - bold, colors, font size for header row
|
|
@@ -304,6 +308,179 @@ Available per-sheet options:
|
|
|
304
308
|
- `table_name` (str): Custom Excel table name
|
|
305
309
|
- `header_format` (dict): Header cell styling
|
|
306
310
|
- `column_formats` (dict): Column formatting with pattern matching
|
|
311
|
+
- `conditional_formats` (dict): Conditional formatting (color scales, data bars, icons)
|
|
312
|
+
- `formula_columns` (dict): Calculated columns with Excel formulas (column name -> formula template)
|
|
313
|
+
- `merged_ranges` (list): List of (range, text) or (range, text, format) tuples to merge cells
|
|
314
|
+
- `hyperlinks` (list): List of (cell, url) or (cell, url, display_text) tuples to add clickable links
|
|
315
|
+
|
|
316
|
+
### Conditional Formatting
|
|
317
|
+
|
|
318
|
+
Apply visual formatting based on cell values:
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
import xlsxturbo
|
|
322
|
+
import pandas as pd
|
|
323
|
+
|
|
324
|
+
df = pd.DataFrame({
|
|
325
|
+
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
|
|
326
|
+
'score': [95, 72, 88, 45],
|
|
327
|
+
'progress': [0.9, 0.5, 0.75, 0.3],
|
|
328
|
+
'status': [3, 2, 3, 1]
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
xlsxturbo.df_to_xlsx(df, "report.xlsx",
|
|
332
|
+
autofit=True,
|
|
333
|
+
conditional_formats={
|
|
334
|
+
# 2-color gradient: red (low) to green (high)
|
|
335
|
+
'score': {
|
|
336
|
+
'type': '2_color_scale',
|
|
337
|
+
'min_color': '#FF6B6B',
|
|
338
|
+
'max_color': '#51CF66'
|
|
339
|
+
},
|
|
340
|
+
# Data bars: in-cell bar chart
|
|
341
|
+
'progress': {
|
|
342
|
+
'type': 'data_bar',
|
|
343
|
+
'bar_color': '#339AF0',
|
|
344
|
+
'solid': True # Solid fill instead of gradient
|
|
345
|
+
},
|
|
346
|
+
# Icon set: traffic lights
|
|
347
|
+
'status': {
|
|
348
|
+
'type': 'icon_set',
|
|
349
|
+
'icon_type': '3_traffic_lights'
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
)
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
**Supported conditional format types:**
|
|
356
|
+
|
|
357
|
+
| Type | Options |
|
|
358
|
+
|------|---------|
|
|
359
|
+
| `2_color_scale` | `min_color`, `max_color` |
|
|
360
|
+
| `3_color_scale` | `min_color`, `mid_color`, `max_color` |
|
|
361
|
+
| `data_bar` | `bar_color`, `border_color`, `solid`, `direction` |
|
|
362
|
+
| `icon_set` | `icon_type`, `reverse`, `icons_only` |
|
|
363
|
+
|
|
364
|
+
**Available icon types:**
|
|
365
|
+
- 3 icons: `3_arrows`, `3_arrows_gray`, `3_flags`, `3_traffic_lights`, `3_traffic_lights_rimmed`, `3_signs`, `3_symbols`, `3_symbols_uncircled`
|
|
366
|
+
- 4 icons: `4_arrows`, `4_arrows_gray`, `4_traffic_lights`, `4_rating`
|
|
367
|
+
- 5 icons: `5_arrows`, `5_arrows_gray`, `5_quarters`, `5_rating`
|
|
368
|
+
|
|
369
|
+
Column patterns work with conditional formats:
|
|
370
|
+
```python
|
|
371
|
+
# Apply data bars to all columns starting with "price_"
|
|
372
|
+
conditional_formats={'price_*': {'type': 'data_bar', 'bar_color': '#9B59B6'}}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### Formula Columns
|
|
376
|
+
|
|
377
|
+
Add calculated columns to your Excel output. Formulas are written after data columns and use `{row}` as a placeholder for the row number:
|
|
378
|
+
|
|
379
|
+
```python
|
|
380
|
+
import xlsxturbo
|
|
381
|
+
import pandas as pd
|
|
382
|
+
|
|
383
|
+
df = pd.DataFrame({
|
|
384
|
+
'price': [100, 200, 150],
|
|
385
|
+
'quantity': [5, 3, 8],
|
|
386
|
+
'tax_rate': [0.1, 0.1, 0.2]
|
|
387
|
+
})
|
|
388
|
+
|
|
389
|
+
xlsxturbo.df_to_xlsx(df, "sales.xlsx",
|
|
390
|
+
autofit=True,
|
|
391
|
+
formula_columns={
|
|
392
|
+
'Subtotal': '=A{row}*B{row}', # price * quantity
|
|
393
|
+
'Tax': '=D{row}*C{row}', # subtotal * tax_rate
|
|
394
|
+
'Total': '=D{row}+E{row}' # subtotal + tax
|
|
395
|
+
}
|
|
396
|
+
)
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
Formula columns appear after data columns (A=price, B=quantity, C=tax_rate, D=Subtotal, E=Tax, F=Total).
|
|
400
|
+
|
|
401
|
+
**Notes:**
|
|
402
|
+
- `{row}` is replaced with the Excel row number (1-based, starting at 2 for data rows when header=True)
|
|
403
|
+
- Formula columns inherit header formatting if specified
|
|
404
|
+
- Column order is preserved (first formula = first new column)
|
|
405
|
+
- Works with both `df_to_xlsx` and `dfs_to_xlsx` (global or per-sheet)
|
|
406
|
+
|
|
407
|
+
### Merged Cells
|
|
408
|
+
|
|
409
|
+
Merge cell ranges to create headers, titles, or grouped labels:
|
|
410
|
+
|
|
411
|
+
```python
|
|
412
|
+
import xlsxturbo
|
|
413
|
+
import pandas as pd
|
|
414
|
+
|
|
415
|
+
df = pd.DataFrame({
|
|
416
|
+
'product': ['Widget A', 'Widget B'],
|
|
417
|
+
'sales': [1500, 2300],
|
|
418
|
+
'revenue': [7500, 11500]
|
|
419
|
+
})
|
|
420
|
+
|
|
421
|
+
# Merge cells for a title above the data
|
|
422
|
+
xlsxturbo.df_to_xlsx(df, "report.xlsx",
|
|
423
|
+
header=True,
|
|
424
|
+
merged_ranges=[
|
|
425
|
+
# Simple merge with text (auto-centered)
|
|
426
|
+
('A1:C1', 'Q4 Sales Report'),
|
|
427
|
+
# Merge with custom formatting
|
|
428
|
+
('A2:C2', 'Regional Data', {
|
|
429
|
+
'bold': True,
|
|
430
|
+
'bg_color': '#4F81BD',
|
|
431
|
+
'font_color': 'white'
|
|
432
|
+
})
|
|
433
|
+
]
|
|
434
|
+
)
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
**Merged range format:**
|
|
438
|
+
- Tuple of `(range, text)` or `(range, text, format_dict)`
|
|
439
|
+
- Range uses Excel notation: `'A1:D1'`, `'B3:B10'`, etc.
|
|
440
|
+
- Format options same as `header_format`: bold, italic, font_color, bg_color, font_size, underline
|
|
441
|
+
|
|
442
|
+
**Notes:**
|
|
443
|
+
- Merged cells are applied after data is written, so plan row positions accordingly
|
|
444
|
+
- When using with `header=True`, data starts at row 2 (Excel row 2)
|
|
445
|
+
- Works with both `df_to_xlsx` and `dfs_to_xlsx` (global or per-sheet)
|
|
446
|
+
|
|
447
|
+
### Hyperlinks
|
|
448
|
+
|
|
449
|
+
Add clickable links to cells:
|
|
450
|
+
|
|
451
|
+
```python
|
|
452
|
+
import xlsxturbo
|
|
453
|
+
import pandas as pd
|
|
454
|
+
|
|
455
|
+
df = pd.DataFrame({
|
|
456
|
+
'company': ['Anthropic', 'Google', 'Microsoft'],
|
|
457
|
+
'product': ['Claude', 'Gemini', 'Copilot'],
|
|
458
|
+
})
|
|
459
|
+
|
|
460
|
+
# Add hyperlinks to a new column (D) after the data columns (A, B, C with header)
|
|
461
|
+
xlsxturbo.df_to_xlsx(df, "companies.xlsx",
|
|
462
|
+
autofit=True,
|
|
463
|
+
hyperlinks=[
|
|
464
|
+
# Header for the links column
|
|
465
|
+
('C1', 'https://example.com', 'Website'),
|
|
466
|
+
# Links with company names as display text
|
|
467
|
+
('C2', 'https://anthropic.com', 'anthropic.com'),
|
|
468
|
+
('C3', 'https://google.com', 'google.com'),
|
|
469
|
+
('C4', 'https://microsoft.com', 'microsoft.com'),
|
|
470
|
+
]
|
|
471
|
+
)
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
**Hyperlink format:**
|
|
475
|
+
- Tuple of `(cell, url)` or `(cell, url, display_text)`
|
|
476
|
+
- Cell uses Excel notation: `'A1'`, `'B5'`, etc.
|
|
477
|
+
- Display text is optional; if omitted, the URL is shown
|
|
478
|
+
|
|
479
|
+
**Notes:**
|
|
480
|
+
- Hyperlinks write to the specified cell position (overwrites existing content)
|
|
481
|
+
- To add a "links column", target cells beyond your DataFrame columns (as shown above)
|
|
482
|
+
- Works with both `df_to_xlsx` and `dfs_to_xlsx` (global or per-sheet)
|
|
483
|
+
- Not available in constant memory mode
|
|
307
484
|
|
|
308
485
|
### Constant Memory Mode (Large Files)
|
|
309
486
|
|
|
@@ -333,6 +510,10 @@ xlsxturbo.dfs_to_xlsx([
|
|
|
333
510
|
- `freeze_panes`
|
|
334
511
|
- `row_heights`
|
|
335
512
|
- `autofit`
|
|
513
|
+
- `conditional_formats`
|
|
514
|
+
- `formula_columns`
|
|
515
|
+
- `merged_ranges`
|
|
516
|
+
- `hyperlinks`
|
|
336
517
|
|
|
337
518
|
Column widths still work in constant memory mode.
|
|
338
519
|
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
Planned features for xlsxturbo, ordered by priority.
|
|
4
|
+
|
|
5
|
+
xlsxturbo's niche is **high-performance DataFrame export** with a simple API. The underlying
|
|
6
|
+
rust_xlsxwriter library already supports most advanced Excel features—they just need Python
|
|
7
|
+
bindings exposed.
|
|
8
|
+
|
|
9
|
+
## High Priority
|
|
10
|
+
|
|
11
|
+
Features that close the gap with XlsxWriter/openpyxl for common use cases.
|
|
12
|
+
|
|
13
|
+
- [x] **Conditional formatting** - Color scales, data bars, icon sets (v0.9.0)
|
|
14
|
+
- Supports: 2_color_scale, 3_color_scale, data_bar, icon_set
|
|
15
|
+
- API: `conditional_formats={'column': {'type': '2_color_scale', 'min_color': '#FF0000', 'max_color': '#00FF00'}}`
|
|
16
|
+
|
|
17
|
+
- [x] **Formulas** - Add calculated columns with Excel formulas (v0.9.0)
|
|
18
|
+
- API: `formula_columns={'Total': '=A{row}+B{row}', 'Percentage': '=C{row}/D{row}*100'}`
|
|
19
|
+
- Use `{row}` placeholder for row numbers (1-based)
|
|
20
|
+
|
|
21
|
+
- [x] **Merged cells** - Merge cell ranges for headers/documentation sheets (v0.9.0)
|
|
22
|
+
- API: `merged_ranges=[('A1:D1', 'Report Title'), ('A2:D2', 'Subtitle', {'bold': True})]`
|
|
23
|
+
|
|
24
|
+
- [x] **Hyperlinks** - Add clickable links to cells (v0.9.0)
|
|
25
|
+
- API: `hyperlinks=[('A1', 'https://example.com'), ('B1', 'https://google.com', 'Google')]`
|
|
26
|
+
- Optional display text (defaults to URL if omitted)
|
|
27
|
+
|
|
28
|
+
## Medium Priority
|
|
29
|
+
|
|
30
|
+
Power user features for richer Excel output.
|
|
31
|
+
|
|
32
|
+
- [ ] **Data validation** - Dropdowns, input constraints
|
|
33
|
+
- rust_xlsxwriter: supported
|
|
34
|
+
- Enables: dropdown lists, numeric ranges, custom error messages
|
|
35
|
+
- API: `validations={'Status': {'type': 'list', 'values': ['Open', 'Closed']}}`
|
|
36
|
+
|
|
37
|
+
- [ ] **Images** - Embed PNG/JPEG/GIF/BMP images
|
|
38
|
+
- rust_xlsxwriter: supported
|
|
39
|
+
- Enables: logos, charts generated externally, screenshots
|
|
40
|
+
- API: `images={'A1': 'logo.png'}` or `images=[('B5', 'chart.png', options)]`
|
|
41
|
+
|
|
42
|
+
- [ ] **Comments/notes** - Add cell comments
|
|
43
|
+
- rust_xlsxwriter: supported
|
|
44
|
+
- Enables: documentation, review notes, explanations
|
|
45
|
+
- API: `comments={'A1': 'This is the header'}` or in column_formats
|
|
46
|
+
|
|
47
|
+
- [ ] **Column type hints** - Override auto-detection for specific columns
|
|
48
|
+
- Enables: force text for ZIP codes, force numbers for string-encoded IDs
|
|
49
|
+
- API: `column_types={'zip_code': 'text', 'amount': 'number'}`
|
|
50
|
+
|
|
51
|
+
- [ ] **Rich text** - Multiple formats within a single cell
|
|
52
|
+
- rust_xlsxwriter: supported
|
|
53
|
+
- Enables: bold + italic in same cell, colored substrings
|
|
54
|
+
- API: `rich_text={'A1': [('Bold part', {'bold': True}), (' normal')]}`
|
|
55
|
+
|
|
56
|
+
## Lower Priority
|
|
57
|
+
|
|
58
|
+
Niche features for specific use cases.
|
|
59
|
+
|
|
60
|
+
- [ ] **Charts** - Bar, line, pie, scatter, etc.
|
|
61
|
+
- rust_xlsxwriter: supported (all standard chart types)
|
|
62
|
+
- Enables: visual data representation within Excel
|
|
63
|
+
- Complex API, may be better served by matplotlib → image
|
|
64
|
+
|
|
65
|
+
- [ ] **Sparklines** - Mini inline charts
|
|
66
|
+
- rust_xlsxwriter: supported
|
|
67
|
+
- Enables: trend indicators in cells
|
|
68
|
+
- API: `sparklines={'D2:D10': {'range': 'A2:C10', 'type': 'line'}}`
|
|
69
|
+
|
|
70
|
+
- [ ] **Append mode** - Add sheets to existing workbook
|
|
71
|
+
- rust_xlsxwriter: not supported (write-only by design)
|
|
72
|
+
- Would require openpyxl hybrid approach
|
|
73
|
+
|
|
74
|
+
- [ ] **Checkboxes** - Interactive checkboxes in cells
|
|
75
|
+
- rust_xlsxwriter: supported
|
|
76
|
+
- Enables: todo lists, selection interfaces
|
|
77
|
+
|
|
78
|
+
- [ ] **Textboxes** - Floating text annotations
|
|
79
|
+
- rust_xlsxwriter: supported
|
|
80
|
+
- Enables: callouts, annotations outside cell grid
|
|
81
|
+
|
|
82
|
+
## Completed
|
|
83
|
+
|
|
84
|
+
- [x] Hyperlinks via `hyperlinks` parameter (v0.9.0)
|
|
85
|
+
- [x] Merged cells via `merged_ranges` parameter (v0.9.0)
|
|
86
|
+
- [x] Formula columns via `formula_columns` parameter (v0.9.0)
|
|
87
|
+
- [x] Conditional formatting via `conditional_formats` parameter (v0.9.0)
|
|
88
|
+
- [x] Column formatting with wildcards via `column_formats` parameter (v0.7.0)
|
|
89
|
+
- [x] Global column width cap with `column_widths={'_all': value}` (v0.6.0)
|
|
90
|
+
- [x] Table name parameter with `table_name` (v0.6.0)
|
|
91
|
+
- [x] Header styling with `header_format` (v0.6.0)
|
|
92
|
+
- [x] CSV to XLSX conversion with type detection (v0.1.0)
|
|
93
|
+
- [x] pandas DataFrame support (v0.2.0)
|
|
94
|
+
- [x] polars DataFrame support (v0.2.0)
|
|
95
|
+
- [x] Multi-sheet workbooks with `dfs_to_xlsx()` (v0.2.0)
|
|
96
|
+
- [x] Parallel CSV parsing with `parallel=True` (v0.2.0)
|
|
97
|
+
- [x] Date/datetime formatting (v0.1.0)
|
|
98
|
+
- [x] CLI tool (v0.1.0)
|
|
99
|
+
- [x] Custom column widths with `column_widths` parameter (v0.4.0)
|
|
100
|
+
- [x] Custom row heights with `row_heights` parameter (v0.4.0)
|
|
101
|
+
- [x] Constant memory mode with `constant_memory` parameter (v0.4.0)
|
|
102
|
+
- [x] Per-sheet options in `dfs_to_xlsx()` (v0.5.0)
|
|
103
|
+
- [x] Column auto-width (v0.3.0)
|
|
104
|
+
- [x] Table styles with 61 built-in options (v0.3.0)
|
|
105
|
+
- [x] Freeze panes (v0.3.0)
|
|
106
|
+
- [x] Multi-core CSV support (v0.2.0)
|