LoginSignup
3
8

More than 3 years have passed since last update.

PythonでExcelを操作する

Last updated at Posted at 2021-01-27

はじめに

とりあえず急ぎで作成したため、後でゆっくり整理する...予定

参考サイト

環境構築関連

◆Seleniumをオフラインで動かす
 https://qiita.com/wakasama_pcmaster/items/73c8e71fde81ed6336bb
  ※Pythonインストール関連はこちらに記載していたので...

◆# openpyxl と xlwings の比較
 https://qiita.com/m5knt/items/ab56f1d0a783f3422ee3
◆ExcelにPythonが搭載?その後 - xlwings を使おう
 https://qiita.com/yniji/items/b38bc312e860027108ac

◆PythonでExcelマクロ実行!VBAを起動する方法
 https://fastclassinfo.com/entry/run_excelvba_from_python/#xlwingsPythonExcelVBA
◆Python×Excel自動化できること28!読み込み書き込みグラフ作成の事例紹介
 https://fastclassinfo.com/entry/python_excel_operation/
◆マスターしよう!PythonでのCSVファイル操作方法を徹底解説!
 https://www.tech-teacher.jp/blog/python-csv/
◆xlwings · PyPI
 https://pypi.org/project/xlwings/#files
  ※xlwings-0.21.4.tar.gz
◆pywin32 · PyPI
 https://pypi.org/project/pywin32/#files
  ※pywin32-300-cp37-cp37m-win_amd64.whl
 
◆Python API — xlwings dev ドキュメント
 https://docs.xlwings.org/ja/latest/api.html
◆xlwings入門
 https://jimaru.blog/programming/python/xlwings/
  ※デバッグのやり方書いてある...重要!!

◆意外と知らない?pipコマンド
 https://qiita.com/tmurakami1234/items/b407dc4cc558564882bf

TODO

Memo

  • Pythonの文字コード:UTF-8

コードサンプル

事前準備&環境構築

enviroment.py
# バージョン確認
> python --version
Python 3.7.1

# インストール パッケージ確認
> pip list

# xlwingsダウンロード
> pip download -d src --no-binary :all: xlwings
#  ※一部はwhlしかないので、実際は下記で取得
> pip download -d package xlwings

# xlwingsインストール
> pip install --no-index --find-links=package xlwings

Excel操作

excel2.py
import csv
import datetime as dt
import os
import time
import xlwings as xw


def isDictionary(dicRange, cellPosition):
    for column in dicRange.columns:
        cells = column[0].value.split(';')
        if cellPosition in cells:
            return True


def createDictionary(dicRange, cellPosition):
    cindex = -1
    dic = {}
    for column in dicRange.columns:
        cindex = cindex + 1
        cells = column[0].value.split(';')
        if cellPosition in cells:
            # print(dicRange.value[cindex])
            # print(column.value)
            rindex = -1
            for r in column:
                rindex = rindex + 1
                # print(dicRange.value[rindex][cindex],
                #      dicRange.value[rindex][cindex+1])
                dic1 = {dicRange.value[rindex][cindex]: dicRange.value[rindex][cindex+1]}
                dic.update(dic1)
                # print(dic)
    return dic


def searchDictionary(dicRange, cellPosition, key):

    # 指定セル情報の値検索
    # cindex = -1
    rindex = -1
    keyFlag = False
    for column in dicRange.columns:
        # if isDictionary(dicRange, cellPosition):
        #     keyFlag = key in column.value
        #     if keyFlag:
        #         rindex = column.value.index(key)
        #         #print(key, rindex)
        # else:
        #     if keyFlag:
        #         return column[rindex].value
        # cindex = cindex + 1
        cells = column[0].value.split(';')
        if cellPosition in cells:
            keyFlag = key in column.value
            if keyFlag:
                rindex = column.value.index(key)
                # print(key, rindex)
            # else:
            #     continue
            # for r in column:
            #     rindex = rindex + 1
            #     if key == r.value:
            #         keyFlag = True
            #         break
            #     else:
            #         continue
        else:
            # if keyFlag == True:
            if keyFlag:
                # print(cindex, rindex)
                # print(column[cindex].value)
                return column[rindex].value
            # else:
            #     continue


start2 = time.time()

