美文网首页
iOS【语言国际化处理】python脚本读取Excel内容批量导

iOS【语言国际化处理】python脚本读取Excel内容批量导

作者: NJ_墨 | 来源:发表于2021-10-03 16:00 被阅读0次

    在项目开发中,偶尔需要新增国际化语言,但是提供的翻译文档一般是Excel文件,
    若只是一个,还可以简单一个一个辛苦的复杂,
    若内容很多,或新增好几个国际化语言,就要吐....了,
    之前用的是工具,现在自己简单实现学习一下,就不工具化了;

    这个版本:批量处理读取Excel到txt文件中

    下一个版本,
    将项目中的国际化语言批量导入到Excel中....

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

    文件示例目录
    |--------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/CCExcelToLocalizationTool.py
    
    配置使用:
    print("可以配置调整路径:")
        # 国际化语言文件
        languageFile = "/Users/odd/Documents/Project/测试国际化/Language"
        # 需要国际化的语言文件名
        languageLocalizableName = "Localizable.strings"
        # 打开excel文件读取数据
        languageExcefilePath = "/Users/odd/Documents/Project/测试国际化/Language/Language.xlsx"
        # 添加版本分割注释(可加可不加)
        versionMark = "// ==================== V1.0.0 ==================== //"
        #versionMark = ""
    
    完整脚本:CCExcelToLocalizationTool.py
    #-*-coding:utf-8-*-
    
    import xlrd,sys,os
    
    """读取Excel表格中的数据,写到txt、Localizable.strings中"""
    
    def read_excel_to_txt():
    
        '''
        # 写入文件路径 示例
        #/Users/odd/Documents/Project/测试国际化/Language/en.lproj/Localizable.txt
        #/Users/odd/Documents/Project/测试国际化/Language/en.lproj/Localizable.strings
        '''
    
        print("可以配置调整路径:")
        # 国际化语言文件
        languageFile = "/Users/odd/Documents/Project/测试国际化/Language"
        # 需要国际化的语言文件名
        languageLocalizableName = "Localizable.strings"
        # 打开excel文件读取数据
        languageExcefilePath = "/Users/odd/Documents/Project/测试国际化/Language/Language.xlsx"
        # 添加版本分割注释(可加可不加)
        versionMark = "// ==================== V1.0.0 ==================== //"
        #versionMark = ""
    
        
        # 打开Excel
        languageExceData = xlrd.open_workbook(languageExcefilePath)
    
        table = languageExceData.sheets()[0] # 表头
        nrows = table.nrows  # 行数
        ncols = table.ncols  # 列数
        
        firstRowDatas = table.row_values(0);
        print(firstRowDatas);
    
        # 对应语言文件夹
        languageLprojName = ""
    
        index = 1
        for firtName in firstRowDatas:
    
            if firtName.upper() == "KEY":
                print("跳过:"+firtName)
                continue
                
            print("\n===========开始写文件=========")
            print("\n===========" + firtName + "===========\n")
            print("开发处理语言文件:" + firtName + " : 第 "+ str(index) + " 个\n")
            
            # 写入文件路径
            languageLprojName = languageFileName(firtName)
            languagePathDir = languageFile+"/"+languageLprojName
            languagePathFile = languageFile+"/"+languageLprojName+"/"+languageLocalizableName
    
            # 判断文件目录是否存在
            isPathExitsDir(languagePathDir)
            # 判断文件是否存在,不存在,则创建
            isPathExitsFile(languagePathFile)
    
            #
            # 尽量不要清空处理
            # 若想调整文档顺序一致,可以先清空一次(要确保文档里的,已经存在excel里)
            # clearLocalization(languagePathFile)
            '''
            #1、可以先用CCExcelToLocalizationTool.py:把要导入更新的excel里的文案加入翻译里
            #2、在用CCLocalizationToExcelTool.py:把已经处理的文案导入到excel里
            #3、在调用CCExcelToLocalizationTool.py时,打开清理clearLocalization(languagePathFile)
            '''
            
            # 读取文件内容,格式化处理
            sourceTxtDic = readTxtToDic(languagePathFile)
        
            needWriteMark = isNeedVersionMark(languagePathFile,versionMark)
    
            #先追加在替换
            sqlfile = open(languagePathFile,"a")
            replateArray = []
            for ronum in range(1, nrows):
                #这行有多少列
                row = table.row_values(ronum)
    
                #过滤空方式:s.strip()=='',len(s) ==0,s.isspace() == True 
                rowFirstKey = str(row[0]).strip()
                if rowFirstKey == '':
                    print("跳过:空数据,第"+str(ronum)+"行")
                    continue
    
                # 将行数据拼接成字符串
                rowValue = handleRowIndexContent(row,index)
                rowKey = str(row[0]).strip()
                # print("======== 行key: "+rowKey)
                if rowKey in sourceTxtDic.keys():
                    print("包含:"+rowKey + " 修改value: " + rowValue)
                    sourceVlaue = sourceTxtDic[rowKey]
                    sourceVlaue["value"] = rowValue
                    replateArray.append(sourceVlaue)
    
                else:
                    print("追加:"+rowKey + " value: " + rowValue)
                    if versionMark != "" and needWriteMark:
                        print("=========添加分割标识=======")
                        sqlfile.writelines(versionMark + "\r") #将字符串写入新文件
                        needWriteMark = False
                        
                    sqlfile.writelines(rowValue + "\r") #将字符串写入新文件
            sqlfile.close() # 关闭写入的文件
    
            # #替换
            sqlReplacefile = open(languagePathFile,"r+")
            relpaceLines = sqlReplacefile.readlines()
    
            #print("读取原始txt内容:")
            #print(relpaceLines)
            #print("\n")
            # 序号+内容
            for txtIndex, txtItem in enumerate(relpaceLines):
                #移除 原始内容中行最后默认的\\n,
                txtItem = txtItem.strip('\n')
                relpaceLines[txtIndex] = txtItem
     
            #print("读取去掉\\n换行txt内容:")
            #print(relpaceLines)
            #print("\n")
            
            # 如果向文件写入数据后,不想马上关闭文件,也可以调用文件对象提供的 flush() 函数,它可以实现将缓冲区的数据写入文件中
            for replaceDic in replateArray:
                replaceRow = replaceDic["row"]
                replaceValue = replaceDic["value"]
                print("替换:" + " 行 " + replaceRow + " key: " + replaceDic["key"] + " value: " + replaceValue)
                # 替换需要改变的内容
                relpaceLines[int(replaceRow)] = replaceValue
    
            sqlWriteFile = open(languagePathFile,"w+")
            #写入对应行+换行
            sqlWriteFile.writelines([tempLine+"\r" for tempLine in relpaceLines])
            sqlWriteFile.close()
            sqlReplacefile.close()
    
            index = index + 1
        print("\n===========结束写文件=========\n")
    
     
    # 将excel首行的key与其他行分别拼接处理
    def handleRowIndexContent(row,index):
    
        #strip方法用于去除字符串首尾空格
        #效果:"key" = "value";
        values = "\"" +str(row[0]).strip() + "\"" + " = " + "\"" +str(row[index]).strip() + "\"" + ";"
        #print("将excel首行的key与其他行分别拼接处理:\n"+values)
        return values
    
    # 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";"
    row = "0" #第几行
    
    itemDic = {"key":rowKey, "value":rowValue, "row":row}
    dic={rowKey=ItemDic}
    """
    def readTxtToDic(txtPath):
    
        #item.endswith('.mp4')
        # line.startswith('#')
        #b = True a = bool(1-b)
        #bool()函数中的1-bool值 就是取bool值的反值了。
        
        if not os.path.exists(txtPath):
            print("读取国际化语言文件不存在")
            return {}
    
        txtDic = {}
        with open(txtPath,"r") as f:
            txtData = f.readlines()
            # print("\ntxt内容:读取所以内容,并以数组格式返回,会读取到'\\n'")
            #print(txtData)
            #print("\n")
            #['"cancel"="CANCEL11"\n', '"done"="Done222"\n']
    
            lineIndex = 0
            for line in txtData:
                #移除 \\n
                line = line.strip('\n')
                #print(line)
                #判断以"开头,
                if line.startswith("\""):
                    rowDataList = line.split('=')
                    
                    # key先移除首尾空,在移除"符号
                    key = clearTextBeginEnd(rowDataList[0],"\"")
                    value = rowDataList[1].strip()
                    print("read 行: " + str(lineIndex) + " key: " + key + " value: " + value)
                    txtDic[key] = {"key":key,"value":value,"row":str(lineIndex)}
    
                lineIndex = lineIndex + 1
            f.close()
    
        #print("字典集合:")
        #print("key==============\n")
        #print(list(txtDic.keys()))
        #print(txtDic)
        return txtDic
    
    # 是否需要添加版本分割标识
    def isNeedVersionMark(filePath,versionMark):
    
        if versionMark == "":
            return False
            
        ishas = True
        with open(filePath,"r") as f:
             txtData = f.readlines()
             for line in txtData:
                # 或 versionMark in line
                if line.find(versionMark) != -1:
                    ishas = False
             f.close
        return ishas
        
    # 读取txt内容方式
    def readeTxtFile(filePath):
        # 一次性读取txt内容
        with open(filePath,"r") as f:
            txtData = f.read()
            print("txt内容:一次性读取")
            print(txtData)
            f.close()
    
        with open(filePath,"r") as f:
            txtData = f.readline()
            print("txt内容:读取一行")
            print(txtData)
            f.close()
    
        # with open(filePath,"r") as f:
        #     txtData = f.readlines()
        #     print("txt内容:读取所以内容,并以数组格式返回,会读取到'\\n'")
        #     #print(txtData)
        #     #['"cancel"="CANCEL11"\n', '"done"="Done222"\n']
        #     for line in txtData:
        #         #移除
        #         line = line.strip('\n')
        #         print(line)
        #     f.close()
        
    
    
    # 写txt文件追加
    def writetxt_a(txt,path):
        #f.seek(0):把文件定位到数据起始位置(index=0),
        #若没有这句,文件默认定位到数据结束位置,w.truncate()不起作用
        with codecs.open(path,'a','utf-8') as f:
            f.seek(0)    # 定位
            f.truncate()  # 清空文件
            f.write(txt)
            f.close()
    
    # 清空内容,可以保持顺序一致
    def clearLocalization(path):
        # 清空文件内容
        clearTextContent(path)
        #读取txt内容
        #readeTxtFile(path)
            
        
    # 清空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
        
    # 将excel某行的数据,拼接处理
    def strs(row):
        values = "";
        for i in range(len(row)):
            if i == len(row) - 1:
                values = values + str(row[I])
            else:
                values = values + str(row[i]) + ","
        return values
    
    read_excel_to_txt()
    

    相关文章

      网友评论

          本文标题:iOS【语言国际化处理】python脚本读取Excel内容批量导

          本文链接:https://www.haomeiwen.com/subject/ecovnltx.html