Spaces:
Sleeping
Sleeping
File size: 15,451 Bytes
dda717c afe94fd 06056ea afe94fd dda717c 58272c9 d09b116 06056ea d09b116 afe94fd dda717c 58272c9 afe94fd 58272c9 08b0c6f 58272c9 08b0c6f 58272c9 afe94fd 8fe937a 58272c9 afe94fd 06056ea afe94fd dda717c afe94fd 06056ea dda717c 58272c9 06056ea 58272c9 afe94fd 58272c9 8fe937a 58272c9 08b0c6f 06056ea 58272c9 8fe937a 58272c9 d09b116 58272c9 d09b116 58272c9 08b0c6f 58272c9 08b0c6f 58272c9 08b0c6f 58272c9 08b0c6f 58272c9 08b0c6f 58272c9 d09b116 58272c9 dda717c 06056ea d09b116 58272c9 06056ea | 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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 | import streamlit as st
import pandas as pd
import json
import io
import os
from datetime import datetime
import numpy as np
import base64
# Configure page
st.set_page_config(
page_title="Excel to JSON Converter",
page_icon="📊",
layout="wide"
)
# Debug information
with st.expander("Directory Structure"):
st.code(f"Current working directory: {os.getcwd()}")
st.code(f"Directory contents: {os.listdir('.')}")
# Check tmp directory
if os.path.exists('tmp'):
st.code(f"tmp directory exists: {os.path.exists('tmp')}")
st.code(f"tmp directory permissions: {oct(os.stat('tmp').st_mode)[-3:]}")
st.code(f"tmp directory is writable: {os.access('tmp', os.W_OK)}")
try:
st.code(f"tmp directory contents: {os.listdir('tmp')}")
except Exception as e:
st.error(f"Error listing tmp directory: {str(e)}")
else:
st.error("tmp directory does not exist!")
st.title("Excel to JSON Converter")
st.markdown("""
Upload an Excel file and convert it to a standard JSON format matching your template.
The app will maintain all the original columns and convert values to the appropriate format.
""")
def handle_nan(obj):
"""Convert NaN values to 0.0 to match your JSON format"""
if isinstance(obj, float) and np.isnan(obj):
return 0.0
return obj
def process_excel_data(excel_data, filename, sheet_name=None):
"""Process Excel file data"""
try:
# Try to read the Excel file
if sheet_name:
df = pd.read_excel(excel_data, sheet_name=sheet_name)
else:
df = pd.read_excel(excel_data)
# Show dimensions of the dataframe
st.info(f"Successfully read {df.shape[0]} rows and {df.shape[1]} columns from the Excel file")
# Fill NaN values
df = df.fillna(0.0)
# Convert dataframe to list of dictionaries (records)
result = {"DateStamp": datetime.now().isoformat(), "PriceList": []}
for _, row in df.iterrows():
record = {}
for column in df.columns:
# Convert pandas Timestamp to ISO format string if needed
if isinstance(row[column], pd.Timestamp):
record[column] = row[column].isoformat()
# Convert float values to match the format in examples
elif isinstance(row[column], (float, np.float64, np.float32)):
record[column] = float(row[column])
else:
record[column] = row[column]
# Add filename if it doesn't exist in the record
if "FileName" not in record:
record["FileName"] = filename
result["PriceList"].append(record)
# Convert to JSON string with indentation
json_str = json.dumps(result, indent=2, default=handle_nan)
return json_str, result
except Exception as e:
st.error(f"Error: {str(e)}")
import traceback
st.code(traceback.format_exc())
return None, None
def get_download_link(json_str, filename="converted_data.json"):
"""Generate a download link for the JSON file"""
b64 = base64.b64encode(json_str.encode()).decode()
href = f'<a href="data:file/json;base64,{b64}" download="{filename}">Download JSON File</a>'
return href
# Create tabs for different approaches
tab1, tab2 = st.tabs(["File Upload", "Sample Data Demo"])
with tab1:
st.info("For large files (>5MB), you may need to split them into smaller Excel files first.")
# File uploader
uploaded_file = st.file_uploader("Upload Excel File (.xlsx, .xls)", type=["xlsx", "xls"])
if uploaded_file is not None:
# Display success message
st.success(f"File uploaded: {uploaded_file.name}")
st.write(f"File size: {uploaded_file.size / 1024:.2f} KB")
try:
# Read Excel file into memory
excel_data = io.BytesIO(uploaded_file.getvalue())
try:
# Try to get sheet names
xls = pd.ExcelFile(excel_data)
sheet_names = xls.sheet_names
st.success(f"Successfully read {len(sheet_names)} sheets")
# Display available sheets
if len(sheet_names) > 1:
selected_sheet = st.selectbox("Select Sheet", options=sheet_names)
else:
selected_sheet = sheet_names[0]
st.info(f"Using sheet: {selected_sheet}")
# Process button
if st.button("Convert to JSON", type="primary"):
# Reset the file pointer
excel_data = io.BytesIO(uploaded_file.getvalue())
# Process the file
with st.spinner("Converting..."):
json_str, json_data = process_excel_data(excel_data, uploaded_file.name, selected_sheet)
if json_str and json_data:
st.success("Conversion successful!")
# Create tabs for different views
json_tab, table_tab, download_tab = st.tabs(["JSON Preview", "Table Preview", "Download"])
with json_tab:
# For large JSON, show only the first part
if len(json_str) > 100000:
st.warning("JSON is too large to display fully. Showing first 100,000 characters.")
st.code(json_str[:100000] + "...", language="json")
else:
st.code(json_str, language="json")
with table_tab:
if "PriceList" in json_data:
preview_df = pd.DataFrame(json_data["PriceList"])
if len(preview_df) > 1000:
st.write(f"Showing first 1000 rows of {len(json_data['PriceList'])} total")
st.dataframe(preview_df.head(1000), use_container_width=True)
else:
st.dataframe(preview_df, use_container_width=True)
with download_tab:
st.markdown(get_download_link(json_str, f"{os.path.splitext(uploaded_file.name)[0]}.json"), unsafe_allow_html=True)
st.info("Click the link above to download the JSON file.")
except Exception as e:
st.error(f"Error reading Excel file: {str(e)}")
import traceback
st.code(traceback.format_exc())
# Fallback: try simple conversion without sheet selection
if st.button("Try Simple Conversion"):
try:
# Reset the pointer and try simple conversion
excel_data = io.BytesIO(uploaded_file.getvalue())
json_str, _ = process_excel_data(excel_data, uploaded_file.name)
if json_str:
st.success("Simple conversion successful!")
# For large JSON, show only the first part
if len(json_str) > 100000:
st.warning("JSON is too large to display fully. Showing first 100,000 characters.")
st.code(json_str[:100000] + "...", language="json")
else:
st.code(json_str, language="json")
st.markdown(get_download_link(json_str, f"{os.path.splitext(uploaded_file.name)[0]}.json"), unsafe_allow_html=True)
except Exception as e2:
st.error(f"Simple conversion failed: {str(e2)}")
st.code(traceback.format_exc())
except Exception as e:
st.error(f"Error processing file: {str(e)}")
import traceback
st.code(traceback.format_exc())
with tab2:
st.info("This demo uses sample data to show how the converter works.")
# Create sample data
st.write("### Sample Data")
# Generate sample data that matches your expected format
sample_data = {
"Supplier": ["TestCompany", "TestCompany", "TestCompany"],
"Manufacturer": ["AJA", "AJA", "GRASS VALLEY"],
"ModelCode": ["TEST-001", "TEST-002", "TEST-003"],
"ModelDescription": ["Test Product 1", "Test Product 2", "Test Product 3"],
"T1List": [0.0, 100.0, 200.0],
"T1Cost": [0.0, 80.0, 160.0],
"T2List": [150.0, 250.0, 350.0],
"T2Cost": [120.0, 200.0, 280.0],
"ISOCurrency": ["EUR", "EUR", "USD"],
"ValidityDate": ["2025-12-31", "2025-12-31", "2025-12-31"],
"T1orT2": ["T2", "T2", "T2"],
"MaterialID": ["MAT-001", "MAT-002", "MAT-003"],
"SAPNumber": ["SAP-001", "SAP-002", "SAP-003"],
"ModelDescriptionEnglish": ["Test Product 1 in English", "Test Product 2 in English", "Test Product 3 in English"],
"QuoteOrPriceList": ["Price List", "Price List", "Price List"],
"WeightKg": [1.5, 2.0, 3.5],
"HeightMm": [100.0, 150.0, 200.0],
"LengthMm": [200.0, 250.0, 300.0],
"WidthMm": [150.0, 175.0, 225.0],
"PowerWatts": [50.0, 75.0, 100.0],
"FileName": ["SampleData.xlsx", "SampleData.xlsx", "SampleData.xlsx"]
}
# Convert to DataFrame
sample_df = pd.DataFrame(sample_data)
# Display the sample data
st.dataframe(sample_df)
# Allow user to edit the sample data
st.write("### Edit Sample Data (Optional)")
# Let user add a row
with st.expander("Add or Edit Rows"):
# Add simple editing capabilities
new_row = {}
col1, col2 = st.columns(2)
with col1:
new_row["Supplier"] = st.text_input("Supplier", "YourCompany")
new_row["Manufacturer"] = st.text_input("Manufacturer", "YourBrand")
new_row["ModelCode"] = st.text_input("ModelCode", "CUSTOM-001")
new_row["ModelDescription"] = st.text_input("ModelDescription", "Custom Product")
with col2:
new_row["T2List"] = st.number_input("T2List", value=499.99)
new_row["T2Cost"] = st.number_input("T2Cost", value=399.99)
new_row["ISOCurrency"] = st.selectbox("ISOCurrency", ["EUR", "USD", "GBP"])
new_row["ValidityDate"] = st.date_input("ValidityDate")
if st.button("Add Row to Sample Data"):
# Fill in missing fields with defaults
for col in sample_df.columns:
if col not in new_row:
if col == "FileName":
new_row[col] = "SampleData.xlsx"
elif "Date" in col:
new_row[col] = "2025-12-31"
elif sample_df[col].dtype == float:
new_row[col] = 0.0
else:
new_row[col] = ""
# Append the new row
sample_df = pd.concat([sample_df, pd.DataFrame([new_row])], ignore_index=True)
st.success("Row added!")
st.dataframe(sample_df)
# Convert button
if st.button("Convert Sample Data to JSON", key="convert2"):
json_str, json_data = process_excel_data(sample_df, "SampleData.xlsx")
if json_str and json_data:
st.success("Conversion successful!")
# Create tabs for different views
json_tab, table_tab, download_tab = st.tabs(["JSON", "Table", "Download"])
with json_tab:
st.code(json_str, language="json")
with table_tab:
if "PriceList" in json_data:
preview_df = pd.DataFrame(json_data["PriceList"])
st.dataframe(preview_df)
with download_tab:
st.markdown(get_download_link(json_str, "sample_data.json"), unsafe_allow_html=True)
st.info("Click the link above to download the JSON file.")
# Information about expected format
with st.expander("Expected Excel Format"):
st.markdown("""
Your Excel file should contain columns such as:
- Supplier
- Manufacturer
- ModelCode
- ModelDescription
- T1List
- T1Cost
- T2List
- T2Cost
- ISOCurrency
- ValidityDate
- T1orT2
- MaterialID
- SAPNumber
- ModelDescriptionEnglish
- ModelDescriptionLanguage2
- ModelDescriptionLanguage3
- ModelDescriptionLanguage4
- QuoteOrPriceList
- WeightKg
- HeightMm
- LengthMm
- WidthMm
- PowerWatts
- FileName
But the app will work with any Excel format, preserving your column structure.
""")
st.markdown("---")
# Add instructions for local usage
with st.expander("Run This App Locally"):
st.markdown("""
### Instructions for Running Locally
If you're encountering upload issues, you can run this app on your own computer:
1. Install Python if you don't have it already
2. Install the required packages:
```bash
pip install streamlit pandas openpyxl
```
3. Save this app code to a file named `app.py`
4. Run the app with:
```bash
streamlit run app.py
```
5. Access the app in your browser and upload your Excel files locally
### Alternative: Direct Excel to JSON Conversion Script
You can also use this simple Python script to convert Excel to JSON directly:
```python
import pandas as pd
import json
from datetime import datetime
# Replace with your Excel file path
excel_file = "your_file.xlsx"
# Read the Excel file
df = pd.read_excel(excel_file)
# Fill NaN values
df = df.fillna(0.0)
# Convert dataframe to list of dictionaries
result = {"DateStamp": datetime.now().isoformat(), "PriceList": []}
for _, row in df.iterrows():
record = {}
for column in df.columns:
# Convert pandas Timestamp to ISO format string
if isinstance(row[column], pd.Timestamp):
record[column] = row[column].isoformat()
# Convert float values
elif isinstance(row[column], float):
record[column] = float(row[column])
else:
record[column] = row[column]
# Add filename if it doesn't exist
if "FileName" not in record:
record["FileName"] = excel_file
result["PriceList"].append(record)
# Save to JSON file
with open("output.json", "w") as f:
json.dump(result, f, indent=2)
print(f"Conversion complete! JSON saved to output.json")
```
""")
# Add footer
st.markdown("---")
st.markdown("Excel to JSON Converter | Created with Streamlit") |