質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
openpyxl

openpyxlは、Excel2007以降のファイル(xlsx/xlsm/xltx/xltm)を読み書きするためのPythonライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

875閲覧

ファイル内のExcelシートに同一処理(書式変更等)を行いたい

sho.sho

総合スコア2

openpyxl

openpyxlは、Excel2007以降のファイル(xlsx/xlsm/xltx/xltm)を読み書きするためのPythonライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/07/06 06:20

最近pythonを勉強し始めた初心者です。見ていただき、ありがとうございます。

openpyxlでファイルに入っている全てのExcelファイルに同一の処理をするための方法を考えているのですが、
一つずつ処理をしていくコードの書き方がわからず困っております。
一つのExcelファイルを同じフォントにしたり、色の調整、枠を引く作業のコードはかけたのですが、最後のファイルの処理の部分がうまくいっておりません。(下のコードはフォント変更のコードを載せています)

一つのファイルに100ほど同じフォントにしたいExcelファイルがあるので、
一括で全てのファイルの書式が変更できるようにしたいと考えております。

お知恵を拝借できると幸いです。
よろしくお願いいたします。

!pip install openpyxl import openpyxl from openpyxl.styles import Font import pandas as pd from glob import glob filepaths = glob('ファイルが保存されている場所') filepath = filepaths[0] #恥ずかしながら、ここの数値を手動で変えて今回は作業していました。 df = pd.read_excel(filepath) #ファイルの読み込み export_file = 'excel000.xlsx' #保存先 df.to_excel(export_file) #Excelへの書き込み #もとのExcelファイルをpythonに読み込んで、修正したExcelに保存する形をとっています。 workbook = openpyxl.load_workbook(export_file) #ワークブックの読み込み worksheet = workbook.worksheets[0] #ワークシートの指定 font = Font(name='メイリオ',size=9) #フォントの変更とフォントサイズの変更 sheet_range =worksheet['A1':'M100'] #変更する範囲 for row in sheet_range: for cell in row: worksheet[cell.coordinate].font = font #それぞれのセルのフォントを変更 workbook.save(export_file) #修正したものを保存

今回は上述のコードのfilepaths[0]の部分の数値とexport_file = 'excel000.xlsx' #保存先の値を変えて、手動で処理を行っていましたが、一括で全てのファイルのフォントを変更したいです。

どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Pythonではfor文で繰り返し処理ができます。

Python

1for filepath in filepaths: 2 print(filepath) 3 export_file = 'export_' + filepath # export_ファイル名.xlsx 4 print(export_file)

連番を振る必要があるなら enumerate() を使えます。

Python

1for idx, filepath in enumerate(filepaths): 2 print(filepath) 3 export_file = filepath.replace(".xlsx", f"_{idx:03}.xlsx") # ファイル名_000.xlsx 4 print(export_file)

書き出し用のフォルダを作っておいてそこに元と同じファイル名で保存する方法もあります。

Python

1for filepath in filepaths: 2 print(filepath) 3 export_file = 'export/' + filepath # exportフォルダに保存(Windowsだと 'export\' かも) 4 print(export_file)

df = pd.read_excel(filepath)df.to_excel(export_file) は不要ではないでしょうか。

Python

1for filepath in filepaths: 2 workbook = openpyxl.load_workbook(filepath) 3 # ... 4 # workbookに対する処理を行う 5 # ... 6 export_file = 'export_' + filepath 7 workbook.save(export_file)

追記:glob のパス指定で絶対パスを使用した場合

glob のパス指定で、'C:\Users\Tanaka\Documents\checksheet*.xlsx' といった 'C:' から始まるパスを指定した場合は、絶対パスで指定したことになります(これに対して、相対パスで指定する方法もありますが、ここでは詳細は省きます)。

絶対パスを使用した場合は、取得されるファイルのパスも絶対パスになりますので、このパスを加工する場合は、ファイル名とディレクトリパスに分割してから処理するのがやりやすいです。

以下は簡単なサンプルコードです。

Python

