Added Pandas Load Excel node to read Excel file and added dependency on openpyxl package.

This commit is contained in:
HowToSD
2025-03-05 03:38:01 -08:00
parent b881244d0c
commit ed1cef099e
9 changed files with 152 additions and 3 deletions
+3 -1
View File
@@ -1,5 +1,7 @@
__pycache__/
**/__pycache__/
datasets/
models/
*.pth
/datasets/
!*/foo/
examples/datasets/.~lock*
+3
View File
@@ -67,6 +67,7 @@ from .modules.pandas_wrapper.pandas_kurtosis import PandasKurtosis
from .modules.pandas_wrapper.pandas_load_csv import PandasLoadCSV
from .modules.pandas_wrapper.pandas_load_csv_with_encoding import PandasLoadCSVWithEncoding
from .modules.pandas_wrapper.pandas_load_csv_with_index import PandasLoadCSVWithIndex
from .modules.pandas_wrapper.pandas_load_excel import PandasLoadExcel
from .modules.pandas_wrapper.pandas_load_html import PandasLoadHTML
from .modules.pandas_wrapper.pandas_load_json import PandasLoadJSON
from .modules.pandas_wrapper.pandas_loc_cell_str import PandasLocCellStr
@@ -300,6 +301,7 @@ NODE_CLASS_MAPPINGS: Dict[str, Type[T]] = {
"PandasLoadCSV": PandasLoadCSV,
"PandasLoadCSVWithEncoding": PandasLoadCSVWithEncoding,
"PandasLoadCSVWithIndex": PandasLoadCSVWithIndex,
"PandasLoadExcel": PandasLoadExcel,
"PandasLoadHTML": PandasLoadHTML,
"PandasLoadJSON": PandasLoadJSON,
"PandasLocCellStr": PandasLocCellStr,
@@ -536,6 +538,7 @@ NODE_DISPLAY_NAME_MAPPINGS: Dict[str, str] = {
"PandasLoadCSV": "Pandas Load CSV",
"PandasLoadCSVWithEncoding": "Pandas Load CSV With Encoding",
"PandasLoadCSVWithIndex": "Pandas Load CSV With Index",
"PandasLoadExcel": "Pandas Load Excel",
"PandasLoadHTML": "Pandas Load HTML",
"PandasLoadJSON": "Pandas Load JSON",
"PandasLocCellStr": "Pandas Loc Cell Str",
+1
View File
@@ -109,6 +109,7 @@
| [Pandas Load CSV](pandas_load_csv.md) | Loads CSV files into a pandas DataFrame. |
| [Pandas Load CSV With Encoding](pandas_load_csv_with_encoding.md) | Loads CSV files into a pandas DataFrame. |
| [Pandas Load CSV With Index](pandas_load_csv_with_index.md) | Loads CSV files into a pandas DataFrame. |
| [Pandas Load Excel](pandas_load_excel.md) | Loads Excel files into a pandas DataFrame. |
| [Pandas Load HTML](pandas_load_html.md) | Scans an HTML file or webpage for tables and returns the number of DataFrames |
| [Pandas Load JSON](pandas_load_json.md) | Loads JSON files into a pandas DataFrame. |
| [Pandas Save CSV](pandas_save_csv.md) | Saves a PandasDataFrame to a CSV file. |
+23
View File
@@ -0,0 +1,23 @@
# Pandas Load Excel
Loads Excel files into a pandas DataFrame.
This node uses read_excel method.
See [Pandas documentation](https://pandas.pydata.org/docs/reference/api/pandas.read_excel.html) for details.
If sheet_name is not specified, first sheet will be read.
## Input
| Name | Data type |
|---|---|
| file_path | String |
| sheet_name | String |
## Output
| Data type |
|---|
| DataFrame |
<HR>
Category: IO
ComfyUI Data Analysis Node Reference. © 2025 Hide Inada (HowToSD.com). All rights reserved.
Binary file not shown.
@@ -0,0 +1,55 @@
from typing import Any, Dict
from io import StringIO
import pandas as pd
class PandasLoadExcel:
"""
Loads Excel files into a pandas DataFrame.
This node uses read_excel method.
See [Pandas documentation](https://pandas.pydata.org/docs/reference/api/pandas.read_excel.html) for details.
If sheet_name is not specified, first sheet will be read.
category: IO
"""
@classmethod
def INPUT_TYPES(cls) -> Dict[str, Any]:
"""
Defines the input types for the `load_csv` function.
Returns:
Dict[str, Any]: A dictionary specifying required input types.
"""
return {
"required": {
"file_path": ("STRING", {"multiline": False}),
"sheet_name": ("STRING", {"default": ""}),
}
}
RETURN_TYPES: tuple = ("DATAFRAME",)
FUNCTION: str = "f"
CATEGORY: str = "Data Analysis"
@classmethod
def IS_CHANGED(cls, **kw):
return float("NaN")
def f(self, file_path: str, sheet_name: str) -> tuple:
"""
Loads an Excel file into a pandas DataFrame.
Args:
file_path (str): The path to the Excel file.
Returns:
tuple: A tuple containing a DataFrame.
"""
if len(sheet_name) == 0:
sheet_name = 0 # Read first sheet
df = pd.read_excel(file_path, sheet_name=sheet_name)
return (df,)
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "data-analysis"
description = "Data analysis custom modules for ComfyUI – Integrates Pandas, Seaborn and Matplotlib into ComfyUI, featuring extensive PyTorch wrapper nodes for seamless tensor operations. Experimental PyTorch model training was added in v2.0."
version = "2.0.4"
version = "2.0.5"
license = {file = "LICENSE"}
[project.urls]
+2 -1
View File
@@ -2,4 +2,5 @@ matplotlib>=3.10.0
pandas>=2.2.3
seaborn>=0.13.2
scipy>=1.14.1
scikit-learn>=1.6.1
scikit-learn>=1.6.1
openpyxl>=3.1.5
@@ -0,0 +1,64 @@
import os
import sys
import unittest
import pandas as pd
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), "..", ".."))
MODULE_ROOT = os.path.join(PROJECT_ROOT, "modules")
sys.path.append(MODULE_ROOT)
from pandas_wrapper.pandas_load_excel import PandasLoadExcel
class TestPandasLoadExcel(unittest.TestCase):
def setUp(self):
"""Set up test data."""
self.node = PandasLoadExcel()
self.test_file_path = os.path.join(
os.path.dirname(__file__), "..", "..",
"examples", "datasets", "test_file.xlsx")
self.test_data_list = [
(
"Sheet1",
pd.DataFrame(
{
"Item": ["Bat", "Racquet", "Glove", "Hockey stick", "Soccer ball"],
"Qty": [3, 4, 5, 6, 7]
},
index = [0, 1, 2, 3, 4]
),
),
(
"FruitPrice",
pd.DataFrame(
{
"Fruit": ["Apple", "Banana", "Coconut", "Donut"],
"Price": [1.23, 2.34, 3.45, 4.56]
},
index = [0, 1, 2, 3]
)
),
(
"", # Leaving the sheet name blank should read the first sheet.
pd.DataFrame(
{
"Item": ["Bat", "Racquet", "Glove", "Hockey stick", "Soccer ball"],
"Qty": [3, 4, 5, 6, 7]
},
index = [0, 1, 2, 3, 4]
),
),
]
def test_read_excel(self):
"""Reads multiple sheets from an excel file.
"""
for test_data in self.test_data_list:
with self.subTest(test_data=test_data):
sheet_name = test_data[0]
expected = test_data[1]
df = self.node.f(self.test_file_path, sheet_name=sheet_name)[0]
pd.testing.assert_frame_equal(df, expected)
if __name__ == "__main__":
unittest.main()