基于Flask与PyMuPDF的PDF文本编辑/修改/替换实现技术求助
基于PyMuPDF实现PDF货币文本替换方案
核心思路
PDF的文本存储是基于页面布局的(非流式文档),无法直接"替换"原有文本,只能通过定位目标文本区域→覆盖原有内容→写入转换后的新文本的方式实现效果。以下是用PyMuPDF(fitz)实现的具体步骤:
具体实现代码
1. 货币替换核心逻辑
import fitz import re # 模拟货币转换逻辑(实际可对接公开汇率API) def convert_currency(amount, from_currency, to_currency): # 示例汇率映射,可根据需求扩展 rate_map = { "USD": {"CNY": 7.2, "EUR": 0.92}, "EUR": {"CNY": 7.83, "USD": 1.09}, "CNY": {"USD": 0.14, "EUR": 0.13} } return round(amount * rate_map[from_currency][to_currency], 2) def replace_currency_in_pdf(input_pdf_path, output_pdf_path, target_currency): doc = fitz.open(input_pdf_path) # 匹配常见货币格式:$100.00、€250、USD 50.5、¥1200 currency_pattern = re.compile(r'(\$|€|¥|USD|EUR|CNY)\s*(\d+\.?\d*)') for page in doc: # 查找所有匹配货币规则的文本区域 text_boxes = page.search_for(currency_pattern) for box in text_boxes: # 提取原文本内容 original_text = page.get_textbox(box).strip() match_result = currency_pattern.match(original_text) if not match_result: continue original_curr, amount_str = match_result.groups() amount = float(amount_str) # 统一货币代码格式(去除符号) base_curr = original_curr.strip('$€¥') # 执行货币转换 converted_amount = convert_currency(amount, base_curr, target_currency) new_text = f"{target_currency} {converted_amount}" # 用白色矩形覆盖原文本区域,避免重叠 page.draw_rect(box, color=(1,1,1), fill=(1,1,1)) # 在原位置写入新文本(可调整字体大小匹配原排版) page.insert_text(box.tl, new_text, fontsize=10, color=(0,0,0)) doc.save(output_pdf_path) doc.close()
2. Flask集成示例
from flask import Flask, request, send_file import os app = Flask(__name__) UPLOAD_DIR = 'temp_uploads' os.makedirs(UPLOAD_DIR, exist_ok=True) @app.route('/process-pdf', methods=['POST']) def process_pdf(): if 'pdf' not in request.files: return "未上传PDF文件", 400 target_curr = request.form.get('target_currency', 'CNY') pdf_file = request.files['pdf'] input_path = os.path.join(UPLOAD_DIR, pdf_file.filename) output_path = os.path.join(UPLOAD_DIR, f"currency_converted_{pdf_file.filename}") pdf_file.save(input_path) replace_currency_in_pdf(input_path, output_path, target_curr) return send_file(output_path, as_attachment=True) if __name__ == '__main__': app.run(debug=True)
关键注意事项
- 字体匹配:如果原PDF使用特殊字体,默认
insert_text的字体可能导致排版差异,可通过fitz.Font()加载原字体文件(需确保字体可访问) - 位置微调:
box.tl是文本块左上角坐标,若新文本长度与原文本差异大,可适当调整坐标避免内容溢出 - 正则优化:根据实际业务中出现的货币格式,调整正则表达式覆盖更多场景
- 性能优化:处理大体积PDF时,可分批次处理页面,避免内存占用过高
内容的提问来源于stack exchange,提问作者abhinav srivastava
相关产品推荐
相关产品推荐

