iOS【语言国际化处理】python脚本将国际化语言文件批量导入Excel文件中(二)

相关国际化处理:
iOS【语言国际化处理】python脚本读取Excel内容批量导入国际化语言文件中(一)
iOS【语言国际化处理】python脚本将国际化语言文件批量导入Excel文件中(二)
iOS【图片国际化处理】python脚本Assets.xcassets图片名称及MD5批量处理(三)

接上一个处理后续:将项目中的国际化语言批量导入到Excel中

注意文案格式与key中有=号
1、"key"="abc def"; //注释
2、"key"="abc=def";
3、"key"="这是一句
话,只是换行了";

4、"key=key"="abc def";
1、2、3、处理了,第4种没处理,一般调整key

文件示例目录
|--------Language---ar.lproj-------------Localizable.strings----|
|---------------------en.lproj------------Localizable.strings----|
|---------------------es.lproj------------Localizable.strings----|
|---------------------Language.xlsx----------------------------|
Excel结构示意图

Excel第一行内容:key | ar.lproj | en.lproj | es.lproj |
Excel后面行内容:第一列为Key, 后面列为对应语言的翻译

[key]-----[ar.lporj]------[en.lproj]-----[es.lproj]
[key1]----[test_ar]------[test_en]-----[test_es]
[key2]----[test2_ar]----[test2_en]----[test2_es]
Localizable.strings结构示意图
"kTest_1" = "test_ar_1 \n 11";
"kTest_2" = "test_ar_2";
"kTest_3" = "test_ar_3  %@ 33";
文件目录截图
翻译Excel截图
国际化处理截图

Python3, 需要安装xlrd读Excel,xlwt写Excel

python里面的xlrd模块(python3.9)表示对应版本
curl https://bootstrap.pypa.io/get-pip.py | python3.9
pip install xlrd
pip install xlwt
pip install pyexcel-xls

终端使用示例
python3.9 /Users/odd/Documents/Project/测试国际化/TestPython/CCLocalizationToExcelTool.py
配置使用:
print("可配置调整")
    # /Users/odd/Documents/Project/测试国际化/Language/en.lproj/Localizable.strings
    # 国际化语言文件
    languageFile = "/Users/odd/Documents/Project/测试国际化/Language"
    # 国际化的语言文件名
    languageLocalizableName = "Localizable.strings"
    # 存储excel文件路径
    languageExcefilePath = languageFile + "/Language.xlsx"
完整脚本:CCLocalizationToExcelTool.py
#-*-coding:utf-8-*-

import xlrd,xlwt,sys,os

"""读取本地国际化语言文件,导出到Excel表格中的数据"""

