育儿知识(家园小报)自动生成ワークフロー(2024年改訂版)

本記事では、Word文書に保存された「育儿知识(家园小报)」を、Pythonスクリプトを用いてバッチ処理で生成・画像化する手法を解説します。対象はA4縦版で、フォルダ内の複数文書を一括処理します。

処理の流れは以下の通りです。

  1. ファイル名の統一
  2. 旧形式(.doc)から新形式(.docx)への変換
  3. 手動によるテキスト抽出とExcelへの格納
  4. Wordテンプレートへのデータ差し込み
  5. 生成された.docxファイルの画像(PNG)変換
  6. 生成画像のトリミング(必要な場合)

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_xzoom_yで調整可能です。

タグ: Word自動化 Python python-docx Win32COM PDF変換

6月29日 16:43 投稿