rustypyxl 0.1.0__cp310-cp310-win_amd64.whl → 0.3.0__cp310-cp310-win_amd64.whl
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.
- rustypyxl/rustypyxl.cp310-win_amd64.pyd +0 -0
- rustypyxl-0.3.0.dist-info/METADATA +263 -0
- rustypyxl-0.3.0.dist-info/RECORD +6 -0
- rustypyxl-0.3.0.dist-info/licenses/LICENSE +21 -0
- rustypyxl-0.1.0.dist-info/METADATA +0 -7
- rustypyxl-0.1.0.dist-info/RECORD +0 -5
- {rustypyxl-0.1.0.dist-info → rustypyxl-0.3.0.dist-info}/WHEEL +0 -0
|
Binary file
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rustypyxl
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Developers
|
|
6
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
+
Classifier: Operating System :: OS Independent
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
15
|
+
Classifier: Programming Language :: Rust
|
|
16
|
+
Classifier: Topic :: Office/Business :: Financial :: Spreadsheet
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Summary: A fast, Rust-powered Excel xlsx library for Python with openpyxl-compatible API
|
|
21
|
+
Keywords: excel,xlsx,spreadsheet,openpyxl,rust,performance
|
|
22
|
+
Author-email: Eve Freeman <eve.freeman@gmail.com>
|
|
23
|
+
License: MIT
|
|
24
|
+
Requires-Python: >=3.10, <3.15
|
|
25
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
26
|
+
Project-URL: Homepage, https://github.com/freeeve/rustypyxl
|
|
27
|
+
Project-URL: Issues, https://github.com/freeeve/rustypyxl/issues
|
|
28
|
+
Project-URL: Repository, https://github.com/freeeve/rustypyxl
|
|
29
|
+
|
|
30
|
+
# rustypyxl
|
|
31
|
+
|
|
32
|
+
[](https://sonarcloud.io/summary/new_code?id=freeeve_rustypyxl)
|
|
33
|
+
[](https://sonarcloud.io/summary/new_code?id=freeeve_rustypyxl)
|
|
34
|
+
[](https://sonarcloud.io/summary/new_code?id=freeeve_rustypyxl)
|
|
35
|
+
[](https://snyk.io/test/github/freeeve/rustypyxl)
|
|
36
|
+
|
|
37
|
+
A Rust-powered Excel (XLSX) library for Python with an openpyxl-compatible API.
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pip install rustypyxl
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import rustypyxl
|
|
49
|
+
|
|
50
|
+
# Load a workbook
|
|
51
|
+
wb = rustypyxl.load_workbook('input.xlsx')
|
|
52
|
+
ws = wb.active
|
|
53
|
+
|
|
54
|
+
# Read values
|
|
55
|
+
value = wb.get_cell_value('Sheet1', 1, 1)
|
|
56
|
+
|
|
57
|
+
# Write values
|
|
58
|
+
wb.set_cell_value('Sheet1', 1, 1, 'Hello')
|
|
59
|
+
wb.set_cell_value('Sheet1', 2, 1, 42.5)
|
|
60
|
+
wb.set_cell_value('Sheet1', 3, 1, '=SUM(A1:A2)')
|
|
61
|
+
|
|
62
|
+
# Bulk operations
|
|
63
|
+
wb.write_rows('Sheet1', [
|
|
64
|
+
['Name', 'Age', 'Score'],
|
|
65
|
+
['Alice', 30, 95.5],
|
|
66
|
+
['Bob', 25, 87.3],
|
|
67
|
+
])
|
|
68
|
+
|
|
69
|
+
data = wb.read_rows('Sheet1', min_row=1, max_row=100)
|
|
70
|
+
|
|
71
|
+
# Save
|
|
72
|
+
wb.save('output.xlsx')
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Features
|
|
76
|
+
|
|
77
|
+
- **openpyxl-compatible API**: Familiar patterns for easy migration
|
|
78
|
+
- **Read and write support**: Full round-trip capability
|
|
79
|
+
- **Cell values**: Strings, numbers, booleans, dates, formulas
|
|
80
|
+
- **Formatting**: Fonts, alignment, fills, borders, number formats
|
|
81
|
+
- **Workbook features**: Comments, hyperlinks, named ranges, merged cells
|
|
82
|
+
- **Sheet features**: Protection, data validation, column/row dimensions
|
|
83
|
+
- **Parquet import/export**: Direct Parquet ↔ Excel conversion (bypasses Python FFI)
|
|
84
|
+
- **S3 support**: Works with boto3 via bytes I/O
|
|
85
|
+
- **Bytes I/O**: Load from bytes or file-like objects, save to bytes
|
|
86
|
+
- **Configurable compression**: Trade off speed vs file size
|
|
87
|
+
|
|
88
|
+
## Parquet Import
|
|
89
|
+
|
|
90
|
+
Import large Parquet files directly into Excel worksheets. Data flows from Parquet → Rust → Excel without crossing the Python FFI boundary, making it very fast for large datasets.
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import rustypyxl
|
|
94
|
+
|
|
95
|
+
wb = rustypyxl.Workbook()
|
|
96
|
+
wb.create_sheet("Data")
|
|
97
|
+
|
|
98
|
+
# Import parquet file into sheet
|
|
99
|
+
result = wb.insert_from_parquet(
|
|
100
|
+
sheet_name="Data",
|
|
101
|
+
path="large_dataset.parquet",
|
|
102
|
+
start_row=1,
|
|
103
|
+
start_col=1,
|
|
104
|
+
include_headers=True,
|
|
105
|
+
column_renames={"old_name": "new_name"}, # optional
|
|
106
|
+
columns=["col1", "col2", "col3"], # optional: select specific columns
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
print(f"Imported {result['rows_imported']} rows")
|
|
110
|
+
print(f"Data range: {result['range_with_headers']}")
|
|
111
|
+
|
|
112
|
+
wb.save("output.xlsx")
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Performance: ~4 seconds for 1M rows × 20 columns on M1 MacBook Pro.
|
|
116
|
+
|
|
117
|
+
## Parquet Export
|
|
118
|
+
|
|
119
|
+
Export worksheet data to Parquet format with automatic type inference:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
import rustypyxl
|
|
123
|
+
|
|
124
|
+
wb = rustypyxl.load_workbook("data.xlsx")
|
|
125
|
+
|
|
126
|
+
# Export entire sheet
|
|
127
|
+
result = wb.export_to_parquet(
|
|
128
|
+
sheet_name="Sheet1",
|
|
129
|
+
path="output.parquet",
|
|
130
|
+
has_headers=True, # first row contains headers
|
|
131
|
+
compression="snappy", # snappy, zstd, gzip, lz4, none
|
|
132
|
+
column_renames={"old": "new"}, # optional: rename columns
|
|
133
|
+
column_types={"date_col": "datetime"}, # optional: force column types
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
print(f"Exported {result['rows_exported']} rows")
|
|
137
|
+
print(f"File size: {result['file_size']} bytes")
|
|
138
|
+
|
|
139
|
+
# Export specific range
|
|
140
|
+
result = wb.export_range_to_parquet(
|
|
141
|
+
sheet_name="Sheet1",
|
|
142
|
+
path="subset.parquet",
|
|
143
|
+
min_row=1, min_col=1,
|
|
144
|
+
max_row=1000, max_col=5,
|
|
145
|
+
)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Supported column type hints: `string`, `float64`, `int64`, `boolean`, `date`, `datetime`, `auto`.
|
|
149
|
+
|
|
150
|
+
## Loading from Bytes or File-like Objects
|
|
151
|
+
|
|
152
|
+
Load workbooks from in-memory bytes or file-like objects:
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
import rustypyxl
|
|
156
|
+
import io
|
|
157
|
+
|
|
158
|
+
# From bytes
|
|
159
|
+
with open("file.xlsx", "rb") as f:
|
|
160
|
+
data = f.read()
|
|
161
|
+
wb = rustypyxl.load_workbook(data)
|
|
162
|
+
|
|
163
|
+
# From file-like object (e.g., BytesIO, HTTP response)
|
|
164
|
+
wb = rustypyxl.load_workbook(io.BytesIO(data))
|
|
165
|
+
|
|
166
|
+
# Save to bytes (for HTTP responses, S3, etc.)
|
|
167
|
+
output_bytes = wb.save_to_bytes()
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## S3 Support
|
|
171
|
+
|
|
172
|
+
Use `save_to_bytes()` and `load_workbook(bytes)` with boto3 for S3 integration:
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
import boto3
|
|
176
|
+
import rustypyxl
|
|
177
|
+
|
|
178
|
+
s3 = boto3.client("s3")
|
|
179
|
+
|
|
180
|
+
# Load from S3
|
|
181
|
+
response = s3.get_object(Bucket="my-bucket", Key="path/to/file.xlsx")
|
|
182
|
+
wb = rustypyxl.load_workbook(response["Body"].read())
|
|
183
|
+
|
|
184
|
+
# Save to S3
|
|
185
|
+
data = wb.save_to_bytes()
|
|
186
|
+
s3.put_object(Bucket="my-bucket", Key="path/to/output.xlsx", Body=data)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
This works with any S3-compatible service and uses boto3's credential handling (IAM roles, environment variables, etc.).
|
|
190
|
+
|
|
191
|
+
## Streaming Writes (Low Memory)
|
|
192
|
+
|
|
193
|
+
For very large files, use `WriteOnlyWorkbook` which streams rows directly to disk:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
import rustypyxl
|
|
197
|
+
|
|
198
|
+
wb = rustypyxl.WriteOnlyWorkbook("large_output.xlsx")
|
|
199
|
+
wb.create_sheet("Data")
|
|
200
|
+
|
|
201
|
+
for i in range(1_000_000):
|
|
202
|
+
wb.append_row([f"Row {i}", i, i * 1.5, i % 2 == 0])
|
|
203
|
+
|
|
204
|
+
wb.close() # Must call close() to finalize the file
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
This uses minimal memory regardless of file size, similar to openpyxl's `write_only=True` mode.
|
|
208
|
+
|
|
209
|
+
## Benchmarks
|
|
210
|
+
|
|
211
|
+
Micro benchmarks on M1 MacBook Pro. Your results may vary depending on data characteristics and hardware.
|
|
212
|
+
|
|
213
|
+
### Write Performance (1M rows × 20 columns)
|
|
214
|
+
|
|
215
|
+
| Library | Time |
|
|
216
|
+
|---------|------|
|
|
217
|
+
| rustypyxl | ~10s |
|
|
218
|
+
| openpyxl | ~200s |
|
|
219
|
+
|
|
220
|
+
### Read Performance
|
|
221
|
+
|
|
222
|
+
| Dataset | rustypyxl | calamine | openpyxl |
|
|
223
|
+
|---------|-----------|----------|----------|
|
|
224
|
+
| 10k × 20 (numeric) | 0.08s | 0.10s | 0.51s |
|
|
225
|
+
| 10k × 20 (strings) | 0.10s | 0.12s | 1.23s |
|
|
226
|
+
| 100k × 20 (numeric) | 0.97s | 1.03s | 4.74s |
|
|
227
|
+
| 100k × 20 (mixed) | 1.20s | 1.28s | 12.1s |
|
|
228
|
+
|
|
229
|
+
[calamine](https://github.com/tafia/calamine) is a Rust Excel reader with Python bindings via python-calamine (read-only).
|
|
230
|
+
|
|
231
|
+
### Memory Usage (Read)
|
|
232
|
+
|
|
233
|
+
| Dataset | rustypyxl | calamine | openpyxl |
|
|
234
|
+
|---------|-----------|----------|----------|
|
|
235
|
+
| 10k × 20 | 29 MB | 9 MB | 11 MB |
|
|
236
|
+
| 50k × 20 | 58 MB | 48 MB | 53 MB |
|
|
237
|
+
| 100k × 20 | 95 MB | 95 MB | 106 MB |
|
|
238
|
+
|
|
239
|
+
### Memory Usage (Write)
|
|
240
|
+
|
|
241
|
+
| Dataset | rustypyxl | WriteOnlyWorkbook | openpyxl (write_only) |
|
|
242
|
+
|---------|-----------|-------------------|----------------------|
|
|
243
|
+
| 10k × 20 | 10 MB | ~0 MB | 0.4 MB |
|
|
244
|
+
| 50k × 20 | 50 MB | ~0 MB | 0.4 MB |
|
|
245
|
+
| 100k × 20 | 99 MB | ~0 MB | 0.4 MB |
|
|
246
|
+
|
|
247
|
+
`WriteOnlyWorkbook` streams rows directly to disk like openpyxl's write_only mode.
|
|
248
|
+
|
|
249
|
+
## Building from Source
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# Install Rust and maturin
|
|
253
|
+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
254
|
+
pip install maturin
|
|
255
|
+
|
|
256
|
+
# Build
|
|
257
|
+
maturin develop --release
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## License
|
|
261
|
+
|
|
262
|
+
MIT
|
|
263
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
rustypyxl\__init__.py,sha256=SXJtqXdgK5i8PgB-tOX0cEWwc5033yqhWtlg6PESgU4,119
|
|
2
|
+
rustypyxl\rustypyxl.cp310-win_amd64.pyd,sha256=grI827DXReGYQONO8B2t1L0j7zQvS57rou8P4zfz-Wo,11081216
|
|
3
|
+
rustypyxl-0.3.0.dist-info\METADATA,sha256=TrunBZ9S8uoAnxqOCNSqwBM91rCuC9WmtRMZKRlyJAE,8248
|
|
4
|
+
rustypyxl-0.3.0.dist-info\WHEEL,sha256=L_nHnx2hhpjVM_Xfu45p0kXGA_F4gVVL8EpDS6M9jpM,97
|
|
5
|
+
rustypyxl-0.3.0.dist-info\licenses\LICENSE,sha256=wKnFG47KqthzLvOs8l2Yi2vxmc3OJJRxRyqBOWD__CY,1089
|
|
6
|
+
rustypyxl-0.3.0.dist-info\RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Eve Freeman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: rustypyxl
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Classifier: Programming Language :: Rust
|
|
5
|
-
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
-
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
7
|
-
Requires-Python: >=3.10, <3.15
|
rustypyxl-0.1.0.dist-info/RECORD
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
rustypyxl\__init__.py,sha256=SXJtqXdgK5i8PgB-tOX0cEWwc5033yqhWtlg6PESgU4,119
|
|
2
|
-
rustypyxl\rustypyxl.cp310-win_amd64.pyd,sha256=g4mVUsQJIW0JEAL9wPw0ih2RwCxBMifTGCjGqhEeIT4,9469952
|
|
3
|
-
rustypyxl-0.1.0.dist-info\METADATA,sha256=T7d2bDujkfo4aKHHj-CHsIdQPywnvX5dx4SHjP5THkc,266
|
|
4
|
-
rustypyxl-0.1.0.dist-info\WHEEL,sha256=L_nHnx2hhpjVM_Xfu45p0kXGA_F4gVVL8EpDS6M9jpM,97
|
|
5
|
-
rustypyxl-0.1.0.dist-info\RECORD,,
|
|
File without changes
|