Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
26
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

openpyxlで罫線を引く

Introduction

ここに以下のようなエクセルデータファイル(test.xlsx)があります。

スクリーンショット 2019-03-13 15.27.15.png

あるときこのエクセルに罫線(ここでは黒い枠線)をつけてほしいと依頼がありました。
エクセルファイルやシートの数が一つであれば手作業で罫線をつけてもよいですが、今後大量のエクセルファイルに同様の作業をしなければならない可能性が出てくるかもしれません。そうなった時のために、この作業を自動化しておけると便利ですね。

スクリプトとその実行結果

エクセルを読み込み、値の入っている範囲に罫線を引くスクリプトを以下に示します。

sheet_border.py

'''
    sheet_border.py
    purpose: read xlsx and set border automatically
'''

import openpyxl as xl
from openpyxl.styles.borders import Border, Side


# set input file name
inputfile = 'test.xlsx'

side = Side(style='thin', color='000000')

# set border (black thin line)
border = Border(top=side, bottom=side, left=side, right=side)

# read tmp xlsx
wb1 = xl.load_workbook(filename=inputfile)
ws1 = wb1.worksheets[0]

# write in sheet
for row in ws1:
    for cell in row:
        ws1[cell.coordinate].border = border

# save xlsx file
wb1.save(inputfile)

結果は以下のようになります。

スクリーンショット 2019-03-13 15.31.05.png

スクリプト詳細

from openpyxl.styles.borders import Border, Side

from openpyxl.styles.borders import Border, Side

とすることで、Border関数とSide関数を直接呼び出すことができます。このSide関数は、その名の通りSideオブジェクトを返す関数です。Border関数で色や線の太さを指定するために使うため、同時にインポートしています。

Side関数

side = Side(style='thin', color='000000')

この一行でside変数にSideオブジェクトを代入しています。ここでは、線の色は黒、細い罫線を指定しています。引数styleには'thin'の他にも‘dashDot’, ‘dashDotDot’, ‘double’, ‘hair’, ‘dotted’, ‘mediumDashDotDot’, ‘dashed’, ‘mediumDashed’, ‘slantDashDot’, ‘thick’, ‘thin’, ‘medium’, ‘mediumDashDot’が指定可能です。
試しに以下のように変更して実行してみます。

side = Side(style='thick', color='FF0000')

すると結果は以下のように、太い赤線の罫線が引かれたものになります。

スクリーンショット 2019-03-13 15.52.14.png

Border関数

border = Border(top=side, bottom=side, left=side, right=side)

この一行でborder変数にBorderオブジェクトを代入しています。ここでセルのtop(上側), bottom(下側), left(左側), right(右側)にどのような罫線を引くかを指定しています。ここでは全ての辺に同じsideを指定しています。

罫線を書き込む

# write in sheet
for row in ws1:
    for cell in row:
        ws1[cell.coordinate].border = border

この部分で、先にBorder関数で指定した罫線書式を各セルの罫線オブジェクトに代入しています。

応用: 値が入っていない部分には枠をつけない

test.xlsxが以下のようなものだったとしましょう。

スクリーンショット 2019-03-13 16.01.15.png

これで上に示したsheet_border.pyを実行すると、結果は以下のようになります。

スクリーンショット 2019-03-13 16.03.38.png

上図から分かるように、11行目やE列目のように全く値の入っていない部分にもまたがって罫線もとい枠線を引くことが適用されています。
値のない部分には枠線をつけたくない場合は、以下のようにsheet_border.pyを書き換えます。

# write in sheet
for row in ws1:
    for cell in row:
        if ws1[cell.coordinate].value:
            ws1[cell.coordinate].border = border

上述のようにif文を追加することにより、セルの値がNoneでないときのみ枠線を書き込むようにすることができます。この結果は以下のようになります。

スクリーンショット 2019-03-13 16.07.49.png

これで大量のエクセルファイルがあっても、一つ一つに手作業で罫線を入れていくという面倒な作業からは解放されそうですね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
26
Help us understand the problem. What are the problem?