カテゴリー

Python基礎

【Python&Excel】openpyxlでフォルダ内の複数csv→1つのExcelへ

2022年2月20日

こんな人にオススメ

複数のcsvのデータを新規で作った1つのExcelファイルに書き出したい!それに読み込んだcsvファイルからできるグラフを新規のExcelファイルに貼り付けたい!

ということで、今回は複数のcsvファイルのデータを1つのExcelファイルにまとめ、グラフも作って貼り付ける方法をopenpyxlを使って解説する。

この方法をマスターすると実験や測定で得られる複数のcsvファイルをいちいち開いてデータをコピーしてメインのExcelファイルにコピペして最後にグラフ化っていう作業が必要なくなる。

1つ2つのcsvなら手作業でもいいけど、これが10csvファイルとかになるとグラフ化した時には多分、天使が見えるだろう。是非ともプログラミングで楽をしたい。

python環境は以下。

  • Python 3.10.1
  • natsort 7.0.1
  • pandas 1.3.5
  • openpyxl 3.0.5
スポンサーリンク
スポンサーリンク

運営者のメガネです。TwitterInstagramも運営してます。

自己紹介はこちらから、お問い合わせはこちら。

運営者メガネ

作成したコード全文

下準備(import

import glob
import natsort
import pandas as pd
import openpyxl
from openpyxl.chart import ScatterChart, Reference, Series

まずは下準備としてのimport関連。globnatsortで指定したフォルダ内のcsvファイルを取得してソートする。1ファイルずつ指定するのが面倒なので自動でファイルを取ってきてもらう。

pandasは1ファイルずつ読み込む際に使用。numpyとかでもいいけど、pandasの方が簡単に処理できると思ったのでpandasにした。

最後はメインとなるopenpyxl。これを使うことでPythonでExcelの操作や書き出しやグラフ化をすることができる。from openpyxl.chartでグラフに関するオブジェクトをimportできる。

各csvデータをそれぞれExcelのグラフに

完成イメージは上の画像の通り。X0, Y0が1つのデータで、それに対してグラフを作成している。これをX1, Y1の組み合わせ、X2, Y2にも適用してグラフ化する方法を解説する。

作成手順は以下。

  1. csvファイルを読み込み
  2. 出力用のExcelファイルを作成
  3. 各csvファイルを出力用のExcelファイルへ書き出し
  4. csvファイルのデータをグラフ化

読み込むcsvファイル

まずは読み込むcsvファイルを示す。以下のデータを1つずつExcelファイルへ書き込んでグラフ化する。今回は3ファイル。

data0.csv↓

X

Y

0

2

1

8

2

4

3

5

4

1

5

0

data1.csv↓

X

Y

0

3

1

6

2

1

3

9

4

0

5

3

data2.csv↓

X

Y

0

4

1

6

2

2

3

3

4

4

5

1

作成コード全文

次に上の画像のようなExcelファイルを作成するためのコードを示す。割と長いので折りたたみで表示しておく。

以下より各項目を解説する。

csvファイルを読み込む

# 読み込みファイルの共通した接頭辞・接尾辞・拡張子

prefix = 'data'
suffix = ''
extension = '.csv'
# 以下の形式でファイルを読み込む
file_name = f'{prefix}*{suffix}{extension}'

# このpyファイルと同じディレクトリのファイルをソートして抽出
file_list = natsort.natsorted(glob.glob(file_name))
print(file_list)
# ['data0.csv', 'data1.csv', 'data2.csv']

まずはcsvファイルを読み込む作業。ファイルはdata0.csvなどのように共通部分があって、連番で区別する場合は上のコードで読み込める。

prefixで接頭辞、suffixで接尾辞、そしてextensionで拡張子を指定する。連番などはglob*を使って変数のように扱う。

natosortはdata0→data1→data10→data2のように、1→10の順番になるのを防ぐために導入。

出力用のExcelファイルを作成

# 出力用のExcelファイル(ワークブック)の作成

wb = openpyxl.Workbook()
# 作成したワークブックを保存
output_name = 'output_csv_each.xlsx'
wb.save(output_name)

# 出力用のワークブックの読み込み
wb = openpyxl.load_workbook(output_name)
# ワークシートの選択(アクティブなワークシートを自動選択)
ws = wb.active

続いては最終的にデータをまとめてグラフ化するためのExcelファイル(ワークブック)を作成。

openpyxl.Workbook()で新規でワークブックを作成、これをwb.saveで保存する。保存しておかないと設定内容が反映されないので注意。

保存したらこのExcelファイルをopenpyxl.load_workbookで読み込む。また、Excelではシートという概念があるので、アクティブなシート(デフォルトでは最初のシート)をwb.activeで指定した。

読み込んだファイルをExcelに出力

# 抽出した各Excelのデータを出力用のExcelファイルへ書き出し
# ついでにグラフ化もする

# 読み込みたいファイルで回す
for number, name in enumerate(file_list):
    # csvファイルをpandasで読み込み
    df = pd.read_csv(name)
    # 値の部分だけ取り出し
    values = df.values

    # ヘッダーの作成
    # .columnsでデータフレームからヘッダーを取り出す
    header_x = f"{df.columns[0]}{number}"
    header_y = f"{df.columns[1]}{number}"

    # 書き込む先の列を決める
    # chrでアルファベットに変換
    cell_x = chr(65 + 2 * number)  # 初めはA列、その次はC列
    cell_y = chr(65 + 2 * number + 1)  # 初めはB列、その次はD列
    ws[f'{cell_x}1'] = header_x
    ws[f'{cell_y}1'] = header_y

    # データフレームから取り出した値を行ごとに回す
    for num, rows in enumerate(values, 1):
        x = rows[0]  # 各行の横軸の値
        y = rows[1]  # 各行の縦軸の値

        # 出力用のワークブックに書き込み
        ws[f'{cell_x}{num + 1}'] = x
        ws[f'{cell_y}{num + 1}'] = y

    # グラフ化するためのScatterChartオブジェクト作成
    chart = ScatterChart()

    # グラフの作成
    # 最大の行数 = 書き込む最後の行番号
    max_row = len(values)
    # xの範囲を設定
    x_values = Reference(
        ws,  # ワークシート
        min_col=2 * number + 1,  # 初めの列番号(1ファイルごとにずらす)
        max_col=2 * number + 1,  # 最後の列番号(1ファイルごとにずらす)
        min_row=2,  # 初めの行番号(ヘッダーを除くので2スタート)
        max_row=max_row  # 最後の行番号
    )
    # yの範囲を設定
    y_values = Reference(
        ws,
        min_col=2 * number + 1 + 1,
        max_col=2 * number + 1 + 1,
        min_row=2,
        max_row=max_row
    )

    # グラフの追加
    series = Series(y_values, x_values, title=header_y)
    chart.series.append(series)

    # グラフを設置B列から設置(設置位置は微調節)
    position = f"{chr(65 + 9 * number)}{max_row + 3}"  # グラフを設置するセル番地
    ws.add_chart(chart, position)  # グラフの設置
    # ワークブックの保存
    wb.save(output_name)

# 保存
wb.save(output_name)

最後はExcelへ出力する作業。手順は以下。

  1. 各csvファイルごとにforループ
  2. ループごとにcsvファイルを読み込んで値部分を抽出
  3. ヘッダーをExcelに書き込み
  4. 各csvのデータを1行ずつExcelへ書き込み
  5. グラフの雛形作成
  6. グラフのx, yを設定・反映
  7. グラフをExcelに貼り付け
  8. Excelファイルを保存

まずは各csvファイルをforループで読み込む。globでフォルダー内のcsvファイルは抽出できたので、これをforで回せばいいだけ。

# 読み込みたいファイルで回す
for number, name in enumerate(file_list):
    # csvファイルをpandasで読み込み
    df = pd.read_csv(name)
    # 値の部分だけ取り出し
    ws_tmp = df.values

続いてはヘッダーの作成。pandasのデータフレームではdf.columnsの形式でヘッダーを取り出すことができる。なお、data0ではX0, Y0に、data1ではX1, Y1となるようにf文字で{number}と連番を振っている。

ヘッダーを取り出せたら、これを出力用のExcelファイルへ書き出す。書き出す際にはセルの位置を指定しないといけない。

ExcelのセルはA1やB3のようにアルファベット+数値で表されるので、charで数値をアルファベットに変換している。大文字はchar(65)がAに該当するから、これを2n+1の形式で1つ飛ばしで指定することで、複数csvファイルを横並びで書き込める。

    # ヘッダーの作成
    # .columnsでデータフレームからヘッダーを取り出す
    header_x = f"{df.columns[0]}{number}"
    header_y = f"{df.columns[1]}{number}"

    # 書き込む先の列を決める
    # chrでアルファベットに変換
    cell_x = chr(65 + 2 * number)  # 初めはA列、その次はC列
    cell_y = chr(65 + 2 * number + 1)  # 初めはB列、その次はD列
    ws[f'{cell_x}1'] = header_x
    ws[f'{cell_y}1'] = header_y

forで回しながらcsvのヘッダーを作成できたので、次は各値を書き込んでいく。

openpyxlでは配列をそのまま書き込めないっぽいので、forで1行ずつ読み込んで1セルずつ書き込むことにした。なので、変数valuesで読み込んだ2次元配列をforの変数rowsで行ごとに抜き出した。

今回は0番目がx、1番目がyに該当するのでそれぞれx, yの変数に代入。あとはヘッダーと同じように1セルずつExcelに書き出せばいい。

    # データフレームから取り出した値を行ごとに回す
    for num, rows in enumerate(values, 1):
        x = rows[0]  # 各行の横軸の値
        y = rows[1]  # 各行の縦軸の値

        # 出力用のワークブックに書き込み
        ws[f'{cell_x}{num + 1}'] = x
        ws[f'{cell_y}{num + 1}'] = y

グラフの作成はopenpyxl.chartで行う。今回は散布図を作成するのでScatterChartを使用。棒グラフならBarChart、折れ線グラフならLineChartとなる。

まずはグラフの雛形を作成。シンプルにScatterChart()とするだけ。これにx, yのセルを指定する。

    # グラフ化するためのScatterChartオブジェクト作成
    chart = ScatterChart()

x, yの指定はReferenceを使用。こちらもScatterChart同様openpyxl.chartからimportすることができる。必要な引数は出力先のシートと、x, yそれぞれの開始セル位置・終了セル位置。

今回は各csvでA列がx、B列がyに該当するので列は2n+1の概念で1つ飛ばしで指定。行については、開始位置はヘッダーがあるので2行目から、終了位置は変数valuesの長さで指定した。

グラフ化したいx, yの位置を指定できたら、Seriesで指定すれば良い。引数titleはプロットの凡例。ここでは各データのYのヘッダー名を使用した。

    # データをシートに書き込み
    # 最大の行数 = 書き込む最後の行番号
    max_row = len(values)
    # xの範囲を設定
    x_values = Reference(
        ws,  # ワークシート
        min_col=2 * number + 1,  # 初めの列番号(1ファイルごとにずらす)
        max_col=2 * number + 1,  # 最後の列番号(1ファイルごとにずらす)
        min_row=2,  # 初めの行番号(ヘッダーを除くので2スタート)
        max_row=max_row  # 最後の行番号
    )
    # yの範囲を設定
    y_values = Reference(
        ws,
        min_col=2 * number + 1 + 1,
        max_col=2 * number + 1 + 1,
        min_row=2,
        max_row=max_row
    )

    # グラフの追加
    series = Series(y_values, x_values, title=header_y)
    chart.series.append(series)

これでグラフ化が完了したので、これを出力用のExcelに貼り付ける。ここまでではまだグラフが完成しただけで、Excelには反映できていない。

なので最後にws.add_chartでグラフを貼り付ける必要がある。貼り付ける位置はpositionでいい感じの位置になるように微調整した。グラフのサイズを変更する方法は後述するが、ScatterChart作成時に以下のように高さと幅を変更したらいい。

# グラフ化するためのScatterChartオブジェクト作成
chart = ScatterChart()
# グラフの高さと幅
chart.height = 15
chart.width = 25
    # グラフを設置B列から設置(設置位置は微調節)
    position = f"{chr(65 + 9 * number)}{max_row + 3}"  # グラフを設置するセル番地
    ws.add_chart(chart, position)  # グラフの設置
    # ワークブックの保存
    wb.save(output_name)

最後に色々と修正したExcelファイルを保存する。これで完成。

# 保存
wb.save(output_name)

出来上がるExcelファイルが以下。最初に示したのと同じ。

各ExcelデータをそれぞれExcelのグラフに

完成イメージは上の画像の通り。さっきのcsv版と同じようにX0, Y0が1つのデータで、それに対してグラフを作成している。これをX1, Y1の組み合わせ、X2, Y2にも適用してグラフ化する方法を解説する。

単に読み込むデータがcsvからxlsxに置き換わっただけだ。ただ、Excelにすると文字コードなどが関係してきてpandasで読み込めないことがあるので、コード自体は変更される。

作成手順は以下。

  1. xlsxファイルを読み込み
  2. 出力用のExcelファイルを作成
  3. 各xlsxファイルを出力用のExcelファイルへ書き出し
  4. 読み込んだxlsxファイルのデータをグラフ化

読み込むxlsxファイル

まずは読み込むxlsxファイルを示す。さっきのcsvの時と同じ。以下のデータを1つずつExcelファイルへ書き込んでグラフ化する。

作成コード全文

次に上の画像のようなExcelファイルを作成するためのコードを示す。割と長いので折りたたみで表示しておく。

xlsxファイルを読み込む

# グラフ化したいデータを抽出・読み込み

# 読み込みファイルの共通した接頭辞・接尾辞・拡張子
prefix = 'data'
suffix = ''
extension = '.xlsx'
# 以下の形式でファイルを読み込む
file_name = f'{prefix}*{suffix}{extension}'

# このpyファイルと同じディレクトリのファイルをソートして抽出
file_list = natsort.natsorted(glob.glob(file_name))
print(file_list)
# ['data0.xlsx', 'data1.xlsx', 'data2.xlsx']

まとめたい・グラフ化したいxlsxファイルをglobを使って抽出。今回も3ファイルを使用したいので、そのファイル名の条件に合うように変数prefix, suffix, extensionを調整する。

出力用のExcelファイルを作成

# 出力用のExcelファイル(ワークブック)の作成

wb = openpyxl.Workbook()
# 作成したワークブックを保存
output_name = 'output_csv_each.xlsx'
wb.save(output_name)

# 出力用のワークブックの読み込み
wb = openpyxl.load_workbook(output_name)
# ワークシートの選択(アクティブなワークシートを自動選択)
ws = wb.active

続いては最終的にデータをまとめてグラフ化するためのExcelファイル(ワークブック)を作成。さっきと同じ。

openpyxl.Workbook()で新規でワークブックを作成、これをwb.saveで保存する。保存しておかないと設定内容が反映されないので注意。

保存したらこのExcelファイルをopenpyxl.load_workbookで読み込む。また、Excelではシートという概念があるので、アクティブなシート(デフォルトでは最初のシート)をwb.activeで指定した。

読み込んだファイルをExcelに出力

# 抽出した各Excelのデータを出力用のExcelファイルへ書き出し
# ついでにグラフ化もする

# 読み込みたいファイルで回す
for number, name in enumerate(file_list):
    # ワークブックの読み込み
    wb_tmp = openpyxl.load_workbook(name)
    # ワークシートの選択
    ws_tmp = wb_tmp.active

    # 各ワークブックを行ごとに読み込み
    for num, rows in enumerate(ws_tmp.rows, 1):
        # 最初の行はヘッダー(X, Y)なのでX1, Y1などデータごとに名称をつける
        if num == 1:
            x = f"{rows[0].value}{number}"  # 各行の横軸の値
            y = f"{rows[1].value}{number}"  # 各行の縦軸の値
        else:  # ヘッダー以外は数値をのまま
            x = rows[0].value  # 各行の横軸の値
            y = rows[1].value  # 各行の縦軸の値

        # 書き込む先の列を決める
        # chrでアルファベットに変換
        cell_x = chr(65 + 2 * number)  # 初めはA列、その次はC列
        cell_y = chr(65 + 2 * number + 1)  # 初めはB列、その次はD列

        # 出力用のワークブックに内容を書き込み
        ws[f'{cell_x}{num}'] = x
        ws[f'{cell_y}{num}'] = y

    # グラフ化するためのScatterChartオブジェクト作成
    chart = ScatterChart()

    # グラフの作成
    # 最大の行数 = 書き込む最後の行番号
    max_row = ws_tmp.max_row
    # xの範囲を設定
    x_values = Reference(
        ws,  # ワークシート
        min_col=2 * number + 1,  # 初めの列番号(1ファイルごとにずらす)
        min_row=2,  # 初めの行番号(ヘッダーを除くので2スタート)
        max_row=max_row  # 最後の行番号
    )
    # yの範囲を設定
    values = Reference(
        ws,
        min_col=2 * number + 1 + 1,
        max_col=2 * number + 1 + 1,
        min_row=2,
        max_row=max_row
    )

    # グラフの追加
    series = Series(values, x_values, title=f"Y{number}")
    chart.series.append(series)

    # グラフを設置B列から設置(設置位置は微調節)
    position = f"{chr(65 + 9 * number)}{max_row + 2}"  # グラフを設置するセル番地
    ws.add_chart(chart, position)  # グラフの設置
    # ワークブックの保存
    wb.save(output_name)

最後にExcelファイルへと出力する。csvファイルの読み込みとは異なり、xlsxの場合は文字コードが関係してくるのでpandasのデータフレームが活用できない。

ということで、読み込むxlsxファイルもopenpyxlを使って読み込むことにする。読み込んだxlsxファイルの初めの行をヘッダー、残りを値のデータとしてExcelファイルへと書き込む。

まずは読み込みたい各xlsxファイルから。変数file_listでxlsxファイルは抽出できているので、これらをforで回せばいい。

# 読み込みたいファイルで回す
for number, name in enumerate(file_list):
    # ワークブックの読み込み
    wb_tmp = openpyxl.load_workbook(name)
    # ワークシートの選択
    ws_tmp = wb_tmp.active

続いて、読み込んだワークブックをさらにforで回して1行ずつ取り出す。この時、1行目はヘッダーに該当するので、ifで1行目の時はf文字でX1というようにヘッダーとして扱っている。

1行ずつ取り出せたら、これを出力用のExcelファイルへと書き出す。セルの指定は先ほどと同じようにA2やB3のように指定するので、charnumを組み合わせている。

# 読み込みたいファイルで回す
for number, name in enumerate(file_list):
    # ワークブックの読み込み
    wb_tmp = openpyxl.load_workbook(name)
    # ワークシートの選択
    ws_tmp = wb_tmp.active

    # 各ワークブックを行ごとに読み込み
    for num, rows in enumerate(ws_tmp.rows, 1):
        # 最初の行はヘッダー(X, Y)なのでX1, Y1などデータごとに名称をつける
        if num == 1:
            x = f"{rows[0].value}{number}"  # 各行の横軸の値
            y = f"{rows[1].value}{number}"  # 各行の縦軸の値
        else:  # ヘッダー以外は数値をのまま
            x = rows[0].value  # 各行の横軸の値
            y = rows[1].value  # 各行の縦軸の値

        # 書き込む先の列を決める
        # chrでアルファベットに変換
        cell_x = chr(65 + 2 * number)  # 初めはA列、その次はC列
        cell_y = chr(65 + 2 * number + 1)  # 初めはB列、その次はD列

        # 出力用のワークブックに内容を書き込み
        ws[f'{cell_x}{num}'] = x
        ws[f'{cell_y}{num}'] = y

データを書き込めたらグラフを作成。グラフは雛形作成→x, yの設定→グラフの追加→グラフの貼り付け→Excelファイルの保存の順番。

# グラフ化するためのScatterChartオブジェクト作成
    chart = ScatterChart()

    # グラフの作成
    # 最大の行数 = 書き込む最後の行番号
    max_row = ws_tmp.max_row
    # xの範囲を設定
    x_values = Reference(
        ws,  # ワークシート
        min_col=2 * number + 1,  # 初めの列番号(1ファイルごとにずらす)
        min_row=2,  # 初めの行番号(ヘッダーを除くので2スタート)
        max_row=max_row  # 最後の行番号
    )
    # yの範囲を設定
    values = Reference(
        ws,
        min_col=2 * number + 1 + 1,
        max_col=2 * number + 1 + 1,
        min_row=2,
        max_row=max_row
    )

    # グラフの追加
    series = Series(values, x_values, title=f"Y{number}")
    chart.series.append(series)

    # グラフを設置B列から設置(設置位置は微調節)
    position = f"{chr(65 + 9 * number)}{max_row + 2}"  # グラフを設置するセル番地
    ws.add_chart(chart, position)  # グラフの設置
    # ワークブックの保存
    wb.save(output_name)

出来上がるファイルが以下。さっきのcsvファイルから作ったのと同じ。

各csvデータを1つのExcelのグラフに

続いては各データを1つのグラフにまとめる方法。上の例のようにシートを分けてシート「graph」にはグラフのみ、シート「data」には読み込んだデータをまとめている。

こうすることでグラフを置く位置に困らない。特に行が増えたり列が増えたりした際に重宝する。

また、ここでは完成するグラフのサイズを変更したり、グラフタイトル・軸ラベルの追加も行っている。作成手順は以下。

  1. csvファイルの読み込み
  2. 出力用のExcelファイル作成
  3. 作成時のシート削除
  4. データを入れる用・グラフ用のシートを追加
  5. グラフの雛形作成
  6. グラフのサイズやラベルなど体裁を整える
  7. 各csvファイルをデータを入れるためのシートに書き込み
  8. グラフを作成
  9. 全csvファイルでグラフを作成し終わったら、グラフの貼り付け
  10. Excelファイルの保存

読み込むcsvファイル

まずは読み込むcsvファイルを示す。以下のデータを1つずつExcelファイルへ書き込んでグラフ化する。今回も3ファイル。

作成コード全文

次に上の画像のようなExcelファイルを作成するためのコードを示す。割と長いので折りたたみで表示しておく。

以下より各項目を解説する。

csvファイルを読み込む

# 読み込みファイルの共通した接頭辞・接尾辞・拡張子

prefix = 'data'
suffix = ''
extension = '.csv'
# 以下の形式でファイルを読み込む
file_name = f'{prefix}*{suffix}{extension}'

# このpyファイルと同じディレクトリのファイルをソートして抽出
file_list = natsort.natsorted(glob.glob(file_name))
print(file_list)
# ['data0.csv', 'data1.csv', 'data2.csv']

まずはcsvファイルを読み込む作業。ファイルはdata0.csvなどのように共通部分があって、連番で区別する場合は上のコードで読み込める。

prefixで接頭辞、suffixで接尾辞、そしてextensionで拡張子を指定する。連番などはglob*を使って変数のように扱う。

natosortはdata0→data1→data10→data2のように、1→10の順番になるのを防ぐために導入。

出力用のExcelファイル作成

# 出力用のExcelファイル(ワークブック)の作成

wb = openpyxl.Workbook()
# 作成したワークブックを保存
output_name = 'output_csv_summarize.xlsx'
wb.save(output_name)

# 出力用のワークブックの読み込み
wb = openpyxl.load_workbook(output_name)
# 最初に作成されるシートを削除
wb.remove_sheet(wb.get_sheet_by_name('Sheet'))

# index=0: 一番左に新規でシートを追加
wb.create_sheet(index=0, title='data')  # データ格納用
# index=0: 一番左に新規でシートを追加
wb.create_sheet(index=0, title='graph')  # グラフ作成用
# ワークシートを追加シートに変更
ws = wb['data']

出力用のExcelファイルの作成もこれまでと同じように行う。ただ、今回はデータのみを入れるためのシートとグラフを貼り付けるためのシートをのみを使いたいから、既存のシートは削除したい。

そんな時はwb.remove_sheetを使う。openpyxl.Workbook()で作成されたExcelファイルにはシート「Sheet」が存在するため、これを削除。

また、データ格納用とグラフ作成用のシートを作成するためにwb.create_sheetを使用。index=0で一番左にシートを作成、titleでシート名を指定する。

グラフ雛形の作成

# グラフ雛形の作成

# グラフ化するためのScatterChartオブジェクト作成
chart = ScatterChart()
# グラフの高さと幅
chart.height = 15
chart.width = 25

# グラフタイトル
chart.title = 'TITLE'
# 横軸・縦軸ラベル
chart.x_axis.title = 'x軸'
chart.y_axis.title = 'y軸'

ここがこれまでとは異なる点。これまでは読み込んだ各csvもしくはxlsxファイルのデータごとにグラフを作成していた。なので各読み込みファイルのforループ内でグラフを作成していた。

しかし、今回は1つのグラフしか作成しないので初めに設定する必要がある。forループの中で作成してしまうと上書きされてまっさらになってしまうから。

また、ここではグラフの高さ・幅とグラフタイトル、そして横軸・縦軸ラベルも追加しておいた。

読み込んだファイルをExcelに出力

# 読み込みたいファイルで回す
for number, name in enumerate(file_list):
    # csvファイルをpandasで読み込み
    df = pd.read_csv(name)
    # 値の部分だけ取り出し
    values = df.values

    # ヘッダーの作成
    # .columnsでデータフレームからヘッダーを取り出す
    header_x = f"{df.columns[0]}{number}"
    header_y = f"{df.columns[1]}{number}"

    # 書き込む先の列を決める
    # chrでアルファベットに変換
    cell_x = chr(65 + 2 * number)  # 初めはA列、その次はC列
    cell_y = chr(65 + 2 * number + 1)  # 初めはB列、その次はD列
    ws[f'{cell_x}1'] = header_x
    ws[f'{cell_y}1'] = header_y

    # データフレームから取り出した値を行ごとに回す
    for num, rows in enumerate(values, 1):
        x = rows[0]  # 各行の横軸の値
        y = rows[1]  # 各行の縦軸の値

        # 出力用のワークブックに書き込み
        ws[f'{cell_x}{num + 1}'] = x
        ws[f'{cell_y}{num + 1}'] = y

ここも初めのcsvファイルの時と同じようにpandasのデータフレームでデータを読み込み、それを出力用のExcelファイルへと書き込む

ヘッダーはvaluesforの外で書き出し、その他の値はforの中で書く。

グラフの追加

    # グラフの作成
    # 最大の行数 = 書き込む最後の行番号
    max_row = len(values)
    # xの範囲を設定
    x_values = Reference(
        ws,  # ワークシート
        min_col=2 * number + 1,  # 初めの列番号(1ファイルごとにずらす)
        min_row=2,  # 初めの行番号(ヘッダーを除くので2スタート)
        max_row=max_row  # 最後の行番号
    )
    # yの範囲を設定
    values = Reference(
        ws,
        min_col=2 * number + 1 + 1,
        min_row=2,
        max_row=max_row
    )

    # グラフの追加
    series = Series(values, x_values, title=header_y)
    # プロットにマーカーを追加しマーカーサイズを変更
    series.marker.symbol = 'circle'
    series.marker.size = 10
    # グラフを追加
    chart.series.append(series)

グラフの追加が今回のミソ。ループ中で新たにグラフの雛形は作成せず、あくまでもプロットの追加のみを行う。

こうすることで1つのグラフに複数のプロットができるようになる。

なお、今回はプロットにマーカーを追加し、マーカーのサイズを変更しておいた。デフォルトだとマーカーなしでマーカーサイズが小さかったから。

グラフの貼り付けと保存

# ワークシートを追加シートに変更
ws = wb['graph']
# 作成したグラフを追加したシートのB列に追記
ws.add_chart(chart, 'B2')

# 保存
wb.save(output_name)

最後に作成したグラフを貼り付ける。この時、ワークシートである変数wsはデータ格納用のシート「data」になっているので、ws = wb['graph']でグラフ貼り付け用のシート「graph」に変更しないといけない。

変更後、ws.add_chartで出力用のExcelファイルにグラフを貼り付け、wb.saveでグラフを保存したら完成。できるグラフが以下。ちゃんと2シートになっているはず。

面倒なことはプログラミングにお任せ

ということで、今回はPythonのopenpyxlを使って、複数のcsvファイルもしくはxlsxファイルのデータを1つのExcelファイルへと書き出し、さらにはグラフまで作成する方法について解説した。

今回は3ファイルだけだったから正直、手作業でもそこまで苦労はしないが、これが100単位になると手作業だとツラい。

そんな時のこそプログラミングでお任せしてしまえば、余った時間を他に回すことができる。効率的。今後もこのような便利なコードを解説していく。

関連記事

【python&初級】のlistとかforとかifとかまとめ

続きを見る

【python&csv読み込み】pythonを使ってcsvを読み込み

続きを見る

【python&~】数値にチルダ(~)をつけると値が+1されて負の数になる(ビット反転)

続きを見る

【python&表出力】tabulateモジュールで出力を表形式にする

続きを見る

【pd&MultiIndex】pandasで複数インデックスの設定と書き読み

続きを見る

【pd&MultiColumns】pandasで複数ヘッダーの設定と書き読み

続きを見る

【python&フィッティング】polyfitとcurve_fitでfitting

続きを見る

【plotly&ボタン】グラフに複数種のボタンを追加

続きを見る

【python&Excel】pandasでエクセルファイルを読み込み・書き出し

続きを見る

【文字入力&グラフに反映】inputとtkinterでグラフに任意の文字を反映

続きを見る

関連コンテンツ

スポンサーリンク

Amazonのお買い物で損したない人へ

1回のチャージ金額通常会員プライム会員
¥90,000〜2.0%2.5%
¥40,000〜1.5%2.0%
¥20,000〜1.0%1.5%
¥5,000〜0.5%1.0%

Amazonギフト券にチャージすることでお得にお買い物できる。通常のAmazon会員なら最大2.0%、プライム会員なら2.5%還元なのでバカにならない。

ゲットしたポイントは通常のAmazonでのお買い物に使えるからお得だ。一度チャージしてしまえば、好きなタイミングでお買いものできる。

なお、有効期限は10年だから安心だ。いつでも気軽にAmazonでお買い物できる。

Amazonチャージはここから出来るで

もっとお得なAmazon Prime会員はこちらから

30日間無料登録

執筆者も便利に使わせてもらってる

スポンサーリンク

  • この記事を書いた人

メガネ

独学でpythonを学び天文学系の大学院を修了。 ガジェット好きでMac×Android使い。色んなスマホやイヤホンを購入したいけどお金がなさすぎて困窮中。 元々、人見知りで根暗だったけど、人生楽しもうと思って良い方向に狂ったために今も人生めちゃくちゃ楽しい。 pythonとガジェットをメインにブログを書いていますので、興味を持たれましたらちょこちょこ訪問してくだされば幸いです🥰。 自己紹介→変わって楽しいの繰り返し

-Python基礎
-, ,