def read_localizable_to_excel():

    print("可配置调整")
    # /Users/odd/Documents/Project/测试国际化/Language/en.lproj/Localizable.strings
    # 国际化语言文件
    languageFile = "/Users/odd/Documents/Project/测试国际化/Language"
    # 国际化的语言文件名
    languageLocalizableName = "Localizable.strings"
    # 存储excel文件路径
    languageExcefilePath = languageFile + "/Language.xlsx"

    # 获取语言文件夹下对应的语言文件名集合
    dirSubDirNames = dir_first_all_subDirs(languageFile)
    if len(dirSubDirNames) == 0:
        print("\n错误>>>>> 该目录下不存在.lproj文件夹")
        return
        
    print("\n语言文件夹里各种语言文件名")
    print(dirSubDirNames)
    
    
    # 创建工作簿
    excleWorlk = xlwt.Workbook()
    sheet1 = excleWorlk.add_sheet(u'翻译',cell_overwrite_ok=True) #创建sheet
    row0 = [u'key']
    row0.extend(dirSubDirNames)
    print("\nexcel 第一行数据:")
    print(row0)
    print("\n")

    for i in range(0,len(row0)):
        sheet1.write(0,i,row0[i],set_style('Times New Roman',420,True))
        # 如果 i>0 ? 12000 : 6000
        sheet1.col(i).width =  12000 if(i>0) else 6000

    
    # 存储key集合,以及key对应的数据:kye,value,row
    # firstKeyArray = ["key1","key2"]
    # firstKeyValueArray = [{"key":"key1","value":"key对应的内容","row":"1(写入表中的第几行)"}]
    firstKeyArray = []
    firstKeyValueArray = []

    # ['ar.lproj', 'en.lproj', '.DS_Store', 'es.lproj']
    for subIndex, subDirName in enumerate(dirSubDirNames):
        languageLocalizableFilePath = languageFile + "/" + subDirName + "/" + languageLocalizableName
        print("翻译文件序号:" + str(subIndex) +" 路径:"+languageLocalizableFilePath)
        
        # 读取国际化语言
        languaeTxtArray = readTxtToArray(languageLocalizableFilePath)
        
        print("\n=====================================")
        print("\n开始写: " + subDirName + " 到表第: " + str(subIndex) + "列")
        print("\n=====================================")

        if subIndex == 0:
            for txtRowIndex, rowDic in enumerate(languaeTxtArray):
                txtRowKey = rowDic["key"]
                txtRowValue = rowDic["value"]
                writeRow = txtRowIndex+1
                
                # 持有已经写入的key
                firstKeyValueArray.append({"key":txtRowKey,"value":txtRowValue,"row":str(writeRow)})
                firstKeyArray.append(txtRowKey)
                
                print("写入列:" + str(subIndex+1) + " 行:" + str(writeRow) + " 值:" + txtRowValue)
                # 写入第一列Key
                sheet1.write(writeRow,0,txtRowKey)
                # 写入Key对应的value
                sheet1.write(writeRow,subIndex+1,txtRowValue)
        
        else:
            for txtRowIndex, rowDic in enumerate(languaeTxtArray):
                txtRowKey = rowDic["key"]
                txtRowValue = rowDic["value"]
                
                if txtRowKey in firstKeyArray:
                    # 取出已有key对应的数据
                    currentDic = dicFilterKeyForArray(firstKeyValueArray,txtRowKey)
                    # key对应的行
                    writeRow = int(currentDic["row"])
                    print(currentDic)
                    # 写入Key对应的value
                    sheet1.write(writeRow,subIndex+1,txtRowValue)
                    print("\n包含 直接写列:" + str(subIndex+1) + " 行:" + str(writeRow) + " 值: " + txtRowValue)

                else:
                    
                    firstKeyArray.append(txtRowKey)
                    firstKeyValueArray.append({"key":txtRowKey,"value":txtRowValue,"row":str(len(firstKeyArray))})
                    writeRow = len(firstKeyArray)
                    
                    print("\n追加到最后:" + str(writeRow))
                    # 写入第一列Key
                    sheet1.write(writeRow,0,txtRowKey)
                    # 写入Key对应的value
                    sheet1.write(writeRow,subIndex+1,txtRowValue)
                    print("写入列:" + str(subIndex+1) + " 行:" + str(writeRow) + " 值:" + txtRowValue)
        


    excleWorlk.save(languageExcefilePath) #保存文件
    print("\n===========导出文件路径=========")
    print("\n路径:"+languageExcefilePath)
    print("\n===========导出文件路径=========")
    print("\n\n")

 
# en.lproj 文件名处理
def langFieleName(nameString):
    result = ""
    #小写处理
    nameString = nameString.lower()
    
    #方式一:截取 nameString[-5:]  输出右5位:lproj
    # if len(nameString) > 1 :
    #     #获取:en
    #     result = nameString[0:2]
    
    #方式二:分割
    #nameList = nameString.split(".")
    #result = nameList[0]
    
    #方式三:查找截取 变量.find("要查找的内容"[,开始位置,结束位置])
    #lprojIndex = nameString.find('lproj') #3
    #result = nameString[0:lprojIndex]

    #方法四:替换
    result = nameString.replace('.lproj','')

    print(result)
    return result
    
def languageFileName(nameString):
    #小写处理
    result = nameString.lower()
    return result

# 判断目录是否存在,及创建
def isPathExitsDir(dirs):
    if dirs == '':
        print("不是文件目录路径")
        return
    
    if not os.path.exists(dirs):
        print("不存在目录,创建目录")
        os.makedirs(dirs)

# 判断文件是否存在,及创建
def isPathExitsFile(filePath):
    if filePath == '':
        print("不是文件路径")
        return
    if not os.path.exists(filePath):
        #调用系统命令行来创建文件
        os.system(r"touch {}".format(filePath))
    
