protae5544 commited on
Commit
057c155
·
verified ·
1 Parent(s): 9e2500c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +235 -100
app.py CHANGED
@@ -1,5 +1,6 @@
1
  import gradio as gr
2
  import pandas as pd
 
3
  import io
4
  import zipfile
5
  from datetime import datetime
@@ -39,8 +40,10 @@ def analyze_pdf_fields(pdf_path):
39
  if "/T" in field_obj:
40
  field_name = str(field_obj["/T"]).strip("()")
41
  field_type = str(field_obj.get("/FT", "Unknown"))
 
42
  all_fields[field_name] = {
43
  'type': field_type,
 
44
  'method': 'AcroForm'
45
  }
46
 
@@ -55,8 +58,10 @@ def analyze_pdf_fields(pdf_path):
55
  if "/T" in annot_obj:
56
  field_name = str(annot_obj["/T"]).strip("()")
57
  field_type = str(annot_obj.get("/FT", "Widget"))
 
58
  all_fields[field_name] = {
59
  'type': field_type,
 
60
  'page': page_num + 1,
61
  'method': 'Annotation'
62
  }
@@ -67,6 +72,166 @@ def analyze_pdf_fields(pdf_path):
67
  except Exception as e:
68
  return {"error": str(e)}
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  def fill_pdf_form(pdf_path, field_data):
71
  """เติมข้อมูลในฟอร์ม PDF"""
72
  try:
