LoginSignup
22
18

More than 5 years have passed since last update.

python-docxを使ってdocxファイルを書き換える

Last updated at Posted at 2018-10-15

はじめに

毎週作成が必要な週報を自動生成するための検討です。

  • 前提
    • 週報はdocxファイルである
    • しかもテンプレートが決まっている
    • 自分以外も更新する
    • 更新した箇所は赤文字にしなければならない

調べたところ、python-docxを使えば、
文字だけ置き換えられることが分かりました。
また、paragraphごとに文字色を変えられることも分かりました。
これなら行けそうです。

paragraph.text = paragraph.text.replace("before","after")
paragraph.runs[0].font.color.rgb = RGBColor(204, 0, 0)

image.png

python_docのDocumentの構造

構造を見ると、paragraphはDocument直下にあるだけでなく、tablesの中にもあることが分かり、
すべてのparagraphのtextを置換するためには、それぞれのpragraphを置換する必要があります。

Document直下のparagraph
document.paragraphs[0].text

tables内のparagraph
document.tables[0].rows[0].cells[0].paragraphs[0].text

また、文字色を設定する場合はruns[0]を使います。なぜ[0]が付くのかは分かりません。
paragraph.runs[0].font.color.rgb = RGBColor(204, 0, 0)

image.png

書き換えのサンプルコード

paragraphtablesしか書き換えしていないので、
それ以外の図形や、ヘッダー・フッターの書き換えも必要であれば
追加の実装が必要です。

from docx import Document
from docx.shared import RGBColor
from docx.enum.text import WD_COLOR_INDEX

def replace_text(paragraph):
    replaced_text = paragraph.text.replace("before","after")
    if paragraph.text != replaced_text:
        paragraph.text = replaced_text
        paragraph.runs[0].font.color.rgb = RGBColor(204, 0, 0)
        paragraph.runs[0].font.highlight_color = WD_COLOR_INDEX.YELLOW

document = Document("original.docx")

for paragraph in document.paragraphs:
    replace_text(paragraph)

paragraphs = (paragraph
              for table in document.tables
              for row in table.rows
              for cell in row.cells
              for paragraph in cell.paragraphs)

for paragraph in paragraphs:
    replace_text(paragraph)

document.save("output_new.docx")

以上で置き換え完了です

参考

22
18
6

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
22
18