import os import sys import uuid import tempfile import pdfplumber from flask import Flask, request, jsonify, send_file from add_signature import find_signature_positions, add_signature_to_pdf from add_watermark import add_watermark_to_pdf from extract_table import extract_temp_time, extract_pdf_table_to_excel, extract_temp_by_datetime_pattern, allowed_file, \ safe_filename, extract_temperature_data_from_pdf, extract_data_from_pdf_5 from drag_signature import add_signature_at_position, add_multiple_signatures from lib import Qiniu from werkzeug.utils import secure_filename from flask_cors import CORS app = Flask(__name__) UPLOAD_FOLDER = tempfile.gettempdir() app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER CORS(app) # 确保temp目录存在 temp_dir = "./temp" if not os.path.exists(temp_dir): os.makedirs(temp_dir) @app.route('/add_signature', methods=['POST']) def add_signature(): try: # 获取请求参数 data = request.get_json() pdf_url = data.get('pdf_url') if not pdf_url: return jsonify({"error": "缺少pdf_url参数"}), 400 # 下载PDF文件 local_pdf = Qiniu.download_file(pdf_url) # 查找签名位置(使用默认公章图片) signature_img = './static/报告专用章.png' # 确保项目目录下有这个文件 positions = find_signature_positions(local_pdf) if not positions: os.remove(local_pdf) return jsonify({"error": "未找到签名位置"}), 400 # 生成带公章的PDF signature_pdf = os.path.join("./temp", f"signature_{os.path.basename(local_pdf)}") add_signature_to_pdf(local_pdf, signature_pdf, signature_img, positions) # 上传到七牛云 file_key = f"UpImage/{uuid.uuid4()}.pdf" new_pdf_url = Qiniu.upload_to_qiniu(signature_pdf, file_key) # 清理临时文件 os.remove(local_pdf) os.remove(signature_pdf) return jsonify({ "success": True, "signature_pdf_url": new_pdf_url }) except Exception as e: return jsonify({ "error": str(e), "success": False, }), 500 @app.route('/add_watermark', methods=['POST']) def add_watermark(): try: # 获取请求参数 data = request.get_json() pdf_url = data.get('pdf_url') if not pdf_url: return jsonify({"error": "缺少pdf_url参数"}), 400 # 下载PDF文件 local_pdf = Qiniu.download_file(pdf_url) # 水印文件 pdf_file_mark = './static/watermark.pdf' # 确保项目目录下有这个文件 # 生成带公章的PDF watermark_pdf = os.path.join("./temp", f"watermark_{os.path.basename(local_pdf)}") add_watermark_to_pdf(local_pdf, pdf_file_mark, watermark_pdf) # 上传到七牛云 file_key = f"UpImage/{uuid.uuid4()}.pdf" new_pdf_url = Qiniu.upload_to_qiniu(watermark_pdf, file_key) # 清理临时文件 os.remove(local_pdf) os.remove(watermark_pdf) return jsonify({ "success": True, "watermark_pdf_url": new_pdf_url }) except Exception as e: return jsonify({ "error": str(e), "success": False, }), 500 @app.route('/extract_table', methods=['POST']) def extract_table(): if 'file' not in request.files: return jsonify({'error': 'No file part'}), 400 file = request.files['file'] if file.filename == '': return jsonify({'error': 'No selected file'}), 400 if file and allowed_file(file.filename): original_filename = file.filename filename = safe_filename(original_filename) # filename = secure_filename(safe_name) filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(filepath) df = None with pdfplumber.open(filepath) as pdf: # 获取第一页 first_page = pdf.pages[0] text = first_page.extract_text() if text: if "温湿度数据报告" in text: df = extract_pdf_table_to_excel(filepath) if "历史数据表" in text: df = extract_temp_time(filepath) if "设备汇总报告" in text: df = extract_temp_by_datetime_pattern(filepath) if "详细数据" in text: df = extract_temperature_data_from_pdf(filepath) else: df = extract_data_from_pdf_5(filepath) if df is None: os.remove(filepath) return jsonify({'error': '所有处理方法均失败'}), 400 # 保存Excel文件 output_filename = filename.replace('.pdf', '.xlsx') output_path = os.path.join(app.config['UPLOAD_FOLDER'], output_filename) df.to_excel(output_path, index=False, engine='openpyxl') # 删除上传的PDF文件 os.remove(filepath) # 返回Excel文件 try: return send_file( output_path, as_attachment=True, download_name=output_filename, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) finally: # 确保临时文件最终被删除 try: os.remove(output_path) except: pass else: return jsonify({'error': 'Invalid file type'}), 400 @app.route('/upload_pdf', methods=['POST']) def upload_pdf(): """ 上传PDF文件到服务器并返回URL """ try: if 'file' not in request.files: return jsonify({"error": "没有文件"}), 400 file = request.files['file'] if file.filename == '': return jsonify({"error": "文件名为空"}), 400 if not file.filename.lower().endswith('.pdf'): return jsonify({"error": "只支持PDF文件"}), 400 # 保存临时文件 filename = secure_filename(file.filename) temp_pdf = os.path.join("./temp", f"upload_{uuid.uuid4()}.pdf") file.save(temp_pdf) # 上传到七牛云 file_key = f"UpImage/{uuid.uuid4()}.pdf" pdf_url = Qiniu.upload_to_qiniu(temp_pdf, file_key) # 清理临时文件 try: os.remove(temp_pdf) except: pass return jsonify({ "success": True, "pdf_url": pdf_url }) except Exception as e: return jsonify({ "error": str(e), "success": False, }), 500 @app.route('/upload_signature', methods=['POST']) def upload_signature(): """ 上传签名图片文件到服务器并返回URL """ try: if 'file' not in request.files: return jsonify({"error": "没有文件"}), 400 file = request.files['file'] if file.filename == '': return jsonify({"error": "文件名为空"}), 400 # 检查文件类型(支持常见的图片格式) allowed_extensions = {'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'} filename_lower = file.filename.lower() if not any(filename_lower.endswith(ext) for ext in allowed_extensions): return jsonify({"error": "只支持图片文件(png, jpg, jpeg, gif, bmp, webp)"}), 400 # 保存临时文件 filename = secure_filename(file.filename) # 获取文件扩展名 file_ext = os.path.splitext(filename)[1] or '.png' temp_signature = os.path.join("./temp", f"upload_signature_{uuid.uuid4()}{file_ext}") file.save(temp_signature) # 上传到七牛云 file_key = f"UpImage/{uuid.uuid4()}{file_ext}" signature_url = Qiniu.upload_to_qiniu(temp_signature, file_key) # 清理临时文件 try: os.remove(temp_signature) except: pass return jsonify({ "success": True, "signature_url": signature_url }) except Exception as e: return jsonify({ "error": str(e), "success": False, }), 500 @app.route('/drag_signature', methods=['POST']) def drag_signature(): """ 在PDF上添加签名或电子章(支持拖放) 请求参数: { "pdf_url": "PDF文件URL", "signatures": [ { "signature_url": "签名/电子章URL", "page_num": 页码(从0开始), "x": X坐标(相对于页面左上角,单位:点), "y": Y坐标(相对于页面左上角,单位:点), "width": 宽度(可选,单位:点), "height": 高度(可选,单位:点) } ] } """ try: # 获取请求参数 data = request.get_json() pdf_url = data.get('pdf_url') signatures = data.get('signatures', []) if not pdf_url: return jsonify({"error": "缺少pdf_url参数"}), 400 if not signatures or len(signatures) == 0: return jsonify({"error": "缺少signatures参数或签名列表为空"}), 400 # 下载PDF文件 local_pdf = Qiniu.download_file(pdf_url) # 生成带签名的PDF output_pdf = os.path.join("./temp", f"drag_signature_{uuid.uuid4()}.pdf") # 添加多个签名 add_multiple_signatures(local_pdf, output_pdf, signatures) # 上传到七牛云 file_key = f"UpImage/{uuid.uuid4()}.pdf" new_pdf_url = Qiniu.upload_to_qiniu(output_pdf, file_key) # 清理临时文件 try: os.remove(local_pdf) os.remove(output_pdf) except: pass return jsonify({ "success": True, "pdf_url": new_pdf_url }) except Exception as e: return jsonify({ "error": str(e), "success": False, }), 500 if __name__ == '__main__': print("项目地址:", os.path.dirname(__file__)) if len(sys.argv) != 2: print("请填写端口号") sys.exit() # app.debug = True # 设置调试模式,生产模式的时候要关掉debug # app.config['JSON_AS_ASCII'] = False app.run(host='0.0.0.0', port=6500, debug=True)