@@ -318,7 +483,7 @@ def process_pdf_csv(pdf_file, csv_file, filename_column, file_prefix, use_form_f
318
  def analyze_pdf_info(pdf_file):
319
  """วิเคราะห์ข้อมูล PDF"""
320
  if pdf_file is None:
321
- return "ไม่มีไฟล์ PDF"
322
 
323
  try:
324
  reader = PdfReader(pdf_file)
@@ -346,7 +511,7 @@ def analyze_pdf_info(pdf_file):
346
  def analyze_csv_info(csv_file):
347
  """วิเคราะห์ข้อมูล CSV"""
348
  if csv_file is None:
349
- return "ไม่มีไฟล์ CSV"
350
 
351
  try:
352
  df, error = read_csv_safe(csv_file)
@@ -378,109 +543,79 @@ def analyze_csv_info(csv_file):
378
 
379
  # สร้าง Gradio Interface
380
  def create_interface():
381
- with gr.Blocks(title="PDF Form Filler", theme=gr.themes.Soft()) as app:
382
  gr.Markdown("""
383
- # 📄 เครื่องมือเติมข้อมูล PDF จาก CSV
384
 
385
  **เครื่องมือนี้สามารถ:**
386
- - เติมข้อมูลลงในฟอร์ม PDF ที่มี form fields
387
- - สร้าง PDF ใหม่หากไม่มี form fields หรือเติมไม่ได้
388
- - รองรับ CSV หลาย encoding (UTF-8, TIS-620, CP874, etc.)
389
- - ส่งออกเป็นไฟล์ ZIP
 
390
  """)
391
 
392
- with gr.Row():
393
- with gr.Column(scale=1):
394
- gr.Markdown("## 📁 อัพโหลดไฟล์")
395
-
396
- pdf_file = gr.File(
397
- label="PDF Template",
398
- file_types=[".pdf"],
399
- type="filepath"
400
- )
401
 
402
- csv_file = gr.File(
403
- label="CSV Data",
404
- file_types=[".csv"],
405
- type="filepath"
406
- )
407
-
408
- gr.Markdown("## ⚙️ ตั้งค่า")
409
-
410
- filename_column = gr.Textbox(
411
- label="คอลัมน์สำหรับชื่อไฟล์ (ถ้ามี)",
412
- placeholder="เช่น name, id, etc.",
413
- value=""
414
- )
415
-
416
- file_prefix = gr.Textbox(
417
- label="คำนำหน้าชื่อไฟล์",
418
- value="document"
419
- )
420
-
421
- use_form_fields = gr.Checkbox(
422
- label="ใช้ Form Fields (ถ้าพบ)",
423
- value=True
424
- )
425
-
426
- process_btn = gr.Button(
427
- "🚀 สร้าง PDF ทั้งหมด",
428
- variant="primary",
429
- size="lg"
430
- )
 
 
431
 
432
- with gr.Column(scale=2):
433
- gr.Markdown("## 📊 ข้อมูลไฟล์")
 
 
 
 
434
 
435
- pdf_info = gr.Markdown("ยังไม่มีไฟล์ PDF")
436
- csv_info = gr.Markdown("ยังไม่มีไฟล์ CSV")
437
-
438
- gr.Markdown("## 📥 ผลลัพธ์")
439
-
440
- result_file = gr.File(
441
- label="ไฟล์ ZIP ที่สร้าง",
442
- visible=False
443
- )
444
-
445
- result_message = gr.Markdown("")
446
-
447
- # Event handlers
448
- pdf_file.change(
449
- fn=analyze_pdf_info,
450
- inputs=[pdf_file],
451
- outputs=[pdf_info]
452
- )
453
-
454
- csv_file.change(
455
- fn=analyze_csv_info,
456
- inputs=[csv_file],
457
- outputs=[csv_info]
458
- )
459
-
460
- process_btn.click(
461
- fn=process_pdf_csv,
462
- inputs=[
463
- pdf_file,
464
- csv_file,
465
- filename_column,
466
- file_prefix,
467
- use_form_fields
468
- ],
469
- outputs=[result_file, result_message]
470
- ).then(
471
- fn=lambda x: gr.update(visible=x is not None),
472
- inputs=[result_file],
473
- outputs=[result_file]
474
- )
475
-
476
- return app
477
-
478
- # รันแอป
479
- if __name__ == "__main__":
480
- app = create_interface()
481
- app.launch(
482
- server_name="0.0.0.0",
483
- server_port=7860,
484
- share=True, # สร้าง public URL
485
- debug=True
486
- )
 
1
  import gradio as gr
2
  import pandas as pd
3
+ import json
4
  import io
5
  import zipfile
6
  from datetime import datetime
 
40
  if "/T" in field_obj:
41
  field_name = str(field_obj["/T"]).strip("()")
42
  field_type = str(field_obj.get("/FT", "Unknown"))
43
+ field_value = str(field_obj.get("/V", "")).strip("()")
44
  all_fields[field_name] = {
45
  'type': field_type,
46
+ 'default_value': field_value,
47
  'method': 'AcroForm'
48
  }
49
 
 
58
  if "/T" in annot_obj:
59
  field_name = str(annot_obj["/T"]).strip("()")
60
  field_type = str(annot_obj.get("/FT", "Widget"))
61
+ field_value = str(annot_obj.get("/V", "")).strip("()")
62
  all_fields[field_name] = {
63
  'type': field_type,
64
+ 'default_value': field_value,
65
  'page': page_num + 1,
66
  'method': 'Annotation'
67
  }
 
72
  except Exception as e:
73
  return {"error": str(e)}
74
 
75
+ def generate_csv_template(pdf_fields, num_rows=5):
76
+ """สร้าง CSV template จาก PDF fields"""
77
+ if not pdf_fields or "error" in pdf_fields:
78
+ return None, "ไม่สามารถสร้าง CSV template ได้"
79
+
80
+ # สร้าง DataFrame ว่าง
81
+ template_data = {}
82
+
83
+ # เพิ่มคอลัมน์ ID
84
+ template_data['id'] = list(range(1, num_rows + 1))
85
+
86
+ # เพิ่มคอลัมน์จาก PDF fields
87
+ for field_name, field_info in pdf_fields.items():
88
+ if field_name and field_name.strip():
89
+ clean_name = field_name.strip()
90
+ # ใส่ค่าตัวอย่าง
91
+ if field_info.get('default_value') and field_info['default_value'].strip():
92
+ sample_value = field_info['default_value']
93
+ else:
94
+ # สร้างค่าตัวอย่าง
95
+ if 'name' in clean_name.lower():
96
+ sample_value = f"ชื่อตัวอย่าง {{}}"
97
+ elif 'date' in clean_name.lower() or 'วันที่' in clean_name:
98
+ sample_value = "2024-01-01"
99
+ elif 'email' in clean_name.lower():
100
+ sample_value = "example{}@email.com"
101
+ elif 'phone' in clean_name.lower() or 'เบอร์' in clean_name:
102
+ sample_value = "08-1234-567{}"
103
+ elif 'address' in clean_name.lower() or 'ที่อยู่' in clean_name:
104
+ sample_value = "123 ถนนตัวอย่าง กรุงเทพ {}"
105
+ else:
106
+ sample_value = f"ข้อมูลตัวอย่าง {{}}"
107
+
108
+ # สร้างข้อมูลตัวอย่าง
109
+ template_data[clean_name] = [
110
+ sample_value.format(i) if '{}' in sample_value else sample_value
111
+ for i in range(1, num_rows + 1)
112
+ ]
113
+
114
+ # สร้าง DataFrame
115
+ df = pd.DataFrame(template_data)
116
+ return df, "สร้าง CSV template สำเร็จ"
117
+
118
+ def generate_json_template(pdf_fields):
119
+ """สร้าง JSON template จาก PDF fields"""
120
+ if not pdf_fields or "error" in pdf_fields:
121
+ return None, "ไม่สามารถสร้าง JSON template ได้"
122
+
123
+ template = {
124
+ "pdf_info": {
125
+ "total_fields": len(pdf_fields),
126
+ "generation_time": datetime.now().isoformat()
127
+ },
128
+ "fields": {},
129
+ "sample_data": []
130
+ }
131
+
132
+ # เพิ่มข้อมูล fields
133
+ for field_name, field_info in pdf_fields.items():
134
+ if field_name and field_name.strip():
135
+ clean_name = field_name.strip()
136
+ template["fields"][clean_name] = {
137
+ "type": field_info.get('type', 'Unknown'),
138
+ "default_value": field_info.get('default_value', ''),
139
+ "page": field_info.get('page', 1),
140
+ "method": field_info.get('method', 'Unknown')
141
+ }
142
+
143
+ # สร้างข้อมูลตัวอย่าง
144
+ for i in range(1, 4): # 3 ตัวอย่าง
145
+ sample_record = {"id": i}
146
+ for field_name in template["fields"].keys():
147
+ if 'name' in field_name.lower():
148
+ sample_record[field_name] = f"ชื่อตัวอย่าง {i}"
149
+ elif 'date' in field_name.lower() or 'วันที่' in field_name:
150
+ sample_record[field_name] = f"2024-0{i}-01"
151
+ elif 'email' in field_name.lower():
152
+ sample_record[field_name] = f"example{i}@email.com"
153
+ else:
154
+ sample_record[field_name] = f"ข้อมูลตัวอย่าง {i}"
155
+ template["sample_data"].append(sample_record)
156
+
157
+ return template, "สร้าง JSON template สำเร็จ"
158
+
159
+ def create_template_files(pdf_file, num_rows=5):
160
+ """สร้างไฟล์ template ทั้งหมด"""
161
+ if pdf_file is None:
162
+ return None, None, "❌ กรุณาอัพโหลดไฟล์ PDF"
163
+
164
+ try:
165
+ # วิเคราะห์ PDF
166
+ pdf_fields = analyze_pdf_fields(pdf_file)
167
+
168
+ if not pdf_fields or "error" in pdf_fields:
169
+ return None, None, "❌ ไม่พบ form fields ใน PDF หรือไม่สามารถอ่านได้"
170
+
171
+ # สร้าง CSV template
172
+ csv_df, csv_msg = generate_csv_template(pdf_fields, num_rows)
173
+
174
+ # สร้าง JSON template
175
+ json_template, json_msg = generate_json_template(pdf_fields)
176
+
177
+ if csv_df is None or json_template is None:
178
+ return None, None, "❌ ไม่สามารถสร้าง template ได้"
179
+
180
+ # สร้าง ZIP file
181
+ zip_buffer = io.BytesIO()
182
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
183
+
184
+ with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
185
+ # เพิ่ม CSV
186
+ csv_buffer = io.StringIO()
187
+ csv_df.to_csv(csv_buffer, index=False, encoding='utf-8-sig')
188
+ zip_file.writestr(f"template_{timestamp}.csv", csv_buffer.getvalue())
189
+
190
+ # เพิ่ม JSON
191
+ json_str = json.dumps(json_template, ensure_ascii=False, indent=2)
192
+ zip_file.writestr(f"template_{timestamp}.json", json_str)
193
+
194
+ # เพิ่ม README
195
+ readme_content = f"""# PDF Form Template Files
196
+ Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
197
+
198
+ ## Files included:
199
+ 1. template_{timestamp}.csv - CSV template with sample data
200
+ 2. template_{timestamp}.json - JSON template with field information
201
+
202
+ ## PDF Fields Found: {len(pdf_fields)}
203
+ {chr(10).join([f"- {name}: {info.get('type', 'Unknown')}" for name, info in pdf_fields.items()])}
204
+
205
+ ## How to use:
206
+ 1. Edit the CSV file with your actual data
207
+ 2. Use the CSV file with the original PDF form filler
208
+ 3. The JSON file contains detailed field information for reference
209
+
210
+ ## Note:
211
+ - Make sure column names in CSV match the field names in PDF
212
+ - You can add more rows to the CSV as needed
213
+ - Keep the column headers exactly as shown
214
+ """
215
+ zip_file.writestr("README.txt", readme_content)
216
+
217
+ zip_buffer.seek(0)
218
+
219
+ # บันทึกไฟล์ชั่วคราว
220
+ temp_zip_path = os.path.join(tempfile.gettempdir(), f"pdf_templates_{timestamp}.zip")
221
+ with open(temp_zip_path, 'wb') as f:
222
+ f.write(zip_buffer.getvalue())
223
+
224
+ result_msg = f"✅ สร้าง template สำเร็จ!\n"
225
+ result_msg += f"🔍 พบ {len(pdf_fields)} fields ใน PDF\n"
226
+ result_msg += f"📄 CSV template: {num_rows} แถวตัวอย่าง\n"
227
+ result_msg += f"📋 JSON template: รายละเอียดครบถ้วน\n"
228
+ result_msg += f"📁 README: คำแนะนำการใช้งาน"
229
+
230
+ return temp_zip_path, pdf_fields, result_msg
231
+
232
+ except Exception as e:
233
+ return None, None, f"❌ เกิดข้อผิดพลาด: {str(e)}"
234
+
235
  def fill_pdf_form(pdf_path, field_data):
236
  """เติมข้อมูลในฟอร์ม PDF"""
237
  try:
 
483
  def analyze_pdf_info(pdf_file):
484
  """วิเคราะห์ข้อมูล PDF"""
485
  if pdf_file is None:
486
+ return "ยังไม่มีไฟล์ PDF"
487
 
488
  try:
489
  reader = PdfReader(pdf_file)
 
511
  def analyze_csv_info(csv_file):
512
  """วิเคราะห์ข้อมูล CSV"""
513
  if csv_file is None:
514
+ return "ยังไม่มีไฟล์ CSV"
515
 
516
  try:
517
  df, error = read_csv_safe(csv_file)
 
543
 
544
  # สร้าง Gradio Interface
545
  def create_interface():
546
+ with gr.Blocks(title="PDF Form Filler & Template Generator", theme=gr.themes.Soft()) as app:
547
  gr.Markdown("""
548
+ # 📄 เครื่องมือเติมข้อมูล PDF จาก CSV + สร้าง Template
549
 
550
  **เครื่องมือนี้สามารถ:**
551
+ - 🔄 **สร้าง CSV/JSON Template จาก PDF** (Reverse Engineering)
552
+ - 📝 เติมข้อมูลลงในฟอร์ม PDF ที่มี form fields
553
+ - 🆕 สร้าง PDF ใหม่หากไม่มี form fields หรือเติมไม่ได้
554
+ - 🌐 รองรับ CSV หลาย encoding (UTF-8, TIS-620, CP874, etc.)
555
+ - 📦 ส่งออกเป็นไฟล์ ZIP
556
  """)
557
 
558
+ with gr.Tabs():
559
+ # Tab 1: Template Generator
560
+ with gr.TabItem("🔄 สร้าง Template"):
561
+ gr.Markdown("""
562
+ ## 🔄 สร้าง CSV/JSON Template จาก PDF
563
+ **อัพโหลด PDF ที่มี form fields แล้วสร้าง template ให้อัตโนมัติ**
564
+ """)
 
 
565
 
566
+ with gr.Row():
567
+ with gr.Column(scale=1):
568
+ template_pdf = gr.File(
569
+ label="📄 PDF ที่ต้องการสร้าง Template",
570
+ file_types=[".pdf"],
571
+ type="filepath"
572
+ )
573
+
574
+ num_sample_rows = gr.Slider(
575
+ label="จำนวนแถวตัวอย่างใน CSV",
576
+ minimum=1,
577
+ maximum=20,
578
+ value=5,
579
+ step=1
580
+ )
581
+
582
+ generate_template_btn = gr.Button(
583
+ "🔄 สร้าง Template",
584
+ variant="primary",
585
+ size="lg"
586
+ )
587
+
588
+ with gr.Column(scale=2):
589
+ template_pdf_info = gr.Markdown("ยังไม่มีไฟล์ PDF")
590
+
591
+ template_result_file = gr.File(
592
+ label="📦 ไฟล์ Template (ZIP)",
593
+ visible=False
594
+ )
595
+
596
+ template_result_message = gr.Markdown("")
597
 
598
+ # Tab 2: PDF Form Filler
599
+ with gr.TabItem("📝 เติมข้อมูล PDF"):
600
+ gr.Markdown("""
601
+ ## 📝 เติมข้อมูล PDF จาก CSV
602
+ **ใช้ CSV ที่สร้างจาก Template หรือ CSV ของคุณเอง**
603
+ """)
604
 
605
+ with gr.Row():
606
+ with gr.Column(scale=1):
607
+ gr.Markdown("### 📁 อัพโหลดไฟล์")
608
+
609
+ pdf_file = gr.File(
610
+ label="PDF Template",
611
+ file_types=[".pdf"],
612
+ type="filepath"
613
+ )
614
+
615
+ csv_file = gr.File(
616
+ label="CSV Data",
617
+ file_types=[".csv"],
618
+ type="filepath"
619
+ )
620
+
621
+ gr.Markdown("### ⚙️ ตั้งค่