本記事では、Word文書に保存された「育儿知识(家园小报)」を、Pythonスクリプトを用いてバッチ処理で生成・画像化する手法を解説します。対象はA4縦版で、フォルダ内の複数文書を一括処理します。
処理の流れは以下の通りです。
- ファイル名の統一
- 旧形式(.doc)から新形式(.docx)への変換
- 手動によるテキスト抽出とExcelへの格納
- Wordテンプレートへのデータ差し込み
- 生成された.docxファイルの画像(PNG)変換
- 生成画像のトリミング(必要な場合)
1. ファイル名の正規化
まず、入力元のフォルダ内にあるファイル名を統一します。具体的には「2024年02月 家园小报.doc」のように整形します。
import os
import time
base_dir = r"D:\test\02办公类\91周计划4份_2024年中4班\03 育儿知识"
input_dir = os.path.join(base_dir, "01doc")
output_dir = os.path.join(base_dir, "02docx")
files = os.listdir(input_dir)
print(files)
for f in files:
parts = f.split('月')
if len(parts) >= 2:
new_name = '2024年' + parts[0] + '月 家园小报.doc'
src_path = os.path.join(input_dir, f)
dst_path = os.path.join(input_dir, new_name)
os.rename(src_path, dst_path)
time.sleep(2)
files = os.listdir(input_dir)
for f in files:
if len(f) == 16: # 1桁の週次
year_part = f.split('年')[0]
rest_part = f.split('年')[1]
new_name = year_part + '年0' + rest_part
os.rename(os.path.join(input_dir, f), os.path.join(input_dir, new_name))
elif len(f) == 17: # 2桁の週次はそのまま
pass
2. .doc から .docx への変換
Win32COMを使ってdoc形式をdocxに変換します。
import os
from win32com import client as wc
files = []
for f in os.listdir(input_dir):
if f.endswith('.doc') and not f.startswith('~$'):
files.append(os.path.join(input_dir, f))
os.makedirs(output_dir, exist_ok=True)
for f in files:
word = wc.Dispatch("Word.Application")
doc = word.Documents.Open(f)
base_name = os.path.basename(f)
new_path = os.path.join(output_dir, base_name + 'x')
doc.SaveAs(new_path, 12)
doc.Close()
3. データ抽出とExcel準備
Word内のテキストはテキストボックス内に配置されているため、Pythonで直接抽出するのは困難です。そこで手動で各ファイルを開き、内容をExcelにコピーします。コピー後、以下のスクリプトで余分な空白や特殊文字を除去します。
from openpyxl import load_workbook
path = r"D:\test\02办公类\91周计划4份_2024年中4班\03 育儿知识"
wb = load_workbook(path + r'\11 中4班下学期_育儿知识.xlsx')
ws = wb.active
for row in ws.iter_rows():
for cell in row:
if cell.value and isinstance(cell.value, str):
cell.value = cell.value.strip()
# 全角・半角スペース除去
cell.value = str(cell.value).replace(' ', '').replace('\u00a0', '')
# 数字+「、」を「.」に置換
for s in range(1, 10):
cell.value = cell.value.replace(f"{s}、", f"{s}.")
wb.save(path + r'\11 中4班下学期_育儿知识.xlsx')
4. Wordテンプレートへのデータ差し込み
次に、準備したExcelデータをWordテンプレート(例:12 信息窗主题知识_竖版双.docx)に差し込み、複数のdocxファイルを生成します。
from docxtpl import DocxTemplate
import pandas as pd
file_path = os.path.join(path, '04合成新育儿知识')
os.makedirs(file_path, exist_ok=True)
df = pd.read_excel(path + '\\11 中4班下学期_育儿知识.xlsx')
# カラム名を適宜修正
title_list = df["title"].str.rstrip()
name_list = df["name"]
content_list = df["content"].str.rstrip()
classroom_list = df["classroom"].str.rstrip()
t1_list = df["T1"].str.rstrip()
t2_list = df["T2"].str.rstrip()
time_list = df["time"].str.rstrip()
for i in range(len(df)):
context = {
"title": title_list[i],
"content": content_list[i],
"classroom": classroom_list[i],
"name": name_list[i],
"T1": t1_list[i],
"T2": t2_list[i],
"time": time_list[i],
}
tpl = DocxTemplate(path + '\\12 信息窗主题知识_竖版双.docx')
tpl.render(context)
output_name = f"第{name_list[i]:02d}周 {classroom_list[i]} 育儿知识({time_list[i]}).docx"
tpl.save(os.path.join(file_path, output_name))
5. Docx → PNG 変換
生成されたdocxをPDF経由でPNG画像に変換します。以下のスクリプトでは、ファイルをコピー後、変換と不要ファイルの削除を行います。
from win32com.client import Dispatch
import fitz
import shutil
src_dir = os.path.join(path, '04合成新育儿知识')
dst_dir = os.path.join(path, '05jpg上传')
os.makedirs(dst_dir, exist_ok=True)
# docxコピー
for f in os.listdir(src_dir):
if f.endswith('.docx'):
shutil.copy(os.path.join(src_dir, f), os.path.join(dst_dir, f))
# Word => PDF => PNG
def convert_word_to_png(folder):
for root, dirs, files in os.walk(folder):
for f in files:
if f.endswith('.docx'):
docx_path = os.path.join(root, f)
word = Dispatch('Word.Application')
doc = word.Documents.Open(docx_path)
pdf_path = docx_path.replace('.docx', '.pdf')
doc.SaveAs(pdf_path, FileFormat=17)
doc.Close()
word.Quit()
pdf = fitz.open(pdf_path)
for pg in range(pdf.page_count):
page = pdf[pg]
trans = fitz.Matrix(2, 2).preRotate(0)
pix = page.get_pixmap(matrix=trans, alpha=False)
pix.save(pdf_path.replace('.pdf', f'{pg+1}.png'))
pdf.close()
convert_word_to_png(dst_dir)
# PDFと元のdocxを削除
for root, dirs, files in os.walk(dst_dir):
for f in files:
if f.endswith('.pdf') or f.endswith('.docx'):
os.remove(os.path.join(root, f))
# 最初のページ以外のPNGを削除(必要な場合)
for root, dirs, files in os.walk(dst_dir):
for f in files:
for k in range(2, 13):
if f.endswith(f'{k}.png'):
os.remove(os.path.join(root, f))
注意点
- 元のWordファイルの構造(テキストボックス使用)によっては、自動抽出が難しいため、手作業でのデータ転記が必要です。
- 各処理は独立して動作するため、ファイル名やフォルダパスは環境に合わせて変更してください。
- 画像解像度は
zoom_x、zoom_yで調整可能です。