Excelの文言管理ファイルからAndroid/iOSの文言データを作成

# やりたい事
Android/iOSアプリを同時開発している場合、文言に差分が出ないように文言管理ファイルを別途作成する事があるかと思います。今回は文言管理ファイルはExcelで記述して、そこからAndroid/iOSの文言データを作成する事をやってみようと思います。以下、環境はMacOS High Sierraで行っています。

# 外部仕様

入力データ：Excelファイル
出力データ：string.xml(Android)、Localizable.settings(iOS)

機能:

* Excelファイルを入力すると上記文言データを出力します。
* ja,enなどの言語設定で言語に応じた文言データを出力します。

# 利用ソフトウェア
xlrdというpythonライブラリを用いる事でpythonでExcelファイルを作成する事ができる事が分かりました。

* python (今回は2系を使っています）
* xlrd https://xlrd.readthedocs.io/en/latest/

```bash
$ pip install xlrd
```

# 入力ファイル
入力されるExcelファイルは以下のような形式になります。文言のIDと日本語、英語の順に並ぶ形となります。
![スクリーンショット 2019-05-20 15.05.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85182/a55c79a0-194f-c2f0-0c9f-4b4fbe67d29b.png)
Excelの文字コードはUTF16LEになります。

# Excelファイルの読み込み
xlrdを用いてExcelファイルからデータを読み取ります。Excelファイルは以下の関数で読み取る事ができます。

```python
import xlrd

wb = xlrd.open_workbook('ファイルパス', encoding_override='utf_16_le')
```
UTF16LEの場合は指定しなくても問題ありませんが、古いExcelファイルを開く場合はUTF16LEではありませんので、エンコーディングを指定する必要があります。
https://xlrd.readthedocs.io/en/latest/unicode.html

Excelファイルの中のシートを開く方法は以下の2種類用意されています。
https://xlrd.readthedocs.io/en/latest/api.html#module-xlrd.book

* sheet_by_index(sheetx)
* sheet_by_name(sheet_name)

今回は名前でシートを開きます。入力データではシートの名前を"strings"にしています。

```python
sheet = wb.sheet_by_name('strings')
```

Excelファイルパスと言語("ja", "en")を指定すると文言データのキーのリストと、データのリストを取得できるクラスを以下のように作成しました。

```python
class StringBase:
    def __init__(self, input_document, lang):
        self.input_document = input_document
        self.lang = lang

    def parse_values_by_language(self, sheet):
        titles = sheet.row_values(0)
        col = 0
        for title in titles:
            if title == self.lang:
                values = sheet.col_values(col)
                del values[0] # remove title of colomn values                                                                                                                                                    
                return values
            else:
                col = col + 1
        return null

    def parse_strings(self):
        wb = xlrd.open_workbook(self.input_document, encoding_override='utf_16_le')
        sheet = wb.sheet_by_name('strings')
        keys = sheet.col_values(0)
        del keys[0] # remove title of colomn values                                                                                                                                                              
        values = self.parse_values_by_language(sheet)
        if len(keys) != len(values):
            print 'Invalid String Base Excel File !!'
            return null,null
        return keys, values

```

# Androidの文言ファイルへの書き出し
Androidはstring.xmlが出力ファイルですが、上記の文言キーと、データのリストからXMLファイルを作成するクラスを以下のように記述しました。python2.7系でやっている事もあり、UTF8にするためにencodeしています。

```python
class AndroidFile:
    def __init__(self, keys, values):
        self.keys = keys
        self.values = values

    def output_string_file(self):
        f = open('string.xml', mode='w')
        f.write('<resources>\n')
        for i in range(len(keys)):
            key = keys[i].encode('utf-8')
            value = values[i].encode('utf-8')
            f.write('    <string name=\"' + key + '\">' + value + '</string>\n')
        f.write('</resources>\n')
        f.close
```

出力ファイルは以下のように出力されます。

```xml
<resources>
    <string name="app_name">アプリケーション名</string>
    <string name="search">検索</string>
    <string name="search_description">デバイスを検索します</string>
    <string name="search_note">デバイスがスマートフォンから遠い場合は見つかりません。</string>
    <string name="next">次</string>
    <string name="prev">前</string>
</resources>
```

# iOSの文言ファイルへの書き出し
iOSアプリの文言ファイルはLocalizable.stringsですが、こちらも同様に文言キーとデータのリストから文言ファイルを作成するクラスを作成しました。

```python
class IOSFile:
    def __init__(self, keys, values):
        self.keys = keys
        self.values = values

    def output_string_file(self):
        f = open('Localizable.strings', mode='w')
        for i in range(len(keys)):
            key = keys[i].encode('utf-8')
            value = values[i].encode('utf-8')
            f.write('\"' + key + '\" = \"' + value + '\";\n')
        f.close
```
出力ファイルは以下のようになります。

```
"app_name" = "アプリケーション名";
"search" = "検索";
"search_description" = "デバイスを検索します";
"search_note" = "デバイスがスマートフォンから遠い場合は見つかりません。";
"next" = "次";
"prev" = "前";
```

# 終わりに

上記のツールで、文言の管理自体はExcelで行って、そこからAndroid,iOSの文言ファイルを作成できるようになりました。