テキストデータを半自動でExcelに貼り付け



# はじめに

**追記：**この記事を作ってから気づいたのですが**処理が遅い**です…。あとスクリプトが走っている途中でExcelを触ると**処理が止まります**。**0(:3 )〜 _('､3｣ ∠ )_**
xlwingsの紹介程度で


会社の評価業務で大量のデータをグラフ化しなければならいことは良くあると思います。どんな形式のグラフでも良い場合は問題ないと思いますが、**Excel**で作らなければならない場面もあると思います。前まではグラフを事前に作ったExcelのテンプレートに評価データをテキストエディタで開いて**Ctrl+C**、**Ctrl+V**しまくっていたのですが、限界が来たのでスクリプトを組みました。下の方で自分が作った環境とスクリプトの説明を載せます。きっと改造したいと思う人がいると思うので参考にしてください。


# 環境
今回はPythonで組んでいます(私がVBを知らないだけです)。PythonでExcelを操作出来るライブラリは色々ありますが、殆どのライブラリは**Open**すると**グラフ情報が消失**してしまいます。今回使っている**xlwings**はグラフ情報が消えないので採用しました。
今回使用した環境は以下の通りです。

- Windows10
- Python 3.5.1
- xlwings 0.11.4
- pywin32 221

**Pythonが3.6**以上ではないのは**win32api**関係のエラーを自分が解決出来なかったからです。**3.5**ならエラーが出なかったので今回はこれで作成しました。[**xlwings**](https://www.xlwings.org/)の導入はpipで問題ないのでpipで入れます。
**参考：**[**xlwings公式の解説ページ**](http://docs.xlwings.org/en/stable/installation.html)

```
pip install xlwings
```
これだけ良いと思っていたのですがこれだけではエラーが出るのでpywin32を入れます。自分は[**ここ**](https://sourceforge.net/projects/pywin32/files/pywin32/)から取ってきました。[**ここ**](https://sourceforge.net/projects/pywin32/files/pywin32/)の**221**の**pywin32-221.win-amd64-py3.5.exe**を落とします(各自Pythonのバージョンのものを落とす)。落としたら以下のコマンドで入れます。

```
easy_install pywin32-221.win-amd64-py3.5.exe
```
環境は以上で整います。この方法を3.6で実行するとなぜかうまく出来ませんでした。

# 実行コード

上記の環境でこれが動くようになると思います。

```py3:xls-paste.py
import xlwings as xw
import sys

args = sys.argv

xls_file = args[1]
out_file = args[2]
file_list = args[3]

#Write  Excel
wb = xw.Book(xls_file)
for line_data in open(file_list, "r"):
    if line_data[0] == "#":
        continue
    split_line_data = line_data.split()

    sheets = split_line_data[1]
    offset_x = int(split_line_data[2]) + 1
    offset_y = int(split_line_data[3]) + 1

    y = 0
    for text_data in open(split_line_data[0], "r"):
        data = text_data.split()
        wb.sheets[sheets].range(offset_y + y, offset_x).value = data
        y += 1

#Save Excel
wb.save(out_file)
```
**コード変だぞ**って声が聞こえて来そうですが許してください。あと自分仕様になっています。このコードでは実行するのに引数が3つあり、**Excelテンプレート**と**出力Excel名**と**ファイルリスト**が必要になっています。

##Excelテンプレート

下の画像のようにグラフのエリアを設定しデータを空にしたExcelテンプレートを作成します(空じゃなくても上書きされるだけです)。評価項目が事前に決まっていれば、グラフの書式が決まっていると思うのでそれで作っておきます。ここで**業務で指定されているグラフ書式**を使いまわすことが出来ます。グラフだけではなくExcelの関数とかも事前に入れることが出来るので**SUM**とか**AVERAGE**とか**STDEV**とか評価に必要なものも組んでおくと捗ります。
![スクリーンショット 2017-12-05 19.22.11.png](https://qiita-image-store.s3.amazonaws.com/0/97833/0ead03d2-134a-1946-bae6-d930d6e4fbbe.png)

template.xls


## ファイルリストの書式

```:file_list.txt
#data path          sheet-name  offsetX offsetY
./data/data1.txt	Sheet1      0       0
./data/data2.txt	Sheet2      0       0
./data/data1.txt	Sheet3      0       0
./data/data2.txt	Sheet3      7       0
```


- data path
    - 貼り付けたいデータの相対パスか絶対パス
- sheet name
    - Excelのテンプレートシート名
- offsetX
    - 貼り付けたいデータのX始点
- offsetY
    - 貼り付けたいデータのY始点

## テキストデータ
テキストデータは、空白かカンマ区切りなどで認識すると思います。


```:data1.txt
*   10  20  30  40  50
A   1   2   3   4   5
B   6   7   8   9   10
C   11  12  13  14  15
D   16  17  18  19  20
E   21  22  23  24  25
```

## 実行例
上で説明したデータを用意して以下のコマンドを入力すると

```
python xls-paste.py template.xls out.xls file_list.txt
```

![スクリーンショット 2017-12-05 19.23.25.png](https://qiita-image-store.s3.amazonaws.com/0/97833/93543ebd-2bf8-bd38-c631-75ac124baf22.png)


こんな感じでデータが貼り付けられグラフが出来ていると思います。入力テキストデータのファイル名前が変わらなければデータを差し替えて実行すれば~~一瞬~~でグラフが完成します。さらにこのコマンドをbatで組んで複数のテンプレートとファイルリストを用意して…って感じで全部自動でやってしまいましょう。

# おわりに
これのスクリプトを作るのにだいたい4時間くらいかかっています(ほぼ環境を作っている時間)。業務で**Ctrl+C**、**Ctrl+V**していた時間は16時間くらい(データ処理しながら)ですので機能としてしょぼくても大体スクリプト化した方が良かったりします。それにこれ以降にも同じ業務が来る可能性もあります…なので色々なスクリプト術を習得して損はないと思います。**[GitHub](https://github.com/kkumt93/xls-paste)**にも公開しておきますので参考になれば幸いです。