【工具】自动生成国际化string.xml


我们做app时候,有时候会遇到国际化需求,由于前期我们做项目时候是以单语种进行开发,这里说的单语种当然是中文了,这里我们列举几个常用的 Android 语种规范

1. 常见的语种

我们可以借助 AndroidStudio 去创建这样的目录,具体操作为:

  1. 选择 res 目录,右键,依次选择 New -> Android Resource Directory 在这里插入图片描述
  2. 在弹出面板下的 Available qualifiers 下选择 Local,并且单击中间 >> 符号,Resource type 按默认的选择 valuse即可
    在这里插入图片描述
  3. 看面板中以中文为例,依次选择 Language 中的 zh,接着选择 Specific Region Only 中的CN
    在这里插入图片描述
    点击OK后,我们就可以在 res目录看到 values-zh-rCN的目录了,当然这里也可以不需要选择最后一栏的 CN 也是可以的,选择 Specific Region Only 的最上行 Any Region即可去掉 rCN

从上面的步骤中,我们大致罗列几种开发中常见的语种

  1. values-en:英语语种
  2. values-fa:法语语种
  3. values-es:西班牙语种
  4. values-ja:日语语种
  5. values-zh-rTW:中国台湾

2. 国际化表格

这里我们用的是 xls的表格来罗列国际化的语言字段,形如下表这样的 translation.xls
在这里插入图片描述
如果遇到非 xls 的表格,建议可以重写另存为一份 xls 表格

3. 自动生成相应资源文件

我们是基于 jxl进行,所以还需要依赖一个 jxl:

dependencies{
 	implementation 'net.sourceforge.jexcelapi:jxl:2.6.12'
}

不多解释,直接上代码;

package com.monk.customlib

import jxl.Workbook
import jxl.WorkbookSettings
import java.io.BufferedWriter
import java.io.File
import java.io.FileWriter

/**
 * @since 2022/08/31 20:02
 * @author monk
 */
object TranslationTools {

    @JvmStatic
    fun main(args: Array<String>) {
        val sheetNums = Workbook.getWorkbook(xlsFile, workbookSettings).numberOfSheets
        for (sheetNum in 0 until sheetNums) {
            // 第2列(column = B)开始国际化,一共有3列是需要国际化
            handleXlsExcel(sheetNum, 1, 3)
        }
    }

    private val codeMap: HashMap<Int, String> = HashMap()
    private val keyAndValueMap: HashMap<String, ArrayList<TranslationBean>> = HashMap()

    private const val DIR = "C:\\Users\\Administrator\\Desktop\\translation"
    // 只支持 xls格式
    private const val XLS_PATH = "$DIR\\translation.xls"

    private val xlsFile = File(XLS_PATH)
    private val workbookSettings = WorkbookSettings()

    init {
        if (codeMap.isNotEmpty()) codeMap.clear()
        if (keyAndValueMap.isNotEmpty()) keyAndValueMap.clear()

        // 这里设置为 utf-8 或者 gbk 或者 iso-885901,这里设置后者防止其它国家文字乱码
        workbookSettings.encoding = "ISO-8859-1"
    }

    /**
     * @param sheetNum: 表示sheet页数量(0表示第1张sheet)
     * @param startColumn: 从0开始,第几列开始是国际化
     * @param columnCount: 一共有多少列是国际化
     */
    @kotlin.jvm.Throws(Exception::class)
    fun handleXlsExcel(sheetNum: Int, startColumn: Int, columnCount: Int) {
        // workbook 与 sheet 是一对一
        val workbook: Workbook = Workbook.getWorkbook(xlsFile, workbookSettings)
        val sheet = workbook.getSheet(sheetNum)

        println("sheet0 = ${sheet.name}")
        // 表示从第1行开始读取
        for (row in 0 until sheet.rows) {
            if (row == 0) {
                for (column in 0 until columnCount) {
                    val columnIndex = startColumn + column
                    // B1, C1, D1单元格的内容表示国家代码
                    val code = sheet.getCell(columnIndex, row).contents
                    codeMap[columnIndex] = code
                    keyAndValueMap[code] = ArrayList()
                }
            } else {
                // A1 ~ A[num] 单元格
                val key = sheet.getCell(0, row).contents
                if (key == null || "" == key) break
                for (column in 0 until columnCount) {
                    val columnIndex = startColumn + column
                    val code = codeMap[columnIndex] ?: "null"
                    val bean = TranslationBean(
                        key,
                        sheet.getCell(columnIndex, row).contents
                    )
                    val translationList = keyAndValueMap[code]
                    translationList?.add(bean)
                }
            }
        }
        workbook.close()
        val dir = File(DIR, sheet.name)
        if (!dir.exists()) dir.mkdir()
        for (code in keyAndValueMap.keys) {
            val default = File(dir, "values-$code")
            if (!default.exists()) default.mkdir()
            val file = File(default, "strings.xml")
            try {
                if (!file.exists()) file.createNewFile()
                val bw = BufferedWriter(FileWriter(file))
                bw.write("<resources>")
                bw.newLine()
                keyAndValueMap[code]?.forEach { value ->
                    bw.write("<string name=\"${value.key}\">${value.value}</string>")
                    bw.newLine()
                }
                bw.write("</resources>")
                bw.close()
                println("生成成功...")
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    data class TranslationBean(
        val key: String,
        val value: String
    )

}

效果如下
在这里插入图片描述 在这里插入图片描述
values-中文(values-zh-rCN)
在这里插入图片描述

values-日文(values-ja)
在这里插入图片描述
values-英文(values)
在这里插入图片描述
最后将生成的目录修改成规范化的目录,或者在一开始的 excel 表格中将 sheet 页定成android规范的语种也是可以的

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值