# 读取iOS国际化语言文件
"""
行样式:"name" = "occc";
rowKey = "name"
rowValue = "occc"

txtArray = [{"key":rowKey,"value":rowValue}]
"""
def readTxtToArray(txtPath):

    #item.endswith('.mp4')
    # line.startswith('#')
    #b = True a = bool(1-b)
    #bool()函数中的1-bool值 就是取bool值的反值了。
    
    if not os.path.exists(txtPath):
        print("读取国际化语言文件不存在:" + txtPath)
        return {}

    txtArray = []
    with open(txtPath,"r") as f:
        txtData = f.readlines()
        # print("\ntxt内容:读取所以内容,并以数组格式返回,会读取到'\\n'")
        #print(txtData)
        #print("\n")
        #['"cancel"="CANCEL11"\n', '"done"="Done222"\n']

        tempStr = ''
        for line in txtData:
            #移除 \\n
            line = line.strip('\n')
            #print(line)
            #判断以"开头,
            print('=====:'+line)
            if line.startswith("\""):
                #查找先替换最后的//xxx
                replaceStr = re.sub('//.*$', '', line)
                if replaceStr.endswith('";'):
                    tempStr = tempStr+replaceStr
                    rowDataList = tempStr.split('=')
                    # key先移除首尾空,在移除"符号
                    key = clearTextBeginEnd(rowDataList[0],"\"")
                    rowValue = ''
                    value = ''
                    # = 分割可能有多个,后面的最后拼接
                    if len(rowDataList) > 1:
                        nextString = '='.join(rowDataList[1:])
                        rowValue = nextString.strip(";")
                        value = clearTextBeginEnd(rowValue,"\"")
                    
                    print("read 有效数据 key: " + key + " value: " + value)
                    txtArray.append({"key":key,"value":value})
                    tempStr = ''
                
                else:
                    tempStr = tempStr+replaceStr
            elif len(tempStr):
                
                #查找先替换最后的//xxx
                replaceStr = re.sub('//.*$', '', line)
                if replaceStr.endswith('";'):
                    tempStr = tempStr+replaceStr
                    rowDataList = tempStr.split('=')
                    # key先移除首尾空,在移除"符号
                    key = clearTextBeginEnd(rowDataList[0],"\"")
                    rowValue = ''
                    value = ''
                    # = 分割可能有多个,后面的最后拼接
                    if len(rowDataList) > 1:
                        nextString = '='.join(rowDataList[1:])
                        rowValue = nextString.strip(";")
                        value = clearTextBeginEnd(rowValue,"\"")
                    
                    print("read 有效数据 key: " + key + " value: " + value)
                    txtArray.append({"key":key,"value":value})
                    tempStr = ''
                else:
                    tempStr = tempStr+replaceStr
                
                
                

        f.close()

    print("数组集合:")
    print("key==============\n")
    #print(txtArray)
    return txtArray

# 清空txt文件内容
def clearTextContent(path):
    # 清空txt文件内容(方式一)
    clearfile = open(path, 'w').close()

    #清空txt文件内容(方式二)
    #with open(path, 'r+') as file:
    #    file.truncate(0)
    #    file.close()
    print("清空文件内容:"+path)

# 清除首尾空和"符号
def clearTextBeginEnd(sourceText,clearChart):
    
    # isinstance(sourceText,str) 是否字符串,然后取反
    if bool(1 - isinstance(sourceText,str)):
        print("清除数据不是字符串")
        return ""

    sourceText = sourceText.strip()
    sourceText = sourceText.strip(clearChart);
    return sourceText

# 获取文件夹里所有文件夹名
def dir_all_subDirs(file_dir):
    for root, dirs, files in os.walk(file_dir):
        print(root) #当前目录路径
        print(dirs) #当前路径下所有子目录
        print(files) #当前路径下所有非目录子文件
        print("\n")

# 获取文件夹里子文件夹名.lproj
def dir_first_all_subDirs(file_dir):

    results = []
    if file_dir == '':
        print("\n异常>>>>> 不是文件目录路径")
        return results
    
    if not os.path.exists(file_dir):
        print("\n异常>>>>>不存在目录,不创建目录")
        #os.makedirs(dirs)
        return results
        
#    for root, dirs, files in os.walk(file_dir):
#        print(root) #当前目录路径
#        print(dirs) #当前路径下所有子目录
#        print("\n")
#        return dirs
    
    # 获取文件夹里子文件夹名
    pathDirNames = os.listdir(file_dir)
    for dirName in pathDirNames:
        if dirName.endswith(".lproj"):
            results.append(dirName)
    
    return results

# 返回对应key的内容
def dicFilterKeyForArray(keyArray,key):
    for dic in keyArray:
        if dic["key"] == key:
            return dic
    
    return {}

'''
设置单元格样式
'''
def set_style(name,height,bold=False):
    style = xlwt.XFStyle() # 初始化样式

    font = xlwt.Font() # 为样式创建字体
    font.name = name # 'Times New Roman'
    font.bold = bold
    font.color_index = 4
    font.height = height

    # DASHED虚线
    # NO_LINE没有
    # THIN实线
    borders= xlwt.Borders()
    borders.left = xlwt.Borders.THIN
    borders.right = xlwt.Borders.THIN
    borders.top = xlwt.Borders.THIN
    borders.bottom = xlwt.Borders.THIN

  
    pattern = xlwt.Pattern()
    pattern.pattern = xlwt.Pattern.SOLID_PATTERN
    pattern.pattern_fore_colour = 42  # 给背景颜色赋值
    
    style.font = font
    style.pattern = pattern
    style.borders = borders
    
    return style
  
read_localizable_to_excel()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容