No project description provided
Project description
Easy Excel Management
A Rust-powered Python module for efficient Excel file manipulation.
-
Filling: Fill an existing sheet of an existing Excel file with data based on headers that are not necessarily in the first row of the sheet. Can handle Pandas, Polars and Dict of Lists. List of lists is also supported, provided the column names are provided too. Can handle overwriting existing data. Can skip nulls. Can handle strict matching of column names.
-
Copying: Copy a range of cells from one sheet of an Excel file to a sheet in another Excel file. Can handle transposing the range.
-
Transforming: Transform a range of cells from one sheet to another. Can handle summing, counting, averaging per row or column.
Installation
Install the module using pip
or your favorite package manager:
pip install ez-excel-mgt
Usage
Filling an existing sheet in an Excel file
Let's assume test.xls contains a sheet "Example" with with a few rows and columns. Let's assume the column names are contained in the third row.
Data can be provided in a Pandas, Polars, Dict of Lists or List of Lists (with column names specified in another argument).
Options
-
column: List of column names to use with a list of lists. This is optional if your DataFrame already has columns (Pandas, Polars or Dict).
-
header_row: Specifies the row containing the headers. Options:
- "first": The first row is used as the header.
- "last" (default): The last row is used as the header.
- Integer > 0: The specific row number (1-based index) where the header is located.
-
overwrite: If
True
, existing data will be overwritten. Default isFalse
. -
skip_nulls: If
True
, null values in the data will be skipped. Default isFalse
, which results in blanking cells for null values. -
strict: If
True
, enforces strict matching: all column names must match exactly.
Example
from typing import List, Dict, Any
from pathlib import Path
import pandas as pd
import polars as pl
import openpyxl
import ez_excel_mgt as ezex
# Create a template.xlsx file with a sheet named "Sheet1" and a header row at row 3
def create_template_excel(tmp_path: Path,
sheet_name: str,
metadata: List[str],
data: Dict[str, List[Any]]) -> int:
# Create a new workbook and add a sheet
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = sheet_name
# Add metadata rows
for i, row in enumerate(metadata):
sheet[f"A{i+1}"] = row
# Header row in row 3 (of the excel file)
for j, (name, values) in enumerate(data.items()):
sheet[f"{chr(65 + j)}{len(metadata)+1}"] = name
for i, v in enumerate(values):
sheet[f"{chr(65 + j)}{len(metadata)+i+1+1}"] = v
# Write to the temporary file
workbook.save(excel_path)
return len(metadata) + 1
if __name__ == "__main__":
sheet_name = "Example"
excel_path = Path("example.xlsx")
header_row = create_template_excel(excel_path,
sheet_name,
["A comment the first row", "Another in the second row"],
{"Name": ["Alice", "Bob", "Charlie"],
"Age": [25, 30, 35],
"Gender": ["F", "M", "M"],
"City": ["New York", "London", "Paris"]})
# Create a Pandas DataFrame
pandas_df = pd.DataFrame({
"Name": ["Anatole", "Erica", "Jules"],
"Age": [85, 15, 95]
})
# Call the function to append the Pandas DataFrame to the existing sheet
ezex.fill_sheet_with(pandas_df, str(excel_path), sheet_name, header_row=header_row)
# Create a Polars DataFrame
polars_df = pl.DataFrame({
"Name": ["Philippe", "Paul"],
"Age": [45, None],
"Gender": ["M", "M"]
})
# Call the function to append the PolarsDataFrame to the existing sheet
ezex.fill_sheet_with(polars_df, str(excel_path), sheet_name, header_row=header_row)
# Create a dictionary with the data to be written to the Excel file
dict_df = {
"Name": ["Michel", "Amelie"],
"Age": [35, 45],
"Gender": ["M", "F"],
"City": ["Paris", "London"]
}
# Read the Excel file into a Polars DataFrame
ezex.fill_sheet_with(dict_df, str(excel_path), sheet_name, header_row=header_row)
# Create a list of dictionaries with the data to be written to the Excel file
# Column names must be provided separately
columns = ["Age", "Gender", "City"]
# skip_null allows to skip None values, which combined with overwrite enables filling gaps or replacing specific values like a mask
list_df = [
[None, None, None, None, None, None, None, 55, None, None],
[None, None, None, "M", "F", "M", None, None, None, None],
[None, None, None, "Brussels", "Madrid", "Berlin", "Lisbon", "Montreal", None, None]
]
ezex.fill_sheet_with(list_df, str(excel_path), sheet_name, header_row=header_row, columns=columns, skip_null=True, overwrite=True)
df = pl.read_excel(source=excel_path, sheet_name=sheet_name,
engine='xlsx2csv', engine_options={"skip_empty_lines": True, "skip_hidden_rows": False},
read_options={"skip_rows": 2, "has_header": True, "infer_schema_length": 0})
print(df)
Copying a range of cells from one file/sheet to another file/sheet
Let's assume test.xls contains a sheet "Example" with with a few rows and columns. Let's assume the column names are contained in the first row.
Options
- transpose: If
True
, the range is transposed.
Example
import random
import polars as pl
import openpyxl
import ez_excel_mgt as ezex
# Function to convert a number to Excel column name
def excel_column(row: int, col: int) -> str:
column_name = ""
while row > 0:
row, remainder = divmod(row - 1, 26)
column_name = chr(65 + remainder) + column_name
return f"{column_name}{col}"
if __name__ == "__main__":
# Create a polars dataframe with 50 rows and 4 columns name Col 1, Col 2, Col 3, Col 4
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "Example"
for i in range(4):
sheet[excel_column(i+1, 1)] = f"Col {i+1}"
workbook.save("example_copy.xlsx")
df = pl.DataFrame({
"Col 1": [random.random() for _ in range(50)],
"Col 2": [random.random() for _ in range(50)],
"Col 3": [random.random() for _ in range(50)],
"Col 4": [random.random() for _ in range(50)]
})
ezex.fill_sheet_with(df, "example_copy.xlsx", "Example")
df = pl.read_excel(source="example_copy.xlsx", sheet_name="Example",
engine='xlsx2csv', engine_options={"skip_empty_lines": True, "skip_hidden_rows": False},
read_options={"has_header": True, "infer_schema_length": 0})
print(df)
# Open the destination excel file using openpyxl and create a new sheet named "Result", containing 50 headers in the first row named Row 1, Row 2, etc.
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "Result"
# Update the loop to use the new function for naming columns
for i in range(50):
sheet[excel_column(i+1, 1)] = f"Row {i+1}"
workbook.save("result_copy.xlsx")
# Call the function to copy the range of cells from the source file to the destination file (row, col; starting at 1)
ezex.copy_range_between_files("example_copy.xlsx", "Example", ((2, 1), (51, 4)),
"result_copy.xlsx", "Result", (2, 1), True)
df = pl.read_excel(source="result_copy.xlsx", sheet_name="Result",
engine='xlsx2csv', engine_options={"skip_empty_lines": True, "skip_hidden_rows": False},
read_options={"has_header": True, "infer_schema_length": 0})
print(df)
Copying and transforming a range of cells from one file/sheet to another file/sheet
Only works with numbers! Can handle summing, counting, averaging per row or column.
Let's assume test.xls contains a sheet "Example" with with a few rows and columns. Let's assume the column names are contained in the first row.
Options
- transpose: If
True
, the range is transposed.
Example
import random
import polars as pl
import openpyxl
import ez_excel_mgt as ezex
# Function to convert a number to Excel column name
def excel_column(row: int, col: int) -> str:
column_name = ""
while row > 0:
row, remainder = divmod(row - 1, 26)
column_name = chr(65 + remainder) + column_name
return f"{column_name}{col}"
if __name__ == "__main__":
# Create a polars dataframe with 50 rows and 4 columns name Col 1, Col 2, Col 3, Col 4
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "Example"
for i in range(4):
sheet[excel_column(i+1, 1)] = f"Col {i+1}"
workbook.save("example_copy.xlsx")
df = pl.DataFrame({
"Col 1": [random.random() for _ in range(50)],
"Col 2": [random.random() for _ in range(50)],
"Col 3": [random.random() for _ in range(50)],
"Col 4": [random.random() for _ in range(50)]
})
ezex.fill_sheet_with(df, "example_copy.xlsx", "Example")
df = pl.read_excel(source="example_copy.xlsx", sheet_name="Example",
engine='xlsx2csv', engine_options={"skip_empty_lines": True, "skip_hidden_rows": False},
read_options={"has_header": True, "infer_schema_length": 0})
print(df)
# Open the destination excel file using openpyxl and create a new sheet named "Result", containing 50 headers in the first row named Row 1, Row 2, etc.
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "Result"
# Update the loop to use the new function for naming columns
for i in range(50):
sheet[excel_column(i+1, 1)] = f"Row {i+1}"
workbook.save("result_copy.xlsx")
# Call the function to copy the range of cells from the source file to the destination file (row, col; starting at 1)
ezex.copy_range_between_files("example_copy.xlsx", "Example", ((2, 1), (51, 4)),
"result_copy.xlsx", "Result", (2, 1), True)
df = pl.read_excel(source="result_copy.xlsx", sheet_name="Result",
engine='xlsx2csv', engine_options={"skip_empty_lines": True, "skip_hidden_rows": False},
read_options={"has_header": True, "infer_schema_length": 0})
print(df)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
File details
Details for the file ez_excel_mgt-0.6.2.tar.gz
.
File metadata
- Download URL: ez_excel_mgt-0.6.2.tar.gz
- Upload date:
- Size: 103.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.11.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6717c30b46fc89bd0c8afcd7e12f75119259b3dce0099fbbbd0e4aed6ec952ca |
|
MD5 | ffda2a6509eebd491f768fc34807cb27 |
|
BLAKE2b-256 | 5bbf921ab4934567fb56d04178c73ebe8323fc03ba3d594a16b06f1027e54dea |
File details
Details for the file ez_excel_mgt-0.6.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl
.
File metadata
- Download URL: ez_excel_mgt-0.6.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl
- Upload date:
- Size: 5.3 MB
- Tags: PyPy, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.11.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d25a482e38022967523ee8e47a18e894e9f22c908394b8064ff5d88504f5a83a |
|
MD5 | 14317aad7b4943e4848aa4a882094d8f |
|
BLAKE2b-256 | 1cd42ec506c0082168a04a2565a4cd641fa0a98dfc4e6df83c9003a33085d8d0 |
File details
Details for the file ez_excel_mgt-0.6.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl
.
File metadata
- Download URL: ez_excel_mgt-0.6.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl
- Upload date:
- Size: 5.3 MB
- Tags: PyPy, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.11.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 62d50024691016cd2b3a2a0529590d36b90293c63dc35b839f77bc192d656d42 |
|
MD5 | 507f4c8b556fa5994b78a2047b95cccd |
|
BLAKE2b-256 | c3f667db3fbf5e4b7ec990be951bf37597970ef5794dc7602da3320cda7e6e87 |
File details
Details for the file ez_excel_mgt-0.6.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl
.
File metadata
- Download URL: ez_excel_mgt-0.6.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl
- Upload date:
- Size: 5.3 MB
- Tags: PyPy, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.11.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 75af7a56464be4a083415ffd5178cabf1c0dcafc0f74a6625bb5c023d3d365de |
|
MD5 | 8240393d9608ecb0790264a2f46ca167 |
|
BLAKE2b-256 | 3c627f470eac5fd6476265b729122cdce5a8979c468c1f39d76c246018648dcb |
File details
Details for the file ez_excel_mgt-0.6.2-cp312-cp312-macosx_11_0_arm64.whl
.
File metadata
- Download URL: ez_excel_mgt-0.6.2-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 5.3 MB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.11.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0f56aac4ad29372e711ecc4d44b7508aabcdf96664805588ac5c84d8c25bcbde |
|
MD5 | bef0a2824beee1b72f59f1ff5ba935f7 |
|
BLAKE2b-256 | 88b1d402e9bb240d0ee66184bb5e7acada3cec9a019c48d641cf576875ff2c08 |
File details
Details for the file ez_excel_mgt-0.6.2-cp311-cp311-macosx_11_0_arm64.whl
.
File metadata
- Download URL: ez_excel_mgt-0.6.2-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 5.3 MB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.11.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3e55093eb30ffce456d0e91e469dd6cbebad92c2dc2f64281c98a9f7992d749f |
|
MD5 | b6cdb0fc65d06c3c86a0bd0a72bc8351 |
|
BLAKE2b-256 | d6f480d6e4b1ce39bab39860bc835b05f4fe91e661216b74e05770bdadd0b1e0 |
File details
Details for the file ez_excel_mgt-0.6.2-cp310-cp310-macosx_11_0_arm64.whl
.
File metadata
- Download URL: ez_excel_mgt-0.6.2-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 5.3 MB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.11.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f564e847c474c7eba37c80530739ae3c794942ded2472c8aa85ce011bf00dad8 |
|
MD5 | 265ade0b35fdf29a0ca3a64b046482af |
|
BLAKE2b-256 | 1bf9393736896f25f5db29c65c75e3395a4db1acafdf6ef4cd176982aa644a0e |