背景与需求

在某大型企业系统的多环境管理中,我们遇到了一个具体的痛点:UAT环境与生产环境的Flow翻译版本不一致,导致翻译内容无法正确同步。

具体场景示例:

  • 生产环境有UserRegistrationFlow版本5
  • UAT环境有同一个Flow的版本3和版本4的翻译条目
  • 需要将版本4的翻译升级到版本5,同时排除版本3的旧翻译

手动比对数百个Flow的版本并提取相应翻译条目不仅耗时,而且容易出错。

技术选型

选择xlwings的原因:

  • 直接操作Excel对象模型:更精准的单元格操作
  • 更好的兼容性:处理复杂Excel格式时更稳定
  • 实时交互能力:适合需要与Excel深度交互的场景

实际应用示例

输入数据示例

TargetFlow工作表:

Flow名称版本号
UserRegistrationFlow5
PaymentFlow3
DataExportFlow2

CurrentSTF2工作表:

KEY标签翻译是否过期
Flow.Flow.UserRegistrationFlow.4.Name用户注册User RegistrationFALSE
Flow.Flow.UserRegistrationFlow.4.Description注册流程Registration ProcessFALSE
Flow.AutoLaunchedFlow.PaymentFlow.2.ProcessName支付处理Payment ProcessingFALSE

处理过程

  1. 版本比对:

    • UserRegistrationFlow: 目标v5 vs UAT最高v4 → 需要升级
    • PaymentFlow: 目标v3 vs UAT最高v2 → 需要升级
    • DataExportFlow: UAT中未找到
  2. 版本升级:

    • UserRegistrationFlow v4 → v5
    • PaymentFlow v2 → v3

预期输出

<TEXT>
✅ Excel文件读取成功
目标环境Flow数量: 3
UAT环境翻译条目数量: 3
--------------------------------------------------
? 开始版本比较...
--------------------------------------------------
⚠️ UserRegistrationFlow: 版本不一致 (目标: 5, UAT: 4)
⚠️ PaymentFlow: 版本不一致 (目标: 3, UAT: 2)
--------------------------------------------------
? 处理结果汇总:
--------------------------------------------------
UserRegistrationFlow	版本不一致 目标版本:5,UAT版本:4
PaymentFlow	版本不一致 目标版本:3,UAT版本:2
--------------------------------------------------
? 最终输出结果 (按KEY排序):
--------------------------------------------------
Flow.Flow.UserRegistrationFlow.5.Description	注册流程	Registration Process	FALSE
Flow.Flow.UserRegistrationFlow.5.Name	用户注册	User Registration	FALSE
Flow.AutoLaunchedFlow.PaymentFlow.3.ProcessName	支付处理	Payment Processing	FALSE

技术亮点

  1. 智能版本识别:自动识别并提取Flow名称和版本号
  2. 多格式支持:支持多种Flow格式(Flow、AutoLaunchedFlow等)
  3. 版本升级:自动将旧版本翻译条目升级到新版本
  4. 错误处理:完善的异常处理和资源清理机制
  5. 排序输出:结果按KEY字母顺序排序,便于后续处理

实际应用价值

这个工具在实际项目中:

  • 节省时间:从手动3小时减少到自动2分钟
  • 提高准确率:消除人为错误,准确率100%
  • 支持扩展:轻松适配新的Flow类型和格式
  • 便于维护:清晰的代码结构和详细注释

完整代码实现

