MS-Office WordをPythonで操作する「python-docx」ライブラリを解説します。
これまでに、python-docxを使って、「文章を作成する」、「画像や表を挿入する」そして「セクションによるページ管理をする」方法について取り上げてきました。
関連記事へのリンクはこちらになります。
さて、連載3回目となる今回は「ドキュメントにスタイルを適用する」また「ユーザーが独自スタイルを定義する」方法を解説していきます。
スタイルを活用するメリットには、
- ドキュメント全体に統一感をもたせ、見栄えを整えることができる。
- 同じスタイルを適用した複数の文章に対して、修正内容を一度に反映することができる。
- 紛らわしい書式の設定を一度スタイルとして登録すれば、以降ドキュメント内で再利用できる。(コード減らし、よりシンプルにできる)
といったものがあります。
WordのUIでは以下のメニュー項目でスタイルの設定ができます。
「python-docxライブラリ」は、これらの操作に関する機能を提供しています。
これまでの解説の中でも、文章やテーブルを管理する、各オブジェクト(Paragraph, Ran, Table)に対し 引数:style や sytleプロパティ(属性) を使ってデフォルトスタイル(組込みスタイル)を設定してきました。
python-docxライブライには Styleオブジェクト というスタイルを管理するオブジェクトが用意されています。Wordに予め定義されたスタイルを適用することは勿論のこと、ユーザーが独自に書式をカスタマイズしてスタイルとして登録することもできます。
今回の記事は、この「スタイルの活用方法」について、より深く解説していきます。
先に要点をまとめておくと、本記事では次のようなことについて触れています。
本サイトでの紹介例は一例です。また、関数などの省略可能なオプション引数などについては割愛していますので、詳細や不明点などは必要に応じて公式サイトなどを参照してください。
<公式サイト>https://python-docx.readthedocs.io/en/latest/
それでは、次節からは具体的な Styleオブジェクト の取り扱いについて解説していきます。
1. スタイル(Styleオブジェクト)の概要
スタイルを「適用する」または「定義する」などの操作は Styleオブジェクト で管理されます。
本節では、まずStyleオブジェクト種類とその階層構造について触れた上で、具体的なスタイルの適用手順について再度確認します。
1.1 Styleオブジェクトの種別とその構成
ドキュメントファイル内で定義されている、すべてのスタイル書式は、
Documentオブジェクト配下の、Stylesオブジェクト (末尾にsが付加されます)に配置されています。
Stylesオブジェクトは、Styleオブジェクトを要素とするイテラブルなオブジェクト(コレクション)です。(図2を参照)
Wordドキュメントの構成レイヤー・要素である段落・単語(文字)・テーブル(表)には、それぞれ固有スタイルがあり明確に区分されています。
段落レイヤーは _ParagraphStyleオブジェクト、単語(文字)レイヤーは _CharacterStyleオブジェクトで、 またテーブル要素は _TableStyleオブジェクト とそれぞれ個別オブジェクトとなります。
また、これらのオブジェクトは全て BaseStyleオブジェクト から継承するかたちで作られていますが、あまり意識する必要はありません。(図3)
以上が、機能別のスタイル分類になります。
さらに、Styleオブジェクトには「Wordにあらかじめ組み込まれ直ぐに使えるもの」と「ユーザー自身が独自に定義(カスタム)するもの」の2つに大別されます。
それぞれ、「Built-in styles」と「Custom styles」と公式サイトでは区別していますので、本記事もそれに合わせています。
段落、単語(文字)、テーブル、どの機能別スタイルにおいてもユーザー独自スタイル(Custom styles)を定義することができます。
「Built-in styles」についてはこの後の第2節で、「Custom styles」によるスタイル書式の定義については第3節で詳しく解説します。
1.2 スタイル(Styleオブジェクト)を適用する
スタイルを導入するメリットと概要が分かったところで、今度はスタイルを実際に適用する手順について解説します。スタイル(Styleオブジェクト)を適用する方法には次の2通りがあります。
- 段落(単語)を追加する際に、メソッドの「引数style」にて指定する。
- 段落(単語)オブジェクトの「styleプロパティ」で設定する
【1. メソッドの「引数style」でスタイルを指定】
段落や文字、テーブルなどのオブジェクトを追加する add_paragraph()メソッド , add_table()メソッド などには、オプショナルな 引数:style があります。
引数styleに「‘Meiryo UI’」などのようにスタイル名(文字列)で指定することで、オブジェクトの追加とともに、そのスタイルが適用されます。
いずれも、引数styleは省略可能で、省略した場合はDefaultスタイルが適用されます。
【2. 対象オブジェクトのstyleプロパティで設定】
段落・文字・テーブルの対象オブジェクトが提供する styleプロパティ を使っても設定することができます。また、現在の適用中のスタイル名も取得できます。
書式は次のとおりです、属性に設定する形式は「‘Meiryo UI’」などのようにスタイル名(文字列)、もしくはStylesコレクション[‘Meiryo UI’]のようにStyleオブジェクトを指定します。
【対象オブジェクト】 | 【プロパティ】 | 【設定・取得】 |
---|---|---|
段落(Paragraphオブジェクト) | style | 段落のスタイルの取得と設定 スタイル名、Styleオブジェクトで設定 |
文字(Runオブジェクト) | style | 文字のスタイルの取得と設定 スタイル名、Styleオブジェクトで設定 |
表(Tableオブジェクト) | style | 表のスタイルの取得と設定 スタイル名、Styleオブジェクトで設定 |
【SAMPLE.1】
スタイルの適用例を実際のサンプルコードで確認してみましょう。
段落(Paragraph)と文字(Run)を追加しながら、メソッドの引数指定、またはプロパティによるスタイル書式の適用例を確認頂けます。(List1)
※なお、コードのコメントにある[A1][A2]・・・[B3]などの表記は、この後の実行結果と対応しています。
from docx import Document
doc = Document() # Documentオブジェクトの取得
# (A)--------------------------------------------------------------------------------
# メソッドの引数styleによるスタイルの設定
# 段落:スタイル名(Title)による指定・・・[A1]
pg1 = doc.add_paragraph('メソッド引数style=名前による設定', style='Title')
print(pg1.style.name) # >>Title
# 文字:スタイル名(Subtitle Char)による指定・・・[A2]
run1 = pg1.add_run('add_run() 引数style=名前による設定', style='Subtitle Char')
print(run1.style.name) # >>Subtitle Char
#-----------------------------
# 段落:Styleオブジェクトによる指定・・・[A3]
pg2 = doc.add_paragraph('add_paragraph() 引数style=オブジェクトによる設定', style=doc.styles['Intense Quote'])
print(pg2.style.name) # >>Intense Quote
# (B)--------------------------------------------------------------------------------
# プロパティによるスタイルの設定と取得
# 段落: デフォルトスタイルの確認・・・[B1]
pg3 = doc.add_paragraph('段落:プロパティによるスタイルの設定')
print(pg3.style.name) # >>Normal
# 段落: スタイル名(Caption)による設定と取得
pg3.style = 'Caption' # styleプロパティでスタイル名'Caption’に設定
print(pg3.style.name) # >>Caption
#-----------------------------
# 文字:デフォルトスタイルの確認・・・[B2]
run3 = pg3.add_run('文字:プロパティによるスタイルの設定')
print(run3.style.name) # >>Default Paragraph Font
# 文字: スタイル名(Strong)による設定と取得
run3.style = 'Intense Emphasis' # styleプロパティでスタイル名'Intense Emphasis’に設定
print(run3.style.name) # >>Intense Emphasis
#-----------------------------
# 段落: Styleオブジェクトによる設定・・・[B3]
pg4 = doc.add_paragraph('段落:プロパティによるスタイルの設定(オブジェクト)')
pg4.style = doc.styles['Body Text'] # styleプロパティでオブジェクト'Body Text'を設定
print(pg4.style.name) # >>Body Text
doc.save('Apply_Style_List1JP.docx')
それでは、ポイントを解説します。
各ステップで name属性 でスタイル名を確認していますが、設定したとおりに反映されていることが確認できます。※Styleオブジェクト配下の主なメソッド・プロパティについては第3節で詳しく解説します。
<List1>の実行結果は次のようになりました(以下からダウンロードできます)。(図6)
指定したとおりのスタイル書式が適用されています。
[A1][A2]・・・[B3]などの表記はコードのコメントに対応しています。
A1: Title, A2: Subtitle Char, A3: Intense Wuote
B1: Normal → Caption, B2:Default Paragraph Font → Insense Emphasis/
B3: Body Text
以上、スタイルの概要と適用方法の解説をしてきました。これまでに「Built-in styles」(組込みスタイル)例がいくつか登場しましたが、次節ではWord(2016)の組込みスタイルをすべてを紹介します。
2. 組込みスタイル(Built-in Styles)のデザインレシピ
本節では組込みスタイル(Built-in Styles)のデザインを全て紹介します。
デザインレシピとしてお役立てください
Wordには、あらかじめ200程度のテンプレートとなるスタイルが組み込まれています。
前節のように、「スタイル名」をメソッドやプロパティに指定するだけで適用できるのはこの定義済みのスタイルがWordに組み込まれているからです。
スタイル名は、すべて英語による世界統一表記で、WordprocessingMLファイルに定義されています。python-docxライブラリもこれに準拠しています。
日本語に対応したWordUIに表示される日本語のスタイル名では指定できません。
世界統一表記と日本語のスタイル名の対応関係は、次のサイトからマクロをダウンロード・実行して頂くことで調べることができます。
参照先:DocTools Word Macros&Tips
https://www.thedoctools.com/word-macros-tips/word-macros/create-style-name-list/
なお、筆者の動作確認環境は「Microsoft Office Personal 2016」となります。環境の違いによっては見た目が異なる可能性がありますのであらかじめご了承ください。
2.1 段落スタイル(_ParagraphStyle)
段落の組込みスタイル( _ParagraphStyleオブジェクト )全36タイプの表示例を示しています。
スタイル指定を省略した場合は、デフォルトの ‘Normal’ が適用されます。また、段落スタイルには「Heading系」「BodyText系」「List系」などの系統があります。
Paragraph styles in default template
https://python-docx.readthedocs.io/en/latest/user/styles-understanding.html#paragraph-styles-in-default-template
2.2 文字スタイル(_CharacterStyle)
文字の組込みスタイル( _CharacterStyleオブジェクト )は全27タイプの表示例を示しています。
スタイル指定を省略した場合は、デフォルトの ‘DefaultParagraphFont’が適用されます。また、文字スタイルには「Heading系」「BodyText系」「Emphasis系」などの系統があります。
Character styles in default template
https://python-docx.readthedocs.io/en/latest/user/styles-understanding.html#character-styles-in-default-template
2.3 テーブルスタイル(_TableStyle)
テーブルの組込みスタイル( _TableStyleオブジェクト )は全100タイプと数多くあります。同一タイプで色違いの指定のものは割愛しています。スタイル指定を省略した場合は、デフォルトの ‘Normal Table’が適用されます。
Table styles in default template
https://python-docx.readthedocs.io/en/latest/user/styles-understanding.html#table-Paragraph styles in default template
以上、組込みスタイル(Built-in Styles)の紹介でした。スタイルは既定のテンプレートを利用だけではなく、ユーザーにて自由に定義できるのでした。次節からはユーザー定義スタイル(Customstyles)について解説していきます。
3. ユーザ定義スタイル(Custom styles)について
スタイルは既定のBuilt-in Styleの中から選択するもの以外にも、ユーザが独自に定義・カスタマイズし追加することも可能です。本節では、ユーザ定義スタイル( Custom styles )について解説します。
また、Styleオブジェクトを定義する上で必要となる、メソッドやプロパティの使い方ついても本節でまとめています。
3.1 ユーザ定義スタイルの追加と定義
スタイルを追加定義するには、まずStyleオブジェクトのコレクションである Stylesオブジェクト を取得した上で、その配下の add_styles()メソッド を次の書式のように実行します。
<1.1節>で解説しようにStyleオブジェクトは、ドキュメントの個別要素(段落、文字、テーブル)ごとに管理されています。
よって、add_style()メソッドでStyleオブジェクトを追加する際には、引数:style_type にどの個別要素に対応するスタイルなのかを明確に示す必要があります。WD_STYLE_TYPEクラス のEnum定義を渡します。(図15)
さて、Styleオブジェクトが追加できましたが、この段階では既定の“デフォルト”スタイルが継承されています。ユーザーがカスタマイズするには、Styleオブジェクト配下にあるメソッドやプロパティ(属性)を使うことになります。
まずは、段落・文・テーブルのStyleオブジェクトに共通する主なメソッド/プロパティを紹介します。
base_style属性 はテンプレートとなるスタイルを指定できます。例えば、‘Body Text 2’を指定すると、‘Body Text 2’のスタイル書式を引き継いだうえで、ユーザーが変更したい設定を上書き(オバーライド)します。特に指定しなければ、Defaultスタイルがテンプレートになります。
また、font属性 は段落や文字のフォントを設定するのと同じように、書体、太字、斜体、下線などを設定できます。
<Fontオブジェクト>を参考にして下さい。
【Styleオブジェクト(共通)】 | 【機能】 | 【その他詳細】 |
---|---|---|
name | スタイル名の取得 | |
type | スタイルの種類を取得 | WD_STYLE_TYPEクラスのEnum定義を返す PARAGRAPH[段落]、CHARACTER[文字/単語]、TABLE[テーブル] |
base_style | ベース(継承)とするBuilt-in-Stylesを 設定する | 省略した場合は、各デフォルトスタイルが継承される |
font | Fontオブジェクト を取得し、フォント関連 の設定をする | 通常の段落・文字に適用するFontオブジェクトと同様 |
上記に加えて、段落(テーブルのセル内の段落も含む)のスタイル書式には、paragraph_format属性 があります。こちらも通常の段落の書式設定と同様に ParagraphFormatオブジェクト を経由して(配置やインデント、間隔)などの設定ができます。
<ParagraphFormatオブジェクト>を参考にして下さい。
さらに、段落スタイルには便利な属性( next_paragraph_style属性 )が用意されていて、現在の段落の次に追加する段落に適用するスタイルをあらかじめ既定しておくことができます。
見出し(‘Heading 1’)を入れたら、次に本文(‘Body Text’)といったように決まったルールがある場合に設定しておくと便利です。
【Styleオブジェクト(共通)】 | 【機能】 |
---|---|
paragraph_format | Paragraph_Formatオブジェクトを取得し、フォーマットを設定します。 ParagraphオブジェクトのParagraph_Formatオブジェクトと同様です。 ※_ParagraphStyle, _TableStyleのみ有効 |
next_paragraph_style | 段落を追加した際に適用するスタイルを設定します。 指定しない場合は、同じスタイルが適用されます。 ※_ParagraphStyle, _TableStyleのみ有効 |
【SAMPLE.2】
ここで、ユーザー定義スタイルについて、具体的にサンプルコードで確認してみましょう。
段落を1つ追加し、フォントや段落書式をカスタマイズして適用しています。
from docx import Document
from docx.enum.style import WD_STYLE_TYPE
from docx.shared import Pt, Inches, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
doc = Document()
styles = doc.styles # Stylesオブジェクト(Styleオブジェクトのコンテナ)を取得する
# add_style()メソッドで新規Styleオブジェクトを追加する
style = styles.add_style('Original-Style', WD_STYLE_TYPE.PARAGRAPH)
# base_styleプロパティで継承された既定スタイルを確認する
# 新規追加した場合は"None"が表示される(つまりDefaultスタイルが適用されている)
print(style.base_style) # >>None
# base_styleプロパティで既定スタイルを継承する
style.base_style = styles['Title']
print(style.base_style) # >>_ParagraphStyle('Title') id: 2408904452360
#---------------------------------------------------------------------------------
# Fontの定義
# 新規styleオブジェクトのフォント設定をするためにFontオブジェクトを取得する
font = style.font
# nameプロパティでフォントの取得と設定
print(font.name) # >>None
font.name = 'Meiryo UI'
print(font.name) # >>Meiryo UI
# sizeプロパティで文字サイズの取得と設定
print(font.size) # >>None
font.size = Pt(20)
print(font.size.pt) # >>10.0
# colorプロパティでフォント色の取得と設定
print(font.color.rgb) # >>None
font.color.rgb = RGBColor(255,0,0)
print(font.color.rgb) # >>FF0000
#---------------------------------------------------------------------------------
# Paragraph_Formattingの定義
# 新規styleオブジェクトの段落書式の設定をするためにParagraph-Formattingブジェクトを取得する
paragraph_format = style.paragraph_format
# alignmentプロパティで段落の位置揃えの取得と設定
print(paragraph_format.alignment) # >>None
paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT
print(paragraph_format.alignment) # >>LEFT(1)
# left_indentプロパティで段落の左インデントの取得と設定
print(paragraph_format.left_indent) # >>None
paragraph_format.left_indent = Inches(0.50)
print(paragraph_format.left_indent.inches) # >>0.5
#---------------------------------------------------------------------------------
# 新規追加したスタイルを段落に適用
doc.add_paragraph('Custom-Styleを定義し適用', style = style)
#print(len(styles)) # >>165
#style.delete()
#print(len(styles)) # >>164
#doc.add_paragraph('Custom-Styleを定義し適用', style = style)
doc.save('Custom Styleを定義する.docx')
print(len(styles)) # >>165
# delete()メソッドで追加スタイルを削除する
style.delete()
print(len(styles)) # >>164
# 削除されたスタイルを適用しようとしたので'AttributeError'が発生する
#doc.add_paragraph('Custom-Styleを定義し適用', style = style) # 'NoneType' object has no attribute 'type'
それでは、ポイントを解説します。
最後に、すべての既定スタイル数(165)を確認した後に、「delete()メソッド」で追加したスタイルを削除します。スタイル数が1つ減って(164)となったことを確認しています。
因みに、スタイルを削除するとそのスタイルを適用していたオブジェクトは “Default” スタイルに戻ります。
<List2>の実行結果は以下のようになりました。(図16)
テンプレート(‘Title’)をベースとして、フォントや段落の書式カスタマイズできています。
以上、ユーザー定義スタイルの追加・作成方法について解説しました。次項では、スタイルをWordのUIに表示して、推奨リストやギャラリーに反映する方法について解説します。
3.2 Wordのメニュー一覧に表示する
ユーザーが定義したスタイルはWordのメニューの一覧やリストに表示させることができます。これによりカスタマイズした、スタイルをコードからだけでなく、WordのUI(ユーザインターフェース)から直接利用できるようになります。
表示できるのはスタイル一覧(the style gallery)と推奨リスト(list of recommended styles)になります。(図17)
表示設定に関連したプロパティには以下の5つがあります。
【Styleオブジェクト】 | 【機能】 |
---|---|
hidden | 対象スタイルを非表示にする(True:非表示/False:表示) ※スタイルの適用自体は可能 |
quick_style | 対象スタイルをUIの一覧へ表示させる(True:非表示/False:表示) hiddenプロパティはFalseであることが前提 |
locked | 対象のスタイルを非表示・適用不可とする(True:保護/False:解除) ※Word書式の保護設定が有効になっていることが前提 |
unhide_when_used | スタイルを適用したタイミングで表示するようにする (True:有効/False:無効) |
priority | スタイル一覧の表示順位を指定する。Defaultは最優先 同じ順位のスタイルが複数ある場合は名前でソートされる |
例えば「スタイル一覧」と「推奨リスト」を表示させるには、hiddenプロパティ は”Flase“、quick_styleプロパティ は”True“に設定する必要があります。また lockedプロパティ に“True”を指定すると表示はおろか、適用することもできなくなります。
その他の属性の組合せについて整理すると図18のようになります。
【SAMPLE.3】
ここで、ユーザー定義したスタイルを一覧や推奨リストに表示する具体例をサンプルコードで確認してみましょう。
from docx import Document
from docx.enum.style import WD_STYLE_TYPE
doc=Document()
# Stylesオブジェクトの取得
styles = doc.styles
# add_style()メソッドでスタイル名('Original-A')のスタイルを追加する
style_A = styles.add_style('Original-A', WD_STYLE_TYPE.PARAGRAPH)
# add_style()メソッドでスタイル名('Original-B')のスタイルを追加する
style_B = styles.add_style('Original-B', WD_STYLE_TYPE.PARAGRAPH)
#------------------------------------------------------------
# 初期状態(Default)の属性値を確認する
print(style_A.hidden) # >>False
print(style_A.locked) # >>False
print(style_A.quick_style) # >>False
print(style_A.priority) # >>None
#------------------------------------------------------------
# スタイル名('Original-A')の属性を設定する
# Word UI 「スタイル一覧」 「推奨リスト」に表示
# 表示優先度は最高レベル
style_A.hidden = False
style_A.quick_style = True
style_A.priority = 0
#------------------------------------------------------------
# スタイル名('Original-B')の属性を設定する
# Word UI 推奨リスト」のみに表示
# 表示優先度は3番目
style_B.hidden = False
style_B.quick_style = False
style_B.priority = 2
doc.save('WordUI_with_Custum-Style.docx')
それでは、ポイントを解説します。
9,12行目で、段落スタイルを2つ新規追加(“original-A”,” original-B”)します。
<List3>の実行結果は以下のようになりました。(図19)
右のスタイル一覧には、スタイル(“original-A”)のみが表示され、左の推奨リストには2つのスタイルが共に表示できました。また、優先度も指定どおりになっています。
以上が、ユーザー定義スタイルをWordのUIへ反映させる方法の解説となります。最後に本記事の内容をまとめておきましょう。
4. まとめ
いかがでしたでしょうか?
今回は「python-docx」ライブラリによるスタイルの適用手順と、ユーザー定義スタイルについて解説してきました。
ドキュメントは見た目の美しさが重要です。どんな良いコンテンツであっても不揃いなものであっては読者に届かないかもしれません。スタイルをうまく活用して、統一感のある見栄えに整えていきましょう。本記事が何かのお役に立てれば幸いです。
最後にポイントをまとめておきます。
➀. 段落、文字、表にスタイル(Styleオブジェクト)を設定することができる。さらに、スタイルにはライブラリに予め組み込まれた(built-in-Style)とユーザー自ら定義する(Custum-Style)の2種類がある。
➁. 組込みスタイルは段落36種、文字27種類、表100種類と豊富に用意されている。
➂. ユーザー定義スタイルは、built-in-Styleをテンプレートとしながら好みの書式にカスタマイズできる。また、Wordへの登録とUIへの表示方法をコード上で指定できる。
本連載は今回が最後ですが、また機会があればpython-docをつかった応用例を紹介したいと思います。お楽しみに。
また、Word以外にも「Excel」や「PowerPoint」を操作するためのライブラリも連載記事で解説しています。 Office3大ソフトとPythonを組合わせて作業効率を上げていきましょう!
〇Excelの連載についてはこちらから
〇PowerPointの連載についてはこちらから
ここまで、お読みいただきありがとうございました。