Spaces:
Running
Running
| ```python | |
| from flask import Flask, request, jsonify, send_file | |
| import os | |
| import uuid | |
| import pandas as pd | |
| import fitz # PyMuPDF | |
| from werkzeug.utils import secure_filename | |
| import zipfile | |
| from io import BytesIO | |
| app = Flask(__name__) | |
| app.config['UPLOAD_FOLDER'] = 'uploads' | |
| app.config['TEMPLATE_FOLDER'] = os.path.join(app.config['UPLOAD_FOLDER'], 'templates') | |
| app.config['OUTPUT_FOLDER'] = os.path.join(app.config['UPLOAD_FOLDER'], 'outputs') | |
| # Ensure upload directories exist | |
| os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) | |
| os.makedirs(app.config['TEMPLATE_FOLDER'], exist_ok=True) | |
| os.makedirs(app.config['OUTPUT_FOLDER'], exist_ok=True) | |
| # Sample field mapping (would normally come from config) | |
| FIELD_MAPPING = { | |
| "invoice_number": {"page": 0, "x": 150, "y": 200, "font_size": 10}, | |
| "therapist_name": {"page": 0, "x": 150, "y": 220, "font_size": 10}, | |
| "parent_id": {"page": 0, "x": 300, "y": 240, "font_size": 10} | |
| } | |
| def index(): | |
| return send_file('index.html') | |
| def upload_template(): | |
| if 'template' not in request.files: | |
| return jsonify({"error": "No file uploaded"}), 400 | |
| file = request.files['template'] | |
| if file.filename == '': | |
| return jsonify({"error": "No file selected"}), 400 | |
| if file and file.filename.lower().endswith('.pdf'): | |
| filename = secure_filename("template.pdf") | |
| filepath = os.path.join(app.config['TEMPLATE_FOLDER'], filename) | |
| file.save(filepath) | |
| return jsonify({"message": "Template uploaded successfully", "filename": filename}) | |
| return jsonify({"error": "Invalid file type"}), 400 | |
| def generate_pdf(): | |
| data = request.get_json() | |
| if not data or 'rows' not in data or 'headers' not in data or 'data' not in data: | |
| return jsonify({"error": "Invalid request data"}), 400 | |
| template_path = os.path.join(app.config['TEMPLATE_FOLDER'], 'template.pdf') | |
| if not os.path.exists(template_path): | |
| return jsonify({"error": "Template PDF not found"}), 404 | |
| selected_rows = data['rows'] | |
| headers = data['headers'] | |
| csv_data = data['data'] | |
| if len(selected_rows) == 1: | |
| # Single PDF generation | |
| row_data = csv_data[selected_rows[0]] | |
| output_path = generate_single_pdf(template_path, headers, row_data) | |
| return send_file(output_path, as_attachment=True) | |
| else: | |
| # Multiple PDFs - return as ZIP | |
| zip_buffer = generate_multiple_pdfs(template_path, headers, csv_data, selected_rows) | |
| return send_file( | |
| zip_buffer, | |
| mimetype='application/zip', | |
| as_attachment=True, | |
| download_name='generated_pdfs.zip' | |
| ) | |
| def generate_single_pdf(template_path, headers, row_data): | |
| doc = fitz.open(template_path) | |
| page = doc[0] | |
| for i, header in enumerate(headers): | |
| if header in FIELD_MAPPING: | |
| mapping = FIELD_MAPPING[header] | |
| text = str(row_data[i]) if i < len(row_data) else "" | |
| # Create a text annotation (similar to form field) | |
| annot = page.add_text_annot( | |
| point=(mapping['x'], mapping['y']), | |
| text=text | |
| ) | |
| annot.set_fontsize(mapping['font_size']) | |
| output_filename = f"output_{uuid.uuid4().hex[:8]}.pdf" | |
| output_path = os.path.join(app.config['OUTPUT_FOLDER'], output_filename) | |
| doc.save(output_path) | |
| doc.close() | |
| return output_path | |
| def generate_multiple_pdfs(template_path, headers, csv_data, selected_rows): | |
| zip_buffer = BytesIO() | |
| with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file: | |
| for row_idx in selected_rows: | |
| if row_idx < len(csv_data): | |
| row_data = csv_data[row_idx] | |
| doc = fitz.open(template_path) | |
| page = doc[0] | |
| for i, header in enumerate(headers): | |
| if header in FIELD_MAPPING: | |
| mapping = FIELD_MAPPING[header] | |
| text = str(row_data[i]) if i < len(row_data) else "" | |
| annot = page.add_text_annot( | |
| point=(mapping['x'], mapping['y']), | |
| text=text | |
| ) | |
| annot.set_fontsize(mapping['font_size']) | |
| pdf_filename = f"output_row_{row_idx + 1}.pdf" | |
| pdf_path = os.path.join(app.config['OUTPUT_FOLDER'], pdf_filename) | |
| doc.save(pdf_path) | |
| doc.close() | |
| zip_file.write(pdf_path, pdf_filename) | |
| os.remove(pdf_path) | |
| zip_buffer.seek(0) | |
| return zip_buffer | |
| if __name__ == '__main__': | |
| app.run(debug=True, port=5000) | |
| ``` |