PythonでWordファイルをHTMLに変換
2021-01-09
目次
概要
静的なサイトで記事ページを作成する際、ライターの方から
頂いた Word ファイル(.docx)を元に実装する事はありませんか?
コピペを何度も何度も行う単純作業はきついですよね。
という事で、今回は Python を使用して Word ファイルを元に
いい感じの HTML を生成する方法を紹介していきます 🙂
完成品はこちらです。
使用方法は
README.md
※ Docker 使用を想定して作成しています
Github強化中なので、☆, フォローいただけると喜びます
環境構築
Python3
Docker
Python3
まずは任意の場所にデモ用の ディレクトリを作成してください。
# ディレクトリ作成
mkdir demo
# ディレクトリ移動
cd demo
今回のデモは下記のようなディレクトリ構造で行っていきます。
demo
└ dist
└ index.html # <-- 作成されたHTML
└ src
└ input.docx # <-- 元となるWordファイル
|
└ converter.py # <-- HTML生成処理
コマンドでもエクスプローラーでも構わないので、
dist/
src/
HTML 生成処理の作成
今回使用するモジュール達は下記の通り
| module | description | | ------- | ----------------------------------------------------------------- | | os | ファイル・ディレクトリ操作 | | re | 正規表現が使える | | glob | ファイル名取得 | | mammoth | docx ファイルから html ファイルに変換してくれる | | bs4 | HTML 操作全般をおこなってくれる(今回は html の整形用として使用) |
| test | test | | --- | --- | | test | test |
os
re
glob
mammoth
bs4(beautifulsoup4)
今回は
converter.py
処理の内容は下記の通りです。
import mammoth # docx → html
import os # create file
import glob # read file name
from bs4 import BeautifulSoup # html linter
from bs4 import Tag
import re # 正規表現
files = glob.glob('./src/*.docx')
for file in files:
with open(file, 'rb') as docx_file:
result = mammoth.convert_to_html(docx_file)
source = result.value
# --------------------- class setting start ---------------------
# 見出し
source = source.replace('<h1>', '<h1 class="">')
source = source.replace('<h2>', '<h2 class="">')
source = source.replace('<h3>', '<h3 class="">')
source = source.replace('<h4>', '<h4 class="">')
source = source.replace('<h5>', '<h5 class="">')
# テーブル内のpタグ削除
source = re.sub('<th(.*?)<p>(.*?)</p>', '<th\\1\\2', source)
source = re.sub('<td(.*?)<p>(.*?)</p>', '<td\\1\\2', source)
# パラグラフ
source = source.replace('<p>', '<p class="">')
# 画像 (画像は未対応の為、ダミー画像を表示)
source = re.sub('<img src=\"(.*?)\"', '<img src="https://placehold.jp/150x150.png"', source)
# リスト
source =source.replace('<ul>', '<ul class="">')
source =source.replace('<ol>', '<ol class="">')
# テーブル
source =source.replace('<table>', '<table class="">')
source =source.replace('<tr>', '<tr class="">')
source =source.replace('<td>', '<td class="">')
# --------------------- class setting end ---------------------
html = BeautifulSoup(source, 'lxml')
html = html.prettify()
messages = result.messages
outputfile = file.replace('.docx', '.html')
outputfile = outputfile.replace('/src/', '/dist/')
with open(outputfile, mode='w') as f:
f.write(html)
print("finished convert (´-ω-`)")
それでは、実際にどのように処理を行っているか解説していきます!
元となるWordファイルの取得・ループ処理
まずは元となるWordファイルのファイルパスを全て取得し
ファイルの件数分だけループを回しています。
# --- 略 ---
files = glob.glob('./src/*.docx')
for file in files:
# --- 略 ---
glob
今回の場合は
./src/
.docx
取得し
files
Wordファイルを元にHTMLを作成
ここからは実際にWordファイルを元にHTMLを作成する機能を作成しています。
# --- 略 ---
with open(file, 'rb') as docx_file:
result = mammoth.convert_to_html(docx_file)
source = result.value
# --- 略 ---
file
そちらのファイルを開き、
docx_file
次に
docx_file
mammoth
mammoth.convert_to_html()
docx_file
返ってきたHTML情報を
result
value
タグを独自に加工
ここから各HTMLタグを独自に加工していきます。
# --- 略 ---
# --------------------- class setting start ---------------------
# 見出し
source = source.replace('<h1>', '<h1 class="">')
source = source.replace('<h2>', '<h2 class="">')
source = source.replace('<h3>', '<h3 class="">')
source = source.replace('<h4>', '<h4 class="">')
source = source.replace('<h5>', '<h5 class="">')
# テーブル内のpタグ削除
source = re.sub('<th(.*?)<p>(.*?)</p>', '<th\\1\\2', source)
source = re.sub('<td(.*?)<p>(.*?)</p>', '<td\\1\\2', source)
# パラグラフ
source = source.replace('<p>', '<p class="">')
# 画像 (画像は未対応の為、ダミー画像を表示)
source = re.sub('<img src=\"(.*?)\"', '<img src="https://placehold.jp/150x150.png"', source)
# リスト
source =source.replace('<ul>', '<ul class="">')
source =source.replace('<ol>', '<ol class="">')
# テーブル
source =source.replace('<table>', '<table class="">')
source =source.replace('<tr>', '<tr class="">')
source =source.replace('<td>', '<td class="">')
# --------------------- class setting end ---------------------
# --- 略 ---
replace
ここは実際に入れたいclass名、id名等を自由に記入してください。
HTMLの整形・出力
最後にHTMLの整形を行い、ディレクトリ・ファイル名を指定して出力する処理を解説していきます。
# --- 略 ---
html = BeautifulSoup(source, 'lxml')
html = html.prettify()
messages = result.messages
outputfile = file.replace('.docx', '.html')
outputfile = outputfile.replace('/src/', '/dist/')
with open(outputfile, mode='w') as f:
f.write(html)
print("finished convert (´-ω-`)")
# --- 略 ---
Wordから変換したHTMLデータが入っている
source
改行やインデント等が入っていないHTMLファイルになってしまっている為、
BeautifleSource
html = BeautifulSoup(source, 'lxml')
source
HTMLデータ
html
このような、「どういったデータ構造になっているか明示的に示す」事を 「パースする」と言う事を初めて知りました
html
BeautifulSoup
HTMLデータ
prettify
最後にファイルパスを出力用のパスに書き換えて、
HTMLファイルを作成したら完成です🙆♂️
おわり
今回初めてまともにPythonを触ったのですが、記述方法がとても簡単で感動しました…
知識が薄いので、もっといい書き方、説明があれば是非ご指摘ください!