便利な反面、登録が面倒極まりない Microsoft Word のスタイルを python で一括登録します。
実行イメージ
- 文字単位のスタイルは背景色+下線の種類で区別
- 段落単位のスタイルは背景色+囲み線の色で区別
- 表は外周の罫線の色で区別
コード
別の記事 で書いたように、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
}