1from glob import glob 2import os 3 4filepaths = glob('C:\Users\Tanaka\Documents\checksheet\*.xlsx') 5for filepath in filepaths: 6        # 取得されるファイルのパスは絶対パス 7        print(filepath) # => C:\Users\Tanaka\Documents\checksheet\xxxx.xlsx 8        # 絶対パスからファイル名のみを取り出す 9 filename = os.path.basename(filepath) 10 print(filename) # => xxxx.xlsx 11        # 絶対パスからファイル名を除いたディレクトリパスの部分だけを取り出す 12 dirname = os.path.dirname(filepath) 13 print(dirname) # => C:\Users\Tanaka\Documents\checksheet 14        # ファイル名とディレクトリパスを結合して再度ファイルの絶対パスを作成する 15 new_path = os.path.join(dirname, filename) 16 print(new_path) # => C:\Users\Tanaka\Documents\checksheet\xxxx.xlsx 17 print() 18 19 # 次のようにしてファイル名とディレクトリパスを一度に取得してもよい 20 dirname, filename = os.path.split(filepath)

以下簡単に説明します。

ファイル名とディレクトリパスに分割するには
os.path.basenameos.path.dirname を使います。もしくは os.path.split を使います。

Python

1filename = os.path.basename(filepath) 2dirname = os.path.dirname(filepath) 3 4# もしくは 5dirname, filename = os.path.split(filepath)

分割した後に、取得したファイル名とディレクトリパスを、書き出すファイルはどんなファイル名で、どこのディレクトリに保存したいかに合わせて加工します。
同じファイル名やディレクトリパスでよければそのままでもいいです。

加工し終わったら、加工済みのファイル名とディレクトリパスを os.path.join を使って結合して、最終的な書き出し用パスを得ます。

Python

1new_path = os.path.join(dirname, filename)

以下に具体的な例をいくつか挙げます。

書き出しファイル名に共通の接頭辞(ここでは'export_')をつけて同じフォルダに保存する場合:

Python

1for filepath in filepaths: 2 dirname, filename = os.path.split(filepath) 3 new_filename = 'export_' + filename # ファイル名を加工 4 export_filepath = os.path.join(dirname, new_filename) 5 print(export_filepath)

書き出しファイル名に連番を振って同じフォルダに保存する場合:

Python

1for idx, filepath in enumerate(filepaths): 2 dirname, filename = os.path.split(filepath) 3 new_filename = filename.replace(".xlsx", f"_{idx:03}.xlsx") # ファイル名を加工 4 export_filepath = os.path.join(dirname, new_filename) 5 print(export_filepath)

書き出し用のフォルダ(ここでは 'export')を作ってそこに元と同じファイル名で保存する場合:

Python

1# 書き出し用のフォルダを元のフォルダの中に作った場合 2for filepath in filepaths: 3 dirname, filename = os.path.split(filepath) 4 new_dirname = os.path.join(dirname, 'export') # 元のフォルダ + exportフォルダ 5 export_filepath = os.path.join(new_dirname, filename) 6 print(export_filepath) 7 8# 書き出し用のフォルダを元のフォルダと同じ階層に作った場合 9for filepath in filepaths: 10 dirname, filename = os.path.split(filepath) 11 upper_dirname = os.path.dirname(dirname) # 元のフォルダのひとつ上の階層のパスを取得 12 new_dirname = os.path.join(upper_dirname, 'export') # ひとつ上の階層 + exportフォルダ 13 export_filepath = os.path.join(new_dirname, filename) 14 print(export_filepath)

なお、raw文字列(r'xxx')を使うと、その文字列内のエスケープ ('') は、エスケープとしての特別な機能を失ってただの文字列になります。そのため下記のコードは、

Python

1filepaths = glob('C:\Users\Tanaka\Documents\checksheet\*.xlsx')

raw文字列を使って次のように書くこともできます。

Python

1filepaths = glob(r'C:\Users\Tanaka\Documents\checksheet*.xlsx')

os.getcwd() はカレントディレクトリを確認するためのコードです。
相対パスを使用する場合は、カレントディレクトリを把握しておくことが重要になりますが、今回質問者さんは絶対パスを使用されていましたので、説明は省略させていただきます。

投稿2021/07/06 21:44

