Manos21/AutoTransfer-StructuredData-from-MS_Word_to_Excel
0
1import streamlit as st2import pandas as pd3from docx import Document4import io5import os6import re7 8st.set_page_config(page_title="Protocol Parser", layout="wide")9 10# ------------------------------11# Title and Intro12# ------------------------------13st.markdown("<h1 style='text-align: center;'>📄 Protocol Data Parser</h1>", unsafe_allow_html=True)14st.markdown("<h4 style='text-align: center;'>Supports Upload or Sample Files</h4>", unsafe_allow_html=True)15 16# ------------------------------17# Load Helpers18# ------------------------------19def load_txt_list(path):20 with open(path, 'r', encoding='utf-8') as f:21 return [line.strip().upper() for line in f if line.strip()]22 23def parse_protocol_table(docx_stream, brand_list, type_list, type_map_df):24 doc = Document(docx_stream)25 records = []26 27 for table in doc.tables:28 for row in table.rows[1:]:29 cells = [cell.text.strip() for cell in row.cells]30 if len(cells) < 4:31 continue32 33 proto_col, control_col, item_col = cells[1], cells[2], cells[3]34 proto_lines = proto_col.split("\n")35 proto_date = proto_lines[0].strip() if len(proto_lines) > 0 else ""36 ypan, ipep = "", ""37 for l in proto_lines:38 if "ΥΠΑΝ" in l:39 ypan = l.replace("ΥΠΑΝ", "").strip(" :")40 elif "IPEP" in l.upper():41 ipep = "✓" if "DONE" in l.upper() else ""42 43 protocol_info = {44 "ΠρωτόκολλοΚατάσχεσης": proto_date,45 "Ημερομηνία": proto_date.split("/")[-1] if "/" in proto_date else "",46 "ΔΙΜΕΑ": 3,47 "IPEP": ipep,48 "ΥΠΑΝ": ypan,49 "Έκθεση Ελέγχου": control_col,50 }51 52 total_amount = ""53 if re.match(r"^\d+", item_col.strip()):54 total_amount = re.findall(r"^\d+", item_col.strip())[0]55 56 if "ΚΑΤΑΣΧΕΣΗ – ΚΑΤΑΣΤΡΟΦΗ" not in item_col:57 continue58 product_block = item_col.split("ΚΑΤΑΣΧΕΣΗ – ΚΑΤΑΣΤΡΟΦΗ:")[-1]59 60 # Fix for multiline entries61 raw_lines = [line.strip() for line in product_block.split("\n") if line.strip()]62 merged_lines = []63 temp = ""64 for line in raw_lines:65 if ":" in line:66 if temp:67 merged_lines.append(temp)68 temp = line69 else:70 temp += f" {line}"71 if temp:72 merged_lines.append(temp)73 74 first = True75 for line in merged_lines:76 if ":" not in line:77 continue78 parts = line.split(":", 1)79 company = parts[0].strip()80 rest = parts[1].strip().upper()81 82 quantity, unit = "", ""83 rest_parts = rest.rsplit(" ", 2)84 if len(rest_parts) >= 2 and rest_parts[-2].isdigit():85 quantity = rest_parts[-2]86 unit = rest_parts[-1]87 88 t_type = next((word for word in type_list if word in rest), "")89 t_cat = ""90 if t_type:91 match_row = type_map_df[type_map_df["Τύπος Προϊόντος"].str.upper() == t_type]92 if not match_row.empty:93 t_cat = match_row.iloc[0]["Κατηγορία Προϊόντος"]94 95 marka = next((word for word in brand_list if word in rest), "")96 if not marka:97 marka = company98 99 record = {100 **protocol_info,101 "Εταιρεία": company,102 "Μάρκα": marka,103 "Κατηγορία Προϊόντος": t_cat,104 "Τύπος Προϊόντος": t_type,105 "ΠοσότηταΑνάΕταιρεία": quantity,106 "ΠοσότηταΑνάΜάρκα": quantity,107 "ΠοσότηταΑνάΤύποςΠροιόντος": quantity,108 "ΠοσότηταΜέτρησης": unit,109 "ΣυνολικόΠοσόΑνάΠρωτόκολλο": total_amount if first else ""110 }111 first = False112 records.append(record)113 return pd.DataFrame(records)114 115# ------------------------------116# Upload or Use Sample Section117# ------------------------------118st.markdown("---")119st.markdown("### 🔄 Load Files")120 121use_sample = st.checkbox("Use Sample Files (from example folder)")122 123if use_sample:124 docx_file = "example/Protocol_Sample.docx"125 brand_list = load_txt_list("example/brand_list.txt")126 type_list = load_txt_list("example/type_list.txt")127 type_excel = pd.read_excel("example/Matches-Type-to-Category-Products.xlsx")128else:129 docx = st.file_uploader("📄 Upload .docx Protocol File", type="docx")130 brand_txt = st.file_uploader("🏷️ Upload brand_list.txt", type="txt")131 type_txt = st.file_uploader("📦 Upload type_list.txt", type="txt")132 type_xlsx = st.file_uploader("📘 Upload Matches-Type-to-Category-Products.xlsx", type="xlsx")133 134 if docx and brand_txt and type_txt and type_xlsx:135 docx_file = docx136 brand_list = [line.strip().upper() for line in brand_txt.read().decode("utf-8").splitlines() if line.strip()]137 type_list = [line.strip().upper() for line in type_txt.read().decode("utf-8").splitlines() if line.strip()]138 type_excel = pd.read_excel(type_xlsx)139 else:140 docx_file = None141 142# ------------------------------143# Parse and Display144# ------------------------------145if docx_file:146 df = parse_protocol_table(docx_file, brand_list, type_list, type_excel)147 st.success(f"✅ Parsed {len(df)} records successfully!")148 st.dataframe(df, use_container_width=True)149 150 col1, col2 = st.columns(2)151 with col1:152 xlsx_buf = io.BytesIO()153 df.to_excel(xlsx_buf, index=False)154 st.download_button("📥 Download Excel", data=xlsx_buf.getvalue(), file_name="parsed_output.xlsx")155 156 with col2:157 csv_buf = io.StringIO()158 df.to_csv(csv_buf, index=False)159 st.download_button("📥 Download CSV", data=csv_buf.getvalue(), file_name="parsed_output.csv", mime="text/csv")160 161# ------------------------------162# Download Sample Files Section163# ------------------------------164st.markdown("---")165st.markdown("### 🧪 Download Sample Files to Test the App")166 167col1, col2 = st.columns(2)168with col1:169 with open("example/Protocol_Sample.docx", "rb") as f:170 st.download_button("📄 Protocol Sample DOCX", f, file_name="Protocol_Sample.docx")171 with open("example/Matches-Type-to-Category-Products.xlsx", "rb") as f:172 st.download_button("📘 Type-Category Excel", f, file_name="Matches-Type-to-Category-Products.xlsx")173 174with col2:175 with open("example/brand_list.txt", "rb") as f:176 st.download_button("🏷️ Brand List TXT", f, file_name="brand_list.txt")177 with open("example/type_list.txt", "rb") as f:178 st.download_button("📦 Type List TXT", f, file_name="type_list.txt")