Spaces:
Sleeping
Sleeping
import io | |
import os | |
import tempfile | |
from numbers_parser import Document | |
from openpyxl import Workbook | |
import gradio as gr | |
import pandas as pd | |
from typing import Union | |
from pathlib import Path | |
def numbers_to_xlsx(numbers_file) -> Union[str, tuple[str, bytes]]: | |
""" | |
Efficiently converts a Numbers file to XLSX format with optimized memory usage. | |
Args: | |
numbers_file: The uploaded Numbers file object. | |
Returns: | |
Union[str, tuple[str, bytes]]: Either error message or tuple of (filename, file_content) | |
""" | |
if not numbers_file: | |
return "Please upload a Numbers file" | |
# Create a temporary directory with context management | |
with tempfile.TemporaryDirectory() as temp_dir: | |
output_path = os.path.join(temp_dir, "converted.xlsx") | |
try: | |
# Read the Numbers file efficiently | |
doc = Document(numbers_file.name) | |
# Validate document structure | |
if not doc.sheets or not doc.sheets[0].tables: | |
return "Invalid Numbers file: No data tables found" | |
# Get the first table's data efficiently | |
table = doc.sheets[0].tables[0] | |
# Extract headers and data in one pass | |
rows = list(table.rows(values_only=True)) | |
if not rows: | |
return "No data found in the table" | |
headers = rows[0] | |
data = rows[1:] | |
# Use pandas optimized DataFrame construction | |
df = pd.DataFrame(data, columns=headers) | |
# Optimize Excel writing with correct options | |
writer = pd.ExcelWriter( | |
output_path, | |
engine='openpyxl' | |
) | |
df.to_excel( | |
writer, | |
index=False, | |
sheet_name='Sheet1' | |
) | |
# Freeze the header row using openpyxl directly | |
writer.sheets['Sheet1'].freeze_panes = 'A2' | |
writer.close() | |
# Return filename and content as tuple | |
return ("converted.xlsx", Path(output_path).read_bytes()) | |
except Exception as e: | |
return f"Error converting file: {str(e)}" | |
# Define the Gradio interface with correct file handling | |
interface = gr.Interface( | |
fn=numbers_to_xlsx, | |
inputs=gr.File(label="Numbers File", file_types=[".numbers"]), | |
outputs=gr.File(label="XLSX file", file_types=[".xlsx"]), | |
title="Numbers to XLSX Converter", | |
description="Convert your Numbers files to Excel format easily and download the result.", | |
examples=None, | |
cache_examples=False | |
) | |
# Launch the Gradio app | |
if __name__ == "__main__": | |
interface.launch() | |