# メイン処理
try:
    # 新規Excelインスタンスでブックを開く
    app = xw.App(visible=False)
    wb = app.books.open('テスト_InputData_TYPE.xlsx')

    # シートを得る
    wss = wb.sheets
    ws1 = wss['InputCsvData']
    # ws.activate()

    # 処理開始
    start = time.time()

    # Dictionary情報取得
    ws2 = wss['Dictionary']
    # ws2.activate()
    u = ws2.api.UsedRange
    r = u.Row + u.Rows.Count - 1
    c = u.Column + u.Columns.Count - 1
    dicRange = ws2.range((1, 1), (r, c))

    # InputCsvData情報取得
    ws1.activate()
    u = ws1.api.UsedRange
    r = u.Row + u.Rows.Count - 1
    c = u.Column + u.Columns.Count - 1
    csvRange = ws1.range((1, 1), (r, c))

    for column in csvRange.columns:
        cellPosition = column[1].value

        # if isDictionary(dicRange, cellPosition):
        #     for r in column:
        #         r.value = searchDictionary(dicRange, cellPosition, r.value)

        dictionary = createDictionary(dicRange, cellPosition)
        if(len(dictionary) > 0):
            index = 0
            for r in column:
                if(index < 2):
                    index = index + 1
                else:
                    # if(r.value == 'R11C3'):
                    #    print(column.value)
                    r.value = dictionary[r.value]

        # print(dicRange.value[0][0])

    # 列毎の範囲操作
    # svalue = searchDictionary(dicRange, 'R10C4', '休日')
    # print(svalue)
    # svalue = searchDictionary(dicRange, 'R11C5', '木曜日')
    # print(svalue)
    # svalue = searchDictionary(dicRange, 'R20C4', '管理職')
    # print(svalue)
    # index = 0
    # for column in dicRange.columns:
    #     if index % 2 == 0:
    #         print('セル情報')
    #         key1 = column[index].value
    #         print(key1)
    #         dkey = column.value
    #     else:
    #         print('不要')
    #         dvalue = column.value
    #     index = index + 1
    #     # for r in column:
    #     print(column.value)

    # 処理終了
    stop = time.time()
    print(stop-start)

    # 使用範囲の値(list)を取得して出力
    # print(rng.value)

    # 行毎の範囲を得て値を出力 (値のみなら rng.value が速い)
    # for row in rng.rows:
    #    print([c.value for c in row])

    # 列毎の範囲を得て値を出力
    # for column in rng.columns:
    #    #print([r.value for r in column])
    #    for r in column:
    #        print(r.value)

    saveFile = r"D:\Python\Excel\OutputData.csv"
    # ファイル存在確認
    isFileExist = os.path.isfile(saveFile)
    if isFileExist:
        os.remove(saveFile)
    # else:
    #     pass  # パスが存在しないかファイルではない

    # csvファイルとして保存
    # ◆XlFileFormat 列挙体 (Excel)
    #  https://docs.microsoft.com/ja-jp/office/vba/api/excel.xlfileformat
    wb.api.SaveAs(saveFile, 6)

finally:
    # ブックを閉じる
    wb.close()
    # Excelインスタンスを閉じる
    app.quit()


# 処理終了
stop2 = time.time()
print(stop2-start2)

excel.py
import csv
import datetime as dt
import xlwings as xw

# CSVファイル読込
with open('data.csv', encoding="utf_8") as file:
    reader = csv.reader(file)
    # ラベルデータをスキップする
    header = next(reader)

    for row in reader:
        print(row)


# 新規Excelインスタンスでブックを開く
app = xw.App(visible=False)
wb = app.books.open('work.xlsx')

# シートを得る
wss = wb.sheets
ws = wss['202101']

# データ表示
print(ws.range('A5').value)
dt1 = ws.range('A5').value
strdt1 = dt1.strftime('%Y/%m/%d(%a)')
print(strdt1)

print(ws.range('B5').value)
print(ws.range('C5').value)


def day_to_time(D):
    # hh:mm:ss
    #    T = str(dt.timedelta(days=D))
    #    return T
    # hh:mm
    return ':'.join(str(dt.timedelta(days=D)).split(':')[:2])


d = day_to_time(ws.range('D5').value)
print(d)
# 数式
print(ws.range('E5').formula)
# 数式の結果
print(day_to_time(ws.range('E5').value))
dt3 = dt.datetime.strptime(
    str(dt.timedelta(days=ws.range('E5').value)), "%H:%M:%S")
print(dt3)
print(dt3.strftime('%H:%M'))

# 使用範囲
# u = ws.api.UsedRange
# r = u.Row + u.Rows.Count - 1
# c = u.Column + u.Columns.Count - 1
# rng = ws.range((1, 1), (r, c))

# 使用範囲の値(list)を取得して出力
# print(rng.value)

# 行毎の範囲を得て値を出力 (値のみなら rng.value が速い)
# for row in rng.rows:
#    print([c.value for c in row])

# テーブル内容の範囲
# rng = ws['テーブル']
# テーブルタイトルを取得して出力
# print(rng.rows[0].offset(-1, 0).value)
# テーブル内容を取得して出力
# print(rng.value)

# マクロVBAを呼び出して実行
# App = xw.App()
# wb = App.books.open(filename)
# macro=wb.macro('keisan')
# macro()

# エクセルファイルを保存
# newfilename = 'Macro_' + filename
# wb.save(newfilename)

# ブックを閉じる
wb.close()

# Excelインスタンスを閉じる
app.quit()
3
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
8