編集2021/07/13 04:15
etherbeg

総合スコア1195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sho.sho

2021/07/08 04:02

ご回答ありがとうございます。 また、複数のご提案までいただき、大変感謝しております。 早速、実効させていただきましたが、最後の保存部分がうまくいいっておりません。 (書き出し用のフォルダに保存するタイプを実施) 1点ご質問なのですが、 export_file = 'export/' + filepath  の 'export/' の部分は保存ファオルダの場所(C\Usersなどからはじまるもの)を記すという認識でよろしいでしょうか。 OSError: [Errno 22] Invalid argument:'C:\Users\~ というエラーが出てしまいます。 教えていただけると幸いです。 どうぞよろしくお願いいたします。
etherbeg

2021/07/08 14:08 編集

コードの filepaths = glob('ファイルが保存されている場所') の「ファイルが保存されている場所」の箇所に実際に入力されている文字列を教えてください。 for filepath in filepaths: print(filepath) の出力結果を途中まで(3行程度)でいいので教えてください。 「ファイルが保存されている場所」をフルパス (C:\Users...) で教えてください。ユーザ名などは伏せ字でいいです。 ファイルを保存したいフォルダをフルパス (C:\Users...) で教えてください。ユーザ名などは伏せ字でいいです。 以上よろしくお願いします。
etherbeg

2021/07/08 22:17

すみません、もうひとつ追加で。 import os print('cwd: ', os.getcwd()) の2行をコードのどこでもいいので追加していただいて、表示される「cwd: 〜」という文字列の内容を教えてください。ユーザ名などは伏せ字でいいです。
sho.sho

2021/07/12 02:48

ご回答いただき、ありがとうございます。 早速、ご確認いただたいた点を記載させていただきます。 >コードの >filepaths = glob('ファイルが保存されている場所') >の「ファイルが保存されている場所」の箇所に実際に入力されている文字列を教えてください。 filepaths = glob('C:\Users\Tanaka\Documents\checksheet\*.xlsx') #ユーザー名はTanakaではありませんが、このような姓をアルファベットで表記したものがはいっています。 >for filepath in filepaths: >print(filepath) >の出力結果を途中まで(3行程度)でいいので教えてください。 C:\Users\Tanaka\Documents\checksheet\ファイル名(日本語).xlsx C:\Users\Tanaka\Documents\checksheet\ファイル名(日本語).xlsx C:\Users\Tanaka\Documents\checksheet_outC:\Users\Tanaka\Documents\checksheet\ファイル名(日本語).xlsx ※ファイル名は、取引先等が含まれるので伏字にさせていただいています。すべて、ひらがなと漢字の組み合わせの名前をつけて、記号は使用していません。  出力されるものはこの3行のみで、そのすぐ下に背景が赤くなったエラーメッセージ群がでてきています。 >import os >print('cwd: ', os.getcwd()) >の2行をコードのどこでもいいので追加していただいて、表示される「cwd: 〜」という文字列の内容を >教えてください。ユーザ名などは伏せ字でいいです。 cwd: C:\Users\Tanaka\Training\フォルダー名 ※JupyterLabを使って処理をしています。フォルダー名は、JupyterLab内に作成しているファルダ―名です。アルファベット表記になり、日本語(ひらがな・漢字・カタカナ)は使用していません。 お時間いただき、ご回答くださいまして、本当にありがとうございます。 どうぞよろしくお願いいたします。
etherbeg

2021/07/12 07:44

ありがとうございます。 普段自分が相対パスを多用しているために、質問者さんも相対パスを使用しているものと勝手に思い込んで回答してしまいました。そのため不完全な回答になってしまっていました。申し訳ありません。 回答に追記させていただきました。
sho.sho

2021/07/14 09:49

ご丁寧なご回答ありがとうございました。 おかげさまで、目的としていたプログラムを作成することができました。 また、相対パスと絶対パスについても教えていただきありがとうございました。 しっかり理解できていないところでしたので、改めて勉強しなおしたいと思います。 貴重な経験となりました。 また、いろいろとご質問させていた際は、ご教授いただけますと幸いです。 どうぞよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問