Spaces:
Sleeping
Sleeping
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
""" | |
Excel Column Remover and Signature Adder | |
A simple Gradio app that removes first 2 columns and adds signature lines to Excel files. | |
""" | |
import gradio as gr | |
import pandas as pd | |
import tempfile | |
import os | |
from datetime import datetime | |
def process_excel_file(input_file): | |
""" | |
Process Excel file by removing first 2 columns and adding signature lines | |
Args: | |
input_file: Gradio file input object | |
Returns: | |
tuple: (output_file_path, success_message, preview_data) | |
""" | |
try: | |
# Create output filename | |
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
output_filename = f"processed_report_{timestamp}.xlsx" | |
output_path = os.path.join(tempfile.gettempdir(), output_filename) | |
# Read Excel file | |
df = pd.read_excel(input_file.name, header=None) | |
print(f"Original shape: {df.shape}") | |
# Extract first 4 header rows and clean them (remove extra spaces) | |
header_rows = [] | |
for i in range(min(4, len(df))): | |
row_data = df.iloc[i].dropna().astype(str).tolist() | |
if row_data: | |
# Take first non-empty cell and clean it | |
header_text = str(row_data[0]).strip() | |
header_rows.append([header_text]) | |
else: | |
header_rows.append(['']) | |
# Remove first 2 columns from all data (including headers) | |
df_processed = df.iloc[:, 2:] # Keep from column 2 onwards | |
print(f"After removing first 2 columns: {df_processed.shape}") | |
# Reset column indices | |
df_processed = df_processed.reset_index(drop=True) | |
df_processed.columns = range(len(df_processed.columns)) | |
# Create the final structure: | |
# 1. First 4 header rows (cleaned) | |
# 2. Original data from column 3 onwards | |
# 3. Signature lines | |
final_data = [] | |
# Add cleaned header rows | |
for header in header_rows: | |
final_data.append(header) | |
# Add empty separator row | |
final_data.append([]) | |
# Add the rest of the data (starting from row 5 in original, which is row 0 after removing first 4) | |
data_start_row = 4 # Skip first 4 header rows we already added | |
for i in range(data_start_row, len(df_processed)): | |
row_data = df_processed.iloc[i].tolist() | |
final_data.append(row_data) | |
# Add signature lines at the end | |
signature_lines = [ | |
[], # Empty row | |
[], # Empty row | |
[], # Empty row | |
["กรรมการ", "", "กรรมการ", "", "กรรมการ"], | |
[], # Empty row | |
[], # Empty row | |
["ผู้ได้รับมอบหมายให้รับเงินและเอกสารแทนตัวเงินตามรายละเอียดข้างต้น ไปแล้ว"], | |
[], # Empty row | |
[], # Empty row | |
[], # Empty row | |
["ลงชื่อ.................................................(ผู้รับเงิน)"], | |
[], # Empty row | |
[], # Empty row | |
["ลงชื่อ.................................................(หัวหน้าหน่วยงานย่อยผู้มอบหมาย)"] | |
] | |
# Add signature lines | |
for signature_line in signature_lines: | |
final_data.append(signature_line) | |
# Create final dataframe | |
final_df = pd.DataFrame(final_data) | |
# Make sure all columns are filled | |
max_cols = max([len(row) for row in final_data if row]) | |
final_df = final_df.reindex(columns=range(max_cols)) | |
# Fill NaN values with empty strings | |
final_df = final_df.fillna('') | |
print(f"Final shape: {final_df.shape}") | |
# Save to Excel | |
final_df.to_excel(output_path, index=False, header=False, engine='openpyxl') | |
# Create preview (first 20 rows) | |
preview_df = final_df.head(20).copy() | |
# Add string column names for Gradio | |
preview_df.columns = [f'คอลัมน์_{i+1}' for i in range(len(preview_df.columns))] | |
# Convert to strings for display | |
for col in preview_df.columns: | |
preview_df[col] = preview_df[col].astype(str).replace('nan', '').replace('', '-') | |
success_message = f""" | |
✅ **ประมวลผลเสร็จสิ้น!** | |
📊 **สรุป:** | |
- รูปแบบต้นฉบับ: {df.shape[0]} แถว × {df.shape[1]} คอลัมน์ | |
- หลังตัดคอลัมน์: {df_processed.shape[0]} แถว × {df_processed.shape[1]} คอลัมน์ | |
- เพิ่มบรรทัดลงนาม: {len(signature_lines)} บรรทัด | |
- รูปแบบสุดท้าย: {final_df.shape[0]} แถว × {final_df.shape[1]} คอลัมน์ | |
📥 **ดาวน์โหลดไฟล์ที่ประมวลผลแล้ว** | |
""" | |
return output_path, success_message, preview_df | |
except Exception as e: | |
error_message = f""" | |
❌ **เกิดข้อผิดพลาด:** | |
{str(e)} | |
**กรุณาตรวจสอบ:** | |
- ไฟล์ Excel (.xls หรือ .xlsx) ที่ถูกต้อง | |
- มีข้อมูลในไฟล์ | |
- ไฟล์ไม่เสียหาย | |
""" | |
return None, error_message, pd.DataFrame({'ข้อผิดพลาด': ['ไม่สามารถประมวลผลไฟล์ได้']}) | |
def create_gradio_interface(): | |
"""Create the Gradio interface""" | |
with gr.Blocks(title="Excel Column Processor", theme=gr.themes.Soft()) as iface: | |
gr.Markdown(""" | |
# 📊 เครื่องมือประมวลผลไฟล์ Excel | |
ตัดคอลัมน์แรก 2 คอลัมน์ และเพิ่มบรรทัดลงนามท้ายไฟล์ | |
**วิธีใช้:** | |
1. อัปโหลดไฟล์ Excel | |
2. กดปุ่ม "ประมวลผลไฟล์" | |
3. ดาวน์โหลดไฟล์ผลลัพธ์ | |
""") | |
with gr.Row(): | |
with gr.Column(): | |
gr.Markdown(""" | |
**การทำงาน:** | |
- ตัดคอลัมน์ที่ 1 และ 2 ออก | |
- เลื่อนข้อมูลมาเริ่มที่คอลัมน์ A | |
- เพิ่มบรรทัดลงนาม (กรรมการ, ผู้รับเงิน, หัวหน้า) | |
- ส่งออกเป็น Excel ใหม่ | |
""") | |
with gr.Row(): | |
with gr.Column(): | |
file_input = gr.File( | |
label="📁 อัปโหลดไฟล์ Excel", | |
file_types=[".xls", ".xlsx"], | |
file_count="single" | |
) | |
process_btn = gr.Button( | |
"🔄 ประมวลผลไฟล์", | |
variant="primary", | |
size="lg" | |
) | |
with gr.Row(): | |
with gr.Column(): | |
status_output = gr.Markdown( | |
label="📊 สถานะ", | |
value="👆 อัปโหลดไฟล์ Excel และกดประมวลผล" | |
) | |
with gr.Row(): | |
with gr.Column(): | |
file_output = gr.File( | |
label="💾 ดาวน์โหลดไฟล์ผลลัพธ์", | |
visible=False | |
) | |
with gr.Row(): | |
with gr.Column(): | |
preview_output = gr.Dataframe( | |
label="👀 ตัวอย่าง (20 แถวแรก)", | |
visible=False, | |
wrap=True | |
) | |
def handle_processing(file): | |
if file is None: | |
return ( | |
gr.update(visible=False), | |
"⚠️ **กรุณาอัปโหลดไฟล์ Excel ก่อน**", | |
gr.update(visible=False) | |
) | |
result_file, message, preview = process_excel_file(file) | |
if result_file: | |
return ( | |
gr.update(value=result_file, visible=True), | |
message, | |
gr.update(value=preview, visible=True) | |
) | |
else: | |
return ( | |
gr.update(visible=False), | |
message, | |
gr.update(value=preview, visible=True) | |
) | |
process_btn.click( | |
fn=handle_processing, | |
inputs=[file_input], | |
outputs=[file_output, status_output, preview_output] | |
) | |
gr.Markdown(""" | |
**รายละเอียด:** | |
- รองรับ Excel (.xls, .xlsx) | |
- ตัดคอลัมน์แรก 2 คอลัมน์อัตโนมัติ | |
- เพิ่มช่องลงนามสำหรับกรรมการ ผู้รับเงิน และหัวหน้า | |
- เหมาะสำหรับรายงานการเงินและเอกสารทางการ | |
💡 **เคล็ดลับ:** เครื่องมือนี้จะลบคอลัมน์ว่างด้านซ้ายและจัดรูปแบบให้พร้อมสำหรับการลงนาม | |
""") | |
return iface | |
# Create and launch the app | |
if __name__ == "__main__": | |
app = create_gradio_interface() | |
app.launch( | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=False | |
) |