python-calamine 0.5.4__cp314-cp314-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.
- python_calamine/__init__.py +29 -0
- python_calamine/_python_calamine.cp314-win_amd64.pyd +0 -0
- python_calamine/_python_calamine.pyi +194 -0
- python_calamine/py.typed +0 -0
- python_calamine-0.5.4.dist-info/METADATA +94 -0
- python_calamine-0.5.4.dist-info/RECORD +8 -0
- python_calamine-0.5.4.dist-info/WHEEL +4 -0
- python_calamine-0.5.4.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from ._python_calamine import (
|
|
2
|
+
CalamineError,
|
|
3
|
+
CalamineSheet,
|
|
4
|
+
CalamineWorkbook,
|
|
5
|
+
PasswordError,
|
|
6
|
+
SheetMetadata,
|
|
7
|
+
SheetTypeEnum,
|
|
8
|
+
SheetVisibleEnum,
|
|
9
|
+
WorkbookClosed,
|
|
10
|
+
WorksheetNotFound,
|
|
11
|
+
XmlError,
|
|
12
|
+
ZipError,
|
|
13
|
+
load_workbook,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = (
|
|
17
|
+
"CalamineError",
|
|
18
|
+
"CalamineSheet",
|
|
19
|
+
"CalamineWorkbook",
|
|
20
|
+
"PasswordError",
|
|
21
|
+
"SheetMetadata",
|
|
22
|
+
"SheetTypeEnum",
|
|
23
|
+
"SheetVisibleEnum",
|
|
24
|
+
"WorksheetNotFound",
|
|
25
|
+
"XmlError",
|
|
26
|
+
"ZipError",
|
|
27
|
+
"WorkbookClosed",
|
|
28
|
+
"load_workbook",
|
|
29
|
+
)
|
|
Binary file
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
import datetime
|
|
5
|
+
import enum
|
|
6
|
+
import os
|
|
7
|
+
import types
|
|
8
|
+
import typing
|
|
9
|
+
|
|
10
|
+
@typing.type_check_only
|
|
11
|
+
class ReadBuffer(typing.Protocol):
|
|
12
|
+
def seek(self, __offset: int, __whence: int = ...) -> int: ...
|
|
13
|
+
def read(self, __size: int = ...) -> bytes | None: ...
|
|
14
|
+
|
|
15
|
+
@typing.final
|
|
16
|
+
class SheetTypeEnum(enum.Enum):
|
|
17
|
+
WorkSheet = ...
|
|
18
|
+
DialogSheet = ...
|
|
19
|
+
MacroSheet = ...
|
|
20
|
+
ChartSheet = ...
|
|
21
|
+
Vba = ...
|
|
22
|
+
|
|
23
|
+
@typing.final
|
|
24
|
+
class SheetVisibleEnum(enum.Enum):
|
|
25
|
+
Visible = ...
|
|
26
|
+
Hidden = ...
|
|
27
|
+
VeryHidden = ...
|
|
28
|
+
|
|
29
|
+
@typing.final
|
|
30
|
+
class SheetMetadata:
|
|
31
|
+
name: str
|
|
32
|
+
typ: SheetTypeEnum
|
|
33
|
+
visible: SheetVisibleEnum
|
|
34
|
+
|
|
35
|
+
def __init__(
|
|
36
|
+
self, name: str, typ: SheetTypeEnum, visible: SheetVisibleEnum
|
|
37
|
+
) -> None: ...
|
|
38
|
+
|
|
39
|
+
@typing.final
|
|
40
|
+
class CalamineSheet:
|
|
41
|
+
name: str
|
|
42
|
+
@property
|
|
43
|
+
def height(self) -> int: ...
|
|
44
|
+
@property
|
|
45
|
+
def width(self) -> int: ...
|
|
46
|
+
@property
|
|
47
|
+
def total_height(self) -> int: ...
|
|
48
|
+
@property
|
|
49
|
+
def total_width(self) -> int: ...
|
|
50
|
+
@property
|
|
51
|
+
def start(self) -> tuple[int, int] | None: ...
|
|
52
|
+
@property
|
|
53
|
+
def end(self) -> tuple[int, int] | None: ...
|
|
54
|
+
def to_python(
|
|
55
|
+
self, skip_empty_area: bool = True, nrows: int | None = None
|
|
56
|
+
) -> list[
|
|
57
|
+
list[
|
|
58
|
+
int
|
|
59
|
+
| float
|
|
60
|
+
| str
|
|
61
|
+
| bool
|
|
62
|
+
| datetime.time
|
|
63
|
+
| datetime.date
|
|
64
|
+
| datetime.datetime
|
|
65
|
+
| datetime.timedelta
|
|
66
|
+
]
|
|
67
|
+
]:
|
|
68
|
+
"""Retunrning data from sheet as list of lists.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
skip_empty_area (bool):
|
|
72
|
+
By default, calamine skips empty rows/cols before data.
|
|
73
|
+
For suppress this behaviour, set `skip_empty_area` to `False`.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def iter_rows(
|
|
77
|
+
self,
|
|
78
|
+
) -> typing.Iterator[
|
|
79
|
+
list[
|
|
80
|
+
int
|
|
81
|
+
| float
|
|
82
|
+
| str
|
|
83
|
+
| bool
|
|
84
|
+
| datetime.time
|
|
85
|
+
| datetime.date
|
|
86
|
+
| datetime.datetime
|
|
87
|
+
| datetime.timedelta
|
|
88
|
+
]
|
|
89
|
+
]:
|
|
90
|
+
"""Retunrning data from sheet as iterator of lists."""
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def merged_cell_ranges(
|
|
94
|
+
self,
|
|
95
|
+
) -> list[tuple[tuple[int, int], tuple[int, int]]] | None:
|
|
96
|
+
"""Return a copy of merged cell ranges.
|
|
97
|
+
|
|
98
|
+
Support only for xlsx/xls.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
list of merged cell ranges (tuple[start coordinate, end coordinate]) or None for unsuported format
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
@typing.final
|
|
105
|
+
class CalamineWorkbook(contextlib.AbstractContextManager):
|
|
106
|
+
path: str | None
|
|
107
|
+
sheet_names: list[str]
|
|
108
|
+
sheets_metadata: list[SheetMetadata]
|
|
109
|
+
@classmethod
|
|
110
|
+
def from_object(
|
|
111
|
+
cls, path_or_filelike: str | os.PathLike | ReadBuffer
|
|
112
|
+
) -> "CalamineWorkbook":
|
|
113
|
+
"""Determining type of pyobject and reading from it.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
path_or_filelike (str | os.PathLike | ReadBuffer): path to file or IO (must imlpement read/seek methods).
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
@classmethod
|
|
120
|
+
def from_path(cls, path: str | os.PathLike) -> "CalamineWorkbook":
|
|
121
|
+
"""Reading file from path.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
path (str | os.PathLike): path to file.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
@classmethod
|
|
128
|
+
def from_filelike(cls, filelike: ReadBuffer) -> "CalamineWorkbook":
|
|
129
|
+
"""Reading file from IO.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
filelike : IO (must imlpement read/seek methods).
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
def close(self) -> None:
|
|
136
|
+
"""Close the workbook.
|
|
137
|
+
|
|
138
|
+
Drop internal rust structure from workbook (and close the file under the hood).
|
|
139
|
+
`get_sheet_by_name`/`get_sheet_by_index` will raise WorkbookClosed after calling that method.
|
|
140
|
+
|
|
141
|
+
Raises:
|
|
142
|
+
WorkbookClosed: If workbook already closed.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
def __enter__(self) -> "CalamineWorkbook": ...
|
|
146
|
+
def __exit__(
|
|
147
|
+
self,
|
|
148
|
+
exc_type: type[BaseException] | None,
|
|
149
|
+
exc_val: BaseException | None,
|
|
150
|
+
exc_tb: types.TracebackType | None,
|
|
151
|
+
) -> None: ...
|
|
152
|
+
def get_sheet_by_name(self, name: str) -> CalamineSheet:
|
|
153
|
+
"""Get worksheet by name.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
name(str): name of worksheet
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
CalamineSheet
|
|
160
|
+
|
|
161
|
+
Raises:
|
|
162
|
+
WorkbookClosed: If workbook already closed.
|
|
163
|
+
WorksheetNotFound: If worksheet not found in workbook.
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
def get_sheet_by_index(self, index: int) -> CalamineSheet:
|
|
167
|
+
"""Get worksheet by index.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
index(int): index of worksheet
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
CalamineSheet
|
|
174
|
+
|
|
175
|
+
Raises:
|
|
176
|
+
WorkbookClosed: If workbook already closed.
|
|
177
|
+
WorksheetNotFound: If worksheet not found in workbook.
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
class CalamineError(Exception): ...
|
|
181
|
+
class PasswordError(CalamineError): ...
|
|
182
|
+
class WorksheetNotFound(CalamineError): ...
|
|
183
|
+
class XmlError(CalamineError): ...
|
|
184
|
+
class ZipError(CalamineError): ...
|
|
185
|
+
class WorkbookClosed(CalamineError): ...
|
|
186
|
+
|
|
187
|
+
def load_workbook(
|
|
188
|
+
path_or_filelike: str | os.PathLike | ReadBuffer,
|
|
189
|
+
) -> CalamineWorkbook:
|
|
190
|
+
"""Determining type of pyobject and reading from it.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
path_or_filelike (str | os.PathLike | ReadBuffer): path to file or IO (must imlpement read/seek methods).
|
|
194
|
+
"""
|
python_calamine/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: python-calamine
|
|
3
|
+
Version: 0.5.4
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Programming Language :: Rust
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Summary: Python binding for Rust's library for reading excel and odf file - calamine
|
|
13
|
+
Author-email: Dmitriy <dimastbk@proton.me>
|
|
14
|
+
License-Expression: MIT
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
17
|
+
Project-URL: homepage, https://github.com/dimastbk/python-calamine
|
|
18
|
+
Project-URL: source, https://github.com/dimastbk/python-calamine
|
|
19
|
+
|
|
20
|
+
# python-calamine
|
|
21
|
+
[](https://pypi.org/project/python-calamine/)
|
|
22
|
+
[](https://anaconda.org/conda-forge/python-calamine)
|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
Python binding for beautiful Rust's library for reading excel and odf file - [calamine](https://github.com/tafia/calamine).
|
|
27
|
+
|
|
28
|
+
### Is used
|
|
29
|
+
* [calamine](https://github.com/tafia/calamine)
|
|
30
|
+
* [pyo3](https://github.com/PyO3/pyo3)
|
|
31
|
+
* [maturin](https://github.com/PyO3/maturin)
|
|
32
|
+
|
|
33
|
+
### Installation
|
|
34
|
+
Pypi:
|
|
35
|
+
```
|
|
36
|
+
pip install python-calamine
|
|
37
|
+
```
|
|
38
|
+
Conda:
|
|
39
|
+
```
|
|
40
|
+
conda install -c conda-forge python-calamine
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Example
|
|
44
|
+
```python
|
|
45
|
+
from python_calamine import CalamineWorkbook
|
|
46
|
+
|
|
47
|
+
workbook = CalamineWorkbook.from_path("file.xlsx")
|
|
48
|
+
workbook.sheet_names
|
|
49
|
+
# ["Sheet1", "Sheet2"]
|
|
50
|
+
|
|
51
|
+
workbook.get_sheet_by_name("Sheet1").to_python()
|
|
52
|
+
# [
|
|
53
|
+
# ["1", "2", "3", "4", "5", "6", "7"],
|
|
54
|
+
# ["1", "2", "3", "4", "5", "6", "7"],
|
|
55
|
+
# ["1", "2", "3", "4", "5", "6", "7"],
|
|
56
|
+
# ]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
By default, calamine skips empty rows/cols before data. For suppress this behaviour, set `skip_empty_area` to `False`.
|
|
60
|
+
```python
|
|
61
|
+
from python_calamine import CalamineWorkbook
|
|
62
|
+
|
|
63
|
+
workbook = CalamineWorkbook.from_path("file.xlsx").get_sheet_by_name("Sheet1").to_python(skip_empty_area=False)
|
|
64
|
+
# [
|
|
65
|
+
# [", ", ", ", ", ", "],
|
|
66
|
+
# ["1", "2", "3", "4", "5", "6", "7"],
|
|
67
|
+
# ["1", "2", "3", "4", "5", "6", "7"],
|
|
68
|
+
# ["1", "2", "3", "4", "5", "6", "7"],
|
|
69
|
+
# ]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Pandas 2.2 and above have built-in support of python-calamine.
|
|
73
|
+
|
|
74
|
+
Also, you can find additional examples in [tests](https://github.com/dimastbk/python-calamine/blob/master/tests/test_base.py).
|
|
75
|
+
|
|
76
|
+
### Development
|
|
77
|
+
|
|
78
|
+
You'll need rust [installed](https://rustup.rs/).
|
|
79
|
+
|
|
80
|
+
```shell
|
|
81
|
+
# clone this repo or your fork
|
|
82
|
+
git clone git@github.com:dimastbk/python-calamine.git
|
|
83
|
+
cd python-calamine
|
|
84
|
+
# create a new virtual env
|
|
85
|
+
python3 -m venv env
|
|
86
|
+
source env/bin/activate
|
|
87
|
+
# install dev dependencies and install python-calamine
|
|
88
|
+
pip install --group dev -e . # required pip 25.1 and above
|
|
89
|
+
# lint code
|
|
90
|
+
pre-commit run --all-files
|
|
91
|
+
# test code
|
|
92
|
+
pytest
|
|
93
|
+
```
|
|
94
|
+
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
python_calamine-0.5.4.dist-info/METADATA,sha256=4qIwE4vvK-7u-ECbM6mLTJCrz2QgoXocJBqmpruUw7g,3171
|
|
2
|
+
python_calamine-0.5.4.dist-info/WHEEL,sha256=tZ3VAZ5HuUzziFCJ2lDsDJnJO-xy4omAQIa7TJCFCZk,96
|
|
3
|
+
python_calamine-0.5.4.dist-info/licenses/LICENSE,sha256=cYURXgSnjCTOT2jQ_McTGn-AhDycRqzJa11QzR38Sn4,1086
|
|
4
|
+
python_calamine/__init__.py,sha256=evxSwIkpatTkygn2mRmWUYPslvdj08q_pNkayyyptfI,560
|
|
5
|
+
python_calamine/_python_calamine.cp314-win_amd64.pyd,sha256=m5M3gdbQYn74t4EeJhCrmm2uGWLUyk1h8jfOl_q_XJ4,1607168
|
|
6
|
+
python_calamine/_python_calamine.pyi,sha256=4kE2AwHusUij-T6XtSVhujFlPuZVm9Ywz3eIFi_yIBc,5330
|
|
7
|
+
python_calamine/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
python_calamine-0.5.4.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 dimastbk
|
|
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.
|