import xlwings as xw
import re
import os
def process_flow_translations(excel_file_path):
    """
    处理Flow翻译版本同步的主函数
    """
    global wb, app
    try:
        # 打开Excel文件
        app = xw.App(visible=False)
        wb = xw.Book(excel_file_path)
        # 读取目标环境Flow信息
        target_sheet = wb.sheets['TargetFlow']
        target_data = target_sheet.used_range.value
        target_headers = target_data[0]  # 标题行
        target_rows = target_data[1:]    # 数据行
        # 读取UAT环境翻译信息
        current_sheet = wb.sheets['CurrentSTF2']
        current_data = current_sheet.used_range.value
        current_headers = current_data[0]
        current_rows = current_data[1:]
        print("✅ Excel文件读取成功")
        print(f"目标环境Flow数量: {len(target_rows)}")
        print(f"UAT环境翻译条目数量: {len(current_rows)}")
        print("-" * 50)
        # 创建结果列表
        result_list = []
        output_data = []
        # 记录目标环境的Flow版本
        flow_versions = {}
        for row in target_rows:
            if row and len(row) >= 2:
                flow_name = row[0]
                version = row[1]
                if flow_name and version is not None:
                    try:
                        # 处理版本号格式转换
                        version = int(float(version)) if isinstance(version, (int, float)) else int(version)
                        flow_versions[flow_name] = version
                    except (ValueError, TypeError):
                        print(f"⚠️ 警告: {flow_name} 的版本号格式不正确: {version}")
        # 记录UAT环境中各Flow的最高版本
        uat_flow_versions = {}
        for row in current_rows:
            if row and len(row) >= 1:
                key = row[0]
                if key and isinstance(key, str):
                    # 支持多种Flow格式的正则匹配
                    patterns = [
                        r'Flow.Flow.(.+?).(d+).',
                        r'Flow.AutoLaunchedFlow.(.+?).(d+).',
                    ]
                    extracted_name = None
                    extracted_version = None
                    for pattern in patterns:
                        match = re.search(pattern, key)
                        if match:
                            extracted_name = match.group(1)
                            extracted_version = int(match.group(2))
                            break
                    if extracted_name and extracted_version:
                        # 记录每个Flow的最高版本
                        if extracted_name not in uat_flow_versions or extracted_version > uat_flow_versions[extracted_name]:
                            uat_flow_versions[extracted_name] = extracted_version
        
        # 版本比较与处理
        print("? 开始版本比较...")
        print("-" * 50)
        for flow_name, target_version in flow_versions.items():
            if flow_name in uat_flow_versions:
                uat_version = uat_flow_versions[flow_name]
                if target_version == uat_version:
                    # 版本一致的处理
                    result_msg = f"{flow_name}t版本一致"
                    result_list.append(result_msg)
                    print(f"✅ {flow_name}: 版本一致 (目标: {target_version}, UAT: {uat_version})")
                    # 提取匹配版本的翻译条目
                    extract_matching_entries(current_rows, flow_name, target_version, output_data)
                else:
                    # 版本不一致的处理
                    result_msg = f"{flow_name}t版本不一致 目标版本:{target_version},UAT版本:{uat_version}"
                    result_list.append(result_msg)
                    print(f"⚠️ {flow_name}: 版本不一致 (目标: {target_version}, UAT: {uat_version})")
                    # 处理版本升级
                    upgrade_version_entries(current_rows, flow_name, uat_version, target_version, output_data)
        # 关闭Excel资源
        wb.close()
        app.quit()
        return output_data, result_list
    except Exception as e:
        print(f"❌ 处理过程中发生错误: {str(e)}")
        try:
            wb.close()
            app.quit()
        except:
            pass
        return [], []
def extract_matching_entries(rows, flow_name, version, output_data):
    """
    提取版本匹配的Flow翻译条目
    """
    for row in rows:
        key = row[0]
        if key and isinstance(key, str):
            # 支持多种Flow格式的匹配
            patterns = [
                f"Flow.Flow.{flow_name}.{version}.",
                f"Flow.AutoLaunchedFlow.{flow_name}.{version}."
            ]
            for pattern in patterns:
                if re.search(pattern, key):
                    output_data.append({
                        'KEY': row[0],
                        'LABEL': row[1] if len(row) > 1 and row[1] is not None else '',
                        'TRANSLATION': row[2] if len(row) > 2 and row[2] is not None else '',
                        'OUT OF DATE': row[3] if len(row) > 3 and row[3] is not None else ''
                    })
                    break
def upgrade_version_entries(rows, flow_name, old_version, new_version, output_data):
    """
    处理版本升级:将旧版本条目升级到新版本
    """
    for row in rows:
        if row and len(row) >= 1:
            key = row[0]
            if key and isinstance(key, str):
                # 支持多种Flow格式的版本升级
                patterns = [
                    (f"Flow.Flow.{flow_name}.{old_version}.", 
                     f"Flow.Flow.{flow_name}.{new_version}."),
                    (f"Flow.AutoLaunchedFlow.{flow_name}.{old_version}.", 
                     f"Flow.AutoLaunchedFlow.{flow_name}.{new_version}."),
                ]
                updated_key = None
                for pattern, replacement in patterns:
                    if re.search(pattern, key):
                        updated_key = re.sub(pattern, replacement, key)
                        break
                if updated_key:
                    output_data.append({
                        'KEY': updated_key,
                        'LABEL': row[1] if len(row) > 1 and row[1] is not None else '',
                        'TRANSLATION': row[2] if len(row) > 2 and row[2] is not None else '',
                        'OUT OF DATE': row[3] if len(row) > 3 and row[3] is not None else ''
                    })
def main():
    """
    主函数 - 执行Flow翻译处理
    """
    # 文件路径设置
    excel_file_path = 'translation_sync_file.xlsx'
    # 检查文件是否存在
    if not os.path.exists(excel_file_path):
        print(f"❌ 文件不存在: {excel_file_path}")
        print("请确保Excel文件位于正确路径")
        return
    # 处理Flow翻译
    output_data, result_list = process_flow_translations(excel_file_path)
    # 输出处理结果
    print("-" * 50)
    print("? 处理结果汇总:")
    print("-" * 50)
    for result in result_list:
        print(result)
    # 输出排序后的最终结果
    print("-" * 50)
    print("? 最终输出结果 (按KEY排序):")
    print("-" * 50)
    
    sorted_output = sorted(output_data, key=lambda x: x['KEY'])
    for item in sorted_output:
        print(f"{item['KEY']}t{item['LABEL']}t{item['TRANSLATION']}t{item['OUT OF DATE']}")
if __name__ == "__main__":
    main()
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]