<当サイト「Pythonでもっと自由を」のコンセプト>
本サイトは、現在人気No.1プログラミング言語である「Python」を使って、「日常の面倒な作業を自動化し効率アップを目指す!」ことを目標に、毎回さまざま役立つライブラリ(モジュール)を紹介しています。
なぜ? Pythonなのか・・・
・Pythonには、私たちのの身近なアプリケーションを操作し自動化をサポートしてくれるさまざまなライブラリ(モジュール)が提供されている。
・初心者でも理解しやすいスクリプト言語でありながら、本格的なオブジェクト指向の側面を合わせ持つバランスの良い言語である。
何を? 自動化する・・・
ビジネスシーンにおいて、もっとも身近に使われるアプリケーションといえば、、、真っ先に思い浮かべるものとしては、MS-Officeの「Excel」「Word」「PowerPoint」・・・あたりではないでしょうか?
毎日使う「定番必須ツール」だからこそ、これらに関わる作業の自動化や効率を上げることのインパクトは非常に大きいと言えます。
そこで今回の連載記事ではOfficeのドキュメント作成ソフト「Word」を「Python」で操作する外部ライブラリの紹介をしたいと思います。
Wordでできることは、メインの「文章を作成する」こと以外にも、「画像・図・表を挿入する」、「ヘッター/フッターの設定」「スタイルを定義する」など多岐にわたります。
そのため、この記事だけで全てを網羅的に解説することはできません。次のようなテーマに分けて複数回の連載記事にわたって図解を交えて詳解します。
連載1回目となる今回は、ドキュメントファイルの「作成・保存」と「文章(テキスト)を作成する」という、Word活用の本質部分を取り上げます。
この記事を読むことで次のようなことが「できる・わかる」ようになりますので最後までお付き合い下さい。
それでは、次節よりライブラリの紹介と導入方法を解説していきます。
1. Wordを操作するライブラリ(python-docx)
PythonからWordを操作するためのライブラリには「pywin32」と「python-docx」の2つがあります。ともにPythonの標準ライブラリではなく外部ライブラリ(サードパーティ)として提供されています。両者の特徴や違いを以下にまとめます。
pywin32:
Wordに限らずOffice系ソフト全般の操作を可能とします。使われるクラスやメソッドなどはWindowsに準拠したプログラミング言語であるC#やVB(Visual Basic)・VBA(VB for Application)と類似したシンタックス構成になっています。
そのためコーディングの際には、Officeディベロッパーセンターのリファレンスが参考になります。
pywin32とOfficeディベロッパーセンターの詳細については次の公式サイトを参照してください。
Pywin32公式ドキュメントの引用
https://pypi.org/project/pywin32/
OfficeディベロッパーセンターVBAリファレンスの引用
https://docs.microsoft.com/ja-jp/office/vba/api/overview/
python-docx:
Wordの操作に特化したPythonライブラリです。pywin32とは異なりクラスやオブジェクトなどは他言語との互換性はなく、、このpython-docx独自仕様ととなります。
そのため、ある程度VBAの知識がある方についてはpywin32を選択されても良いかと思います。
ただし、このpython-docxを使うことのメリットとしては、「比較的コードが単純で直感的に理解しやすい」点にあると言えます。
また、以下の公式リファレンスが整理され、目的に応じたコード事例をトレースするだけでもそれなりのドキュメント作成が行えるでしょう。
python-docx公式ドキュメントの引用
https://python-docx.readthedocs.io/en/latest/
以上をまとめると、次のようになります。
・かゆい所に手が届き何でもできるのは、「pywin32」
・Wordに特化した専用ライブラリとして、容易にコードが書けるのが「python-docx」
とある程度使い分けることができますので参考にして下さい。
本記事では、「python-docx」ライブラリについて解説していきます。
なお、本記事内で紹介する各種クラスや関数などの使い方は一例です。省略可能なオプション引数などについては割愛していますので、詳細や不明点などは必要に応じて上記、公式ドキュメントを確認してください。
1.1 python-docxのインストールと動作確認
「python-docx」の導入と動作確認をします。本ライブラリは「Anaconda」には同梱されていないため、別途インストールが必要です。Pythonのライブラリ管理ツールの pipコマンド をAnacondaプロンプトに入力・実行してインストールしましょう。
pip install python-docx
その他、パッケージ(インストーラ)をダウンロードして「setup.py」による手動インストールも可能です。その場合は依存関係のある「lxml 2.3.2以上」が導入済みであることも確認します。その一方で、pipコマンドであれば自動で依存チェックとインストールが行われます。
Python setup.py install
続いて動作確認をします。Python-docxモジュールであるdocからWordドキュメント本体を管理する「Documentクラス」のインポートだけをして実行します。
from docx import Document
この時点で、特にエラーメッセージなどの警告が表示されなければインストール成功です。
記事内で動作確認した開発環境とバージョン情報は次のとおりとなります。異なる環境やバージョンのライブラリをご使用の際はこの点をご留意ください。
・JupyterNotebook 6.4.8
・Python3.10.6(64bit)
・python-docx 0.8.11
・lxml4.5.0
2. python-docxライブラリのオブジェクト構造
オブジェクト指向を採用するpython-docxでは、一つのオブジェクトには配下にさまざまな関数(メソッド)や属性(プロパティ)をもちあわせており、複数のオブジェクト間を連結・関連付けてWordファイルを操作していきます。
本節では、基本事項としてWordドキュメントの主要コンテンツである文章(テキスト)がpython-docxライブラリ内ではどのように管理されているのか、関連オブジェクトの階層構造について示します。
また、ドキュメントの「新規作成」「既存ファイルの読込み」「保存」といった操作の基本についても解説します。
2.1 段落と文を管理するオブジェクト
Wordのメインコンテンツは、文章(テキスト)です。文章を構成する単位には大きいものから「ページ」「段落」があり「文」「単語」と続きます。python-docxで文章を操作する際も同じように、それぞれ単位ごとのオブジェクトで管理されています。
ですので、まずはじめに文章に関わるオブジェクトの階層構造を理解することは極めて重要となります。
Wordファイル本体は、Documentオブジェクト として管理されます。このDocumentオブジェクトが最上位オブジェクトとなり配下の全てのオブジェクトを管理します。
一般的に、文章は複数の段落により構成されます。
日本語の段落には、「形式段落」と「意味段落」の2パターンあるようです。
Documentオブジェクトが管理する段落は「形式段落」を意味します。途中、意図的に改行することなく、一続きの単文もしくは複数の文になります。
python-docxでは、段落は Paragraphオブジェクト で管理します。
Documentは、複数の段落をもつことができます。つまり、Paragraphオブジェクトを要素とするコレクション形式で管理しています。
さらに、段落(文)は「文字(単語)に分解すること」も、「あらたに文字(単語)を末尾に追加すること」もできます。これを可能にしているのが、単語一つ一つに割り当てられた Runオブジェクト となります。
Paragraphもまた複数の文字(単語)を管理します。つまり、Runオブジェクトを要素とするコレクション(イテラブル)形式をとります。
ここまでの「文章作成」に関わるオブジェクトと、それ以外の「Wordの構成機能」に関わるオブジェクトの階層構造を以下にまとめました。(図3)
今回解説する「文章作成」以外にも「画像」「テーブル(表)」「スタイルの定義」「セクションの定義」などの機能がWordにはありますが、これらは全てDocumentオブジェクトの直下に配置されます。これらについては、別記事で詳解します。
以上が、python-docxが管理するオブジェクトの概要になります。
それでは、次項より本記事のメインテーマである「文章作成」ついて深掘り解説していきます。
3. python-docxの基本(ドキュメントの作成~保存まで)
python-docxにてWordを操作するには、まずDocumentオブジェクトを取得する必要があります。前述したとおり、同オブジェクトはWordファイルそのものであって、オブジェクト階層構造の最上位クラスに位置します。
3.1 ドキュメントの新規作成・既存ファイルの読込み
Documentオブジェクトを取得する方法は、「既存のWordファイルを読込む」または「新規ファイルを作成」する場合の2通りがあります。
いずれの場合も Documentクラス からを次の書式のようにしてインスタンスを生成します。
既存ファイルを読込み編集する場合は 引数:docx にファイル名(カレントディレクトリにない場合は、パスも含めて)を指定し、新規作成する場合は引数を指定せずに生成します。
3.2 ドキュメントの保存(上書き/名前を付けて保存)
作成したドキュメントを保存するにはDocumentオブジェクトの save()メソッド を次の書式のように指定します。
「名前を付けて保存」するもしくは「別名を付けて保存する」場合は 引数:path_or_stream に所望のファイル名を指定して save()メソッド を実行します。
「上書き保存」の場合は、Documentオブジェクトを読込んだ時と同じファイル名を省略することなく指定します。
例として、既存のファイル(sample1.docx)を読込んで、新規ファイルとして別名(otherName.docx)を付けて保存するコードは次のようになります。<List1>
# docxライブラリからDocumentクラスをインポート
from docx import Document
# Documentクラスの引数に読込むファイルを指定してインスタンスを生成
doc = Document('sample1.docx')
# Documentオブジェクトであることを確認
print(type(doc)) # >> <class 'docx.document.Document'>
# Documentオブジェクトのsaveメソッドの引数にファイル名を指定する
doc.save('OtherName.docx')
4. ドキュメントに「段落」を追加し文章コンテンツを作る
本節ではWordドキュメントの「メインコンテンツである文章」を配置するためのフレームワークとなる段落(Paragraphオブジェクト)について解説します。
段落を追加して文章を設定する基本操作から、段落ブロック単位での書式設定までを取り上げます。
4.1 段落(Paragraphオブジェクト)を追加する
新規作成もしくは既存のドキュメントに、あらたに段落を追加したい場合は、Documentオブジェクトの add_paragraph()メソッド を次の書式のようにして使います。
引数:text には、段落追加する際に設定する文章を指定します。特に指定しなかった場合でも、add_paragraphメソッドは、空の段落だけ(Paragraphオブジェクト)が追加されます。文章は後からtextプロパティ(後述)でも設定することもできます。
引数:style には、Wordに登録された、様々な文章スタイルを設定することができます。図5はあらかじめ登録されたスタイル書式の一覧となります。(一部はWordの「ホーム」メニュー ->「スタイル」のUIにも表示)
タイトル「“Title”」、見出し「“Heading *”」、リスト「“List **”」といったように文字列(シングル、ダブルクォート付き)で指定します。
次に、追加した段落の取得についてです。Documentオブジェクには、複数の段落を含むことができ、Paragraphオブジェクトを要素とするコレクション(イテラブルなオブジェクト)として管理しています。
Documentファイルに含まれる、全ての段落を取得するには次の paragrahsプロパティ を使います。
また、インデックスを指定して所望の段落だけを取得することもできます。
Paragraphオブジェクト配下にも、同様に多くのメソッド・プロパティ・属性がありますが、全てを紹介することはできません。ここでは、厳選して3つ紹介します。
1つ目が段落に文章を設定する textプロパティ、2つ目が段落の書式設定(※)を行う paragraph_formatプロパティ です。最後に、文字(単語)単位で管理するRunオブジェクトを追加する add_run()メソッド です。
※ 文字(単語)レベルでの書式設定は、以降で解説するRunオブジェクトにて対応します。
【Paragraphオブジェクト】 | 【機能】 | 【その他詳細】 |
---|---|---|
text | 段落の文字列の取得(Textオブジェクトの取得)と設定 | |
paragraph_format | ParagraphFormatオブジェクト を取得 | 段落の書式設定を行う(後述) 【ParagraphFormatオブジェクト】 |
add_run(text, style) | Runオブジェクト を取得する 引数: text: 設定する文字列を指定する 引数: style: スタイルを指定する(デフォルト:None) | 個別文字を管理する(後述) 【Runオブジェクト】 |
paragraph_formatプロパティ で取得できるParagraphFormatオブジェクトからは、段落レベルでの書式(インデント、スペースなど)に関わる様々なプロパティが用意されています。以下、主要なものをリストアップしました。
【ParagraphFormatオブジェクト】 | 【機能】 | 【その他詳細】 |
---|---|---|
alignment | 段落中の文章の揃え位置を指定する | 【WD_ALIGN_PARAGRAPHクラス】 例:左寄せ(LEFT), 右寄せ(RIGHT) |
left_indent | 左側のインデント間隔を指定する | Inchesなどの単位で指定する |
page_break_before | 新しいページの先頭に段落を追加する | True:有効/False:無効 |
widow_control | 段落がページを跨ぐことがないようにする | True:有効/False:無効 |
space_before | 一つ前の段落との間隔を指定する | Pt/Inchiesなどの単位で指定する |
line_spacing | 行間の間隔を指定する | Ptによる数値指定や、 【WD_LINE_SPACINGクラス】 の定義から指定 |
以下は、MS-WordのUIと各種プロパティの対応関係を示しています。(図6,7)
「配置」は alignmentプロパティ にて対応します。「WD_ALIGN_PARAGRAPクラス」で定義されているEnumで指定します。「インデント」は left(right)_indentプロパティ にて対応します。
また、「行間の間隔」は line_spacingプロパティ で、「WD_LINE_SPACINGクラス」から単位と間隔値を指定します。
段落の「改ページ」に関してもMS-Word同レベルに対応しており、次のように4つのプロパティが提供されています。
例えば、段落がページを跨ぐような場合は、全体を改ページへ移動する widow_control プロパティ であったり、段落を追加する際には改ページ(新しいページ)に挿入するといった page_break_beforeプロパティ などがあります。
新しいページを追加(改ページ)する機能は、他にも後述する add_page_bread()メソッド がありますが、こちらは段落の追加自体は別に行う必要があります。
【SAMPLE.1】
段落(Paragraphオブジェクト)に関しての解説は以上です。少し長くなりましたのでサンプルコードで実際の使い方を確認してみましょう。
コードの概要は、スタイル(Title/List Number)をもつ段落を追加します。属性による文章の設定や、段落レベルでの書式(配置揃え)を適用する事例です。
from docx import Document # Documentクラスをインポート
from docx.enum.text import WD_ALIGN_PARAGRAPH # 段落位置の定義クラスをインポート
sentence = ['Python(パイソン)はインタープリタ型の高水準汎用プログラミング言語',
'Pythonは1980年代後半にABC言語の後継としてリリースされた',
'Pythonは動的に型付言語である',
'Pythonはオブジェクト指向を採り入れている']
# Documentオブジェクトを取得
doc = Document()
# Paragraphオブジェクトを追加(タイトル)・・・(A)
doc.add_paragraph('python-docxでWordを操作する', style='Title')
for i in range(0, len(sentence)):
# Paragraphオブジェクトを追加(リスト番号)・・・(B)
doc.add_paragraph(sentence[i], style='List Number')
# Paragraphオブジェクトを追加(デフォルト)・・・(C)
paragraph_1 = doc.add_paragraph()
# textプロパティで文字を追加
paragraph_1.text = '段落の位置(中央合わせ)'
# alignmentプロパティで段落の位置を設定(中央合わせ)
paragraph_1.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
# paragraphsプロパティでParagraphオブジェクトの個数を調べる
print(len(doc.paragraphs)) # >>6
doc.save('Paragraph_usage_List2JP.docx')
それでは、コードのポイントを解説します。
<List2>の実行結果(以下からダウンロードできます)は以下のようになりました。(図8)
タイトル(Title)とリスト(List Number)付きの段落が追加され、文章の設定(引数によるものと、属性による指定)と、配置揃えに対応できました。
【SAMPLE.2】
もう一つ、活用例を紹介します。
Python-docxでは、何も指定しなければページの先頭から順番に段落が追加されていきますが、次のコード例のように「新規ページを追加する」「次のページから文章(段落)を追加する」といったことに対応できます。
from docx import Document
# Documentオブジェクトを取得
doc = Document()
# Paragraphオブジェクトを追加 [A]
doc.add_paragraph('python-docxでWordを操作する1', style='Title' )
# 改ページする
tmp=doc.add_page_break()
# Paragraphオブジェクトを追加 [B]
doc.add_paragraph('python-docxでWordを操作する2', style='Title')
doc.save('Page_break_List3JP.docx')
それでは、コードのポイントを解説します。
<List3>の実行結果(以下からダウンロードできます)は以下のようになりました。(図9)
1ページ目の冒頭の段落から、改ページにより2ページ目にカーソルが移動し、新たに段落が追加されました。
さて、ここまでの解説により、文章コンテンツをドキュメントに配置するには、Paragraphオブジェクトの追加とその操作が重要であることがご理解いただけたと思います。
ところで、文章レベルでの書式設定。たとえば「文字を大きくする」「太字」「斜体」「文字色」などフォントの設定を行うにはどのよにするのでしょうか?
これらのことはこの後で解説するRunオブジェクトという新たなレイヤーにて対応ができます。
5. 文字(Runオブジェクト)の追加/書式・装飾の設定をする
段落を構成する文章は、単語や文字単位に分解することができます。python-docxでは、文章の最小区切り単位をRunオブジェクトで管理しています。Runオブジェクトには、文字のフォント調整や、太下線、斜体、文字色指定などを施すための多くの属性が提供されています。
引数:text にはRunオブジェクトの追加と同時に設定する文字(単語)を、引数:style には登録済みのスタイルを指定します。これらはオプション引数であとから、プロパティで設定することがでます。
また、文字のデフォルト(組込み)スタイルには以下にようなものがあり、段落のスタイル同様に文字列で指定します。
文字レベルでの操作に関連したメソッド(属性)には以下があります。
【Runオブジェクト(メソッド)】 | 【特徴】 | 【その他詳細】 |
---|---|---|
add_break(break_type) | 改行する | 改行パターン(6種類)を選択 例) WD_BREAK.LINE, WD_BREAK.PAGE |
add_picture(image_path, width, height) | 文章途中に画像を挿入する | 引数:image_path:画像ファイルのパス 引数:width:横幅 引数:height:縦幅 |
add_tab() | タブを挿入する | |
add_text() textプロパティ | 文字・単語を設定/取得する |
文字のフォント・書式の設定は、fontプロパティ で取得した Fontオブジェクト にさらに配下のプロパティを繋げます。主なプロパティには以下のようなものがあります。
【Fontオブジェクト(属性)】 | 【特徴】 | 【その他詳細】 |
---|---|---|
color. rgb color. theme_color | 文字のフォントの色を設定する | 【RGBColorクラス】指定 例) RGBColor(0xff, 0x99, 0xcc) 【MSO_THEME_COLOR_INDEXクラス】から選択 |
size | フォントサイズを設定する | Pt単位で指定 |
name | フォント名を設定する | 例) Calivri’など |
underline | 下線の設定をする | True(下線(SINGLE)あり)/False(なし) 他の線種は【WD_UNDERLINE】の定義から選択 |
bold | 文字を太文字にする | True(有効)/False(無効) |
italic | 文字を斜体にする | True(有効)/False(無効) |
【SAMPLE.3】
文字(Runオブジェクト)に関しては以上です。サンプルコードで具体的な使い方を確認してみましょう。
コードの概要は、段落(Paragraphオブジェクト)にRunオブジェクトを追加しつつも、個別文字(単語)ごとに書式・フォントの詳細設定を施す内容となります。
from docx import Document
from docx.shared import Pt, RGBColor # 単位系や色が定義されているSharedクラス
from docx.enum.dml import MSO_THEME_COLOR # 各種プロパティの設定が定義されているEnumerationsクラス
from docx.enum.text import WD_UNDERLINE
doc1= Document()
doc1.add_paragraph('「python-docx」でWord文書作成', style='Title')
doc1.add_paragraph('Pythonの外部ライブラリ「python-docx」を使って、\
Wordを操作することができます。Runオブジェクトを取得し各種プロパティを設定 \
することで様々な文字の装飾をすることができます。')
doc1.add_paragraph('文書作成の基本', style='Heading 1')
#---------------------------------------------------------------------------------
# Runオブジェクト関連のメソッド・プロパティ[A]
p1 = doc1.add_paragraph('文書内で')
p1.add_run('太文字').bold = True # boldプロパティによる太文字指定
p1.add_run('や、')
p1.add_run('斜線').italic = True # italicプロパティによる斜体指定
p1.add_run('や、')
p1.add_run('下線(DEFAULT) ').underline = True # underlineプロパティによる下線指定
p1.add_run('や、')
p1.add_run('下線(DASH) ').underline = WD_UNDERLINE.DASH
p1.add_run('などを設定できます。')
#----------------------------------------------------------------------------------
# Fontオブジェクト関連のプロパティ[B]
p2 = doc1.add_paragraph()
# フォントサイズの指定
p2.add_run('フォントサイズ「12ポイント」').font.size = Pt(12)
p2.add_run().add_break()
p2.add_run('フォントサイズ「15ポイント」').font.size = Pt(15)
p2.add_run().add_break()
# フォントの色の指定
p2.add_run('赤色 ').font.color.rgb = RGBColor(255,0,0)
p2.add_run('青色 ').font.color.rgb = RGBColor(0,255,0)
p2.add_run('緑色 ').font.color.rgb = RGBColor(0,0,255)
p2.add_run().add_break()
p2.add_run('MSO_THEME_COLOR.ACCENT_1').font.color.theme_color = MSO_THEME_COLOR.ACCENT_2
p2.add_run().add_break()
p2.add_run('MSO_THEME_COLOR.FOLLOWED_HYPERLINK').font.color.theme_color = MSO_THEME_COLOR.FOLLOWED_HYPERLINK
doc1.save('RunObj_List4JP.docx')
それでは、コードのポイントを解説します。
コードの冒頭で、文字色と下線の設定に必要となるクラスをそれぞれインポートしてます。(RGBColor, WD_UNDERLINEクラス)
その他、39行目などでは、add_break()メソッド にて段落内で改行を入れています。
<List4>の実行結果(以下からダウンロードできます)は以下のようになりました。
文字単位での、書式設定(太字・斜体字・下線)およびフォント設定(サイズ、色)が適用されています。
以上が、Runオブジェクトによる文字(単語)の取り扱い方となります。
6. まとめ
いかがでしたでしょうか?
今回はMS-OfficeのWordを操作する「python-docx」ライブラリを取り上げ、ドキュメント作成の基本について解説してきました。
Wordを使って文章作成をしたことがある方でしたら、オブジェクト名やメソッド・プロパティ名から直感的にコーディングできることを実感して頂けたのではないでしょうか。
1から新規コンテンツを作成するといった用途で、わざわざPythonを経由する必要はあまりないかもしれません。しかし、「ある程度、既定のドキュメントスタイルがある」場合や「一度に大量の編集作業が必要になった」といった場合に効果を発揮します。
是非、貴方の作業効率の改善にお役立てください。
最後にポイントをまとめておきましょう。
➀. PythonからWordを操作する機能を提供するライブラリに「pywin32」と「python-docx」の2つがある。それぞれに特徴や長所・短所があるため用途に応じて使い分けるのが良いであろう。特に初心者におすすめなのは「python-docx」ライブラリである。
➁. python-docxにて文章作成をするには、Paragraph(段落) と Run(文字)オブジェクト の存在を常に意識しながらコーディングすることが肝要である。
➂. 段落単位での書式は、Paragraphオブジェクトで、文字単位での書式はRunオブジェクトで設定する。MS-Wordでできる、文章作成の大部分に対応する。
さて、次回の記事ではpython-docxの応用編として、「画像や表(テーブル)を挿入する方法」「セクションによるページの詳細設定やヘッターやフッター設定する方法」について解説をしていきます。
ぜひ、こちらもお読み頂ければ幸いです。
最後までお読みいただきありがとうございました。