Help us understand the problem. What is going on with this article?

Word に複数の自作スタイルを一括登録する

便利な反面、登録が面倒極まりない Microsoft Word のスタイルを python で一括登録します。

実行イメージ

  • 文字単位のスタイルは背景色+下線の種類で区別
  • 段落単位のスタイルは背景色+囲み線の色で区別

202005202190044.png

  • 表は外周の罫線の色で区別

202005232210703.png

コード

別の記事 で書いたように、pywin32 を使って現在開いている文書を見ながら処理します(Word VBA の定数は こちらの記事 など参照)。

デフォルトだと「実行時点でカーソルがある段落の書式設定」を基準に新規スタイルが作成されます。冒頭にタイトルとして大きなフォントが指定されているような場合に困るので、「標準」スタイルの書式を基準にしました。

activeword_set-style.py
import win32com.client

class vb:
    wdLineStyleSingle          = 1
    wdLineWidth050pt           = 4
    wdLineWidth025pt           = 2
    wdLineWidth150pt           = 12
    wdStyleNormal              = -1
    wdStyleTypeCharacter       = 2
    wdStyleTypeParagraphOnly   = 5
    wdStyleTypeTable           = 3
    wdUnderlineThick           = 6
    wdUnderlineDouble          = 3
    wdUnderlineWavyHeavy       = 27
    wdUnderlineDotDotDashHeavy = 26
    wdUnderlineDottedHeavy     = 20
    wdUnderlineDotDashHeavy    = 25
    wdUnderlineDashHeavy       = 23

def colorhex_to_int(colorcode):
    hex = colorcode[1:7]
    r = int(hex[0:2], 16)
    g = int(hex[2:4], 16)
    b = int(hex[4:6], 16)
    return r + g*256 + b*256*256

def add_marker_style(doc, base_style):
    print('creating new marker style...')
    marker_color_table = (
        [1, {"fill":"#f5ff3d", "border":"#1700c2"}],
        [2, {"fill":"#97ff57", "border":"#ff007b"}],
        [3, {"fill":"#5efffc", "border":"#ffaa00"}],
        [4, {"fill":"#ff91fa", "border":"#167335"}],
        [5, {"fill":"#ffca59", "border":"#2f5773"}],
        [6, {"fill":"#d6d6d6", "border":"#0f1c24"}],
    )
    for mkr in marker_color_table:
        marker_style_name = f"myMaker{mkr[0]}"
        try:
            marker_style = doc.Styles.Add(marker_style_name, vb.wdStyleTypeParagraphOnly)
            marker_style.ParagraphFormat = base_style.ParagraphFormat
            for i in (-4,-3,-2,-1):
                marker_style.ParagraphFormat.Borders(i).LineStyle = vb.wdLineStyleSingle
                marker_style.ParagraphFormat.Borders(i).LineWidth = vb.wdLineWidth050pt
                marker_style.ParagraphFormat.Borders(i).Color = colorhex_to_int(mkr[1]["border"])
            marker_style.Font = base_style.Font
            marker_style.NextParagraphStyle = base_style
            marker_style.ParagraphFormat.Shading.BackgroundPatternColor = colorhex_to_int(mkr[1]["fill"])
            marker_style.ParagraphFormat.OutlineLevel = mkr[0]
            marker_style.QuickStyle = True
            print(f' + "{marker_style_name}"')
        except:
            print(f'failed to create style "{marker_style_name}" ...')

def add_character_style(doc, base_style):
    print('creating new character style...')
    char_color_table = (
        [1, "#ffda0a",vb.wdUnderlineThick],
        [2, "#66bdcc",vb.wdUnderlineDotDashHeavy],
        [3, "#a3ff52",vb.wdUnderlineDottedHeavy],
        [4, "#ff7d95",vb.wdUnderlineDouble],
        [5, "#bf3de3",vb.wdUnderlineDashHeavy],
        [6, "#ff9500",vb.wdUnderlineWavyHeavy],
    )
    for char in char_color_table:
        char_style_name = f"myChar{char[0]}"
        try:
            char_style = doc.Styles.Add(char_style_name, vb.wdStyleTypeCharacter)
            char_style.Font = base_style.Font
            char_style.Font.Shading.BackgroundPatternColor = colorhex_to_int(char[1])
            char_style.Font.Color = colorhex_to_int("#111111")
            char_style.Font.Underline = char[2]
            char_style.QuickStyle = True
            print(f' + "{char_style_name}"')
        except:
            print(f'failed to create style "{char_style_name}" ...')

def add_table_style(doc, base_style):
    print(f'creating new table style...')
    border_color_table = (
        [1,"#2b70ba"],
        [2,"#fc035a"],
        [3,"#0d942a"],
        [4,"#ff4f14"],
        [5,"#fffb00"],
    )
    for tbl in border_color_table:
        table_style_name = f"myTable{tbl[0]}"
        try:
            table_style = doc.Styles.Add(table_style_name, vb.wdStyleTypeTable)
            table_style.Font = base_style.Font
            for i in (-4,-3,-2,-1):
                table_style.Table.Borders(i).LineStyle = vb.wdLineStyleSingle
                table_style.Table.Borders(i).LineWidth = vb.wdLineWidth150pt
                table_style.Table.Borders(i).Color = colorhex_to_int(tbl[1])
                table_style.Table.Shading.BackgroundPatternColor = colorhex_to_int("#eeeeee")
            print(f' + "{table_style_name}"')
        except:
            print(f'failed to create style "{table_style_name}" ...')

def main():
    wdApp = win32com.client.Dispatch("Word.Application")
    if wdApp.Documents.Count < 1:
        if not wdApp.Visible:
            wdApp.Quit()
        return 0

    doc = wdApp.ActiveDocument
    normalStyle = doc.Styles(vb.wdStyleNormal)

    add_marker_style(doc, normalStyle)
    add_character_style(doc, normalStyle)
    add_table_style(doc, normalStyle)

if __name__ == '__main__':
    main()

powershell から呼び出す

メイン使用の powershell から下記のコマンドレットを作って呼び出しています。もちろん python activeword_set-style.py で直接呼び出しても構いません。

function Set-MyStyleToActiveWordDocumentWithPython {
    if ((Get-Process | Where-Object ProcessName -EQ "winword").Count -lt 1) {
        return
    }
    $pyCodePath = "{0}\python_code\activeword_set-style.py" -f $PSScriptRoot
    'python -B "{0}"' -f $pyCodePath | Invoke-Expression
}
AWtnb
神保町で編集者やってます。アナログ大正義の業界で色々模索中。
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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした