File size: 2,965 Bytes
fd90193
c58c1d8
 
fd90193
 
 
 
1f99de8
fd90193
04f69e7
c58c1d8
 
fd90193
c58c1d8
c325e25
fd90193
c58c1d8
c325e25
c58c1d8
 
04f69e7
c58c1d8
04f69e7
 
 
 
 
c58c1d8
c325e25
04f69e7
 
c325e25
 
 
 
04f69e7
c325e25
 
 
04f69e7
c325e25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
04f69e7
 
 
c325e25
 
 
 
 
 
1f99de8
04f69e7
 
 
fd90193
1f99de8
fd90193
 
c58c1d8
 
fd90193
 
c58c1d8
 
fd90193
 
 
c58c1d8
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import io
import os
import tempfile
from numbers_parser import Document
from openpyxl import Workbook
import gradio as gr
import pandas as pd
from pathlib import Path

def numbers_to_xlsx(numbers_file):
    """
    Efficiently converts a Numbers file to XLSX format with optimized memory usage.

    Args:
        numbers_file: The uploaded Numbers file object from Gradio.

    Returns:
        str: Path to the converted xlsx file, or None if conversion fails.
    """
    if not numbers_file:
        return None
    
    try:
        # Create output directory if it doesn't exist
        output_dir = "outputs"
        os.makedirs(output_dir, exist_ok=True)
        output_path = os.path.join(output_dir, "converted.xlsx")
        
        # Read the Numbers file efficiently using the temporary path
        doc = Document(numbers_file.name)
        
        # Get all sheets and validate
        sheets = doc.sheets
        if not sheets:
            print("No sheets found in the document")
            return None
            
        # Process each sheet
        writer = pd.ExcelWriter(output_path, engine='openpyxl')
        
        for sheet_index, sheet in enumerate(sheets):
            if not sheet.tables:
                continue
                
            # Get the first table in the sheet
            table = sheet.tables[0]
            
            # Extract data
            rows = list(table.rows(values_only=True))
            if not rows:
                continue
                
            # Split headers and data
            headers = rows[0] if rows else []
            data = rows[1:] if len(rows) > 1 else []
            
            # Create DataFrame and write to Excel
            df = pd.DataFrame(data, columns=headers)
            sheet_name = f"Sheet{sheet_index + 1}"
            
            df.to_excel(
                writer,
                sheet_name=sheet_name,
                index=False
            )
            
            # Freeze the header row
            writer.sheets[sheet_name].freeze_panes = 'A2'
        
        writer.close()
        
        # Verify the file was created and has content
        if os.path.exists(output_path) and os.path.getsize(output_path) > 0:
            return output_path
        else:
            print("Output file is empty or was not created")
            return None
            
    except Exception as e:
        print(f"Error converting file: {str(e)}")
        return None

# 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()