Python 仕事の話

Pythonでワード文書も編集したい【表からデータを読み込んで新規ファイルへ】

※アフィリエイト広告を利用しています

SHIN

ガジェット好きの凡人会社員
未経験からシステム業務をしてる人
※Pythonでの業務効率化に挑戦中
自分の勉強の為の自由帳ブログ運営

こんにちはSHINです。

僕のことについては上のプロフィールを見てくれたら嬉しいです。

とにかく未経験からPythonに挑戦中です。

これまではExcelやCSVのファイルをグラフ化したり編集したりといった作業を紹介していますが、今回はワード文書の編集になります。

みなさんWord文書の作成に時間を費やしていませんか?

複雑な報告書やプレゼンテーション資料、それに請求書など、Word文書はいまだに結構使うことありますよね?

今回はいつものPythonを使ってWord文書の自動生成を行う方法をご紹介します。

特に、表データを読み込んで、その情報を基に1ページごとに特定のテキストと画像を挿入する複雑な文書を作成する方法を解説します。

やりたいこと

Wordの表データからそれぞれのページを作成する

・そのページに指定した画像を自動挿入する

PythonってWordも編集できんのよ

話題のChatGPTを使ったプログラミングをするなら下の書籍がおススメです。

Pythonを本気で学びたい人はUdemyでの勉強がおススメです。私も実際に入ってますし、なによりPythonのコースが豊富です。

これからの必須スキルであるPythonを本気で学んで今後の仕事に活かして生きましょう♪

多彩な講座から自分に合った講座を探そう!

プログラミング言語カテゴリー

表データからカスタマイズされた文書を自動生成

今回ご紹介するコードは特定のWord文書内の表データを読み込みそのデータを基にして新しいWord文書を生成するスクリプトです。

今回紹介するスクリプトは、表データ内の各行に対応するページを新しい文書に作成してくれます。

たとえば上の画像の【No】の列をページとして新しい文書が7ページ生成されます。

さらに各ページのヘッダーに【機器名称】そして対応する番号の画像が挿入されるため文書全体が一貫したフォーマットで整理されます。

上の画像のようにあらかじめ挿入したい画像を用意し、ファイルの名称を設定することで自動で画像を挿入してくれます。

例えば1ペーのヘッダーには【部品A】と記載されさらに上の画像ファイルの【1_1】と【1_2】の画像が挿入されます。

この自動化プロセスは、手作業によるミスを減らし文書作成にかかる時間を大幅に短縮してくれます。

これ動いた時は感動しました。

すごさ伝わってる?

サンプルコード

※コピペでは使えないのであくまで参考にしてください

 

import tkinter as tk
from tkinter import filedialog
from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from pathlib import Path



# グローバル変数の設定
doc_path = ''  # Wordファイルのパス
img_folder = ''  # 画像フォルダのパス
save_path = ''  # 保存先パス

def load_file():
    """Wordファイルを選択するための関数"""
    global doc_path
    doc_path = filedialog.askopenfilename(filetypes=[("Word files", "*.docx")])  # ユーザーにファイルを選択させる
    print("Selected Word File:", doc_path)  # 選択したファイルパスを表示(デバッグ用)

def load_folder():
    """画像フォルダを選択するための関数"""
    global img_folder
    img_folder = filedialog.askdirectory()  # ユーザーにフォルダを選択させる
    print("Selected Image Folder:", img_folder)  # 選択したフォルダパスを表示(デバッグ用)

def save_file():
    """保存先ファイルを選択する関数"""
    global save_path
    save_path = filedialog.asksaveasfilename(defaultextension=".docx")
    print("Selected Save Path:", save_path)

def generate_document():
    """新しいWord文書を生成する関数"""
    try:
        print("文書生成プロセスを開始します。")

        if not doc_path or not img_folder:
            print("ファイルまたはフォルダが選択されていません。")
            return

        # 元の文書から表を読み込む
        doc = Document(doc_path)
        table = doc.tables[0]

        # 新しい文書オブジェクトを作成
        new_doc = Document()
        for i, row in enumerate(table.rows):
            if i == 0: continue  # ヘッダー行はスキップ

            no = row.cells[0].text.strip()  # No列
            equipment_name = row.cells[1].text.strip()  # 機器名称列
            application_type = row.cells[5].text.strip()  # 申請区分列

            # ヘッダーに機器名称と申請区分を追加
            section = new_doc.add_section() if i > 1 else new_doc.sections[0]
            header = section.header
            header.is_linked_to_previous = False
            paragraph = header.paragraphs[0] if header.paragraphs else header.add_paragraph()
            paragraph.clear()


             # ヘッダーに「機器リスト」と「No」を含むテキストを追加
            text = f"機器リスト No{no}:{equipment_name} | {application_type}"
            run = paragraph.add_run(text)
            paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
            run.font.size = Pt(12)

             # 各ページに複数の画像を挿入
            for img_index in range(1, 4):  # 例えば、最大3つの画像を挿入すると仮定
                img_filename = f"{no}_{img_index}.jpg"
                img_path = Path(img_folder) / img_filename
                if img_path.is_file():
                    new_doc.add_picture(str(img_path), width=Pt(200))

            # 2ページ目以降は改ページを追加
            if i < len(table.rows) - 1:
                new_doc.add_page_break()

        
        # 文書をユーザーが指定したパスに保存
        if save_path:  # 保存先パスが指定されているか確認
            new_doc.save(save_path)
            print("保存されました", save_path)
        else:
            print("保存先が指定されていません。")

    except Exception as e:
        print("エラーが発生しました:", e)




# Tkinter GUI の設定
root = tk.Tk()
root.title("資料作成ツール")

# ボタンの設定
load_file_btn = tk.Button(root, text="Wordファイルを読み込む", command=load_file)
load_file_btn.pack()

load_folder_btn = tk.Button(root, text="画像フォルダを読み込む", command=load_folder)
load_folder_btn.pack()

# 新しいボタンを追加
save_file_btn = tk.Button(root, text="保存先を選択", command=save_file)
save_file_btn.pack()

generate_btn = tk.Button(root, text="文書を生成する", command=generate_document)
generate_btn.pack()

root.mainloop()  # GUIを起動


このコードの設計としては

ユーザーインターフェースの準備:
    • Tkinterを使用してGUIを構築し、ユーザーがWordファイルと画像フォルダを選択できるようにする。
既存Word文書から表データの読み込み:
    • 選択されたWordファイルを読み込み、指定された表からデータを取得する。
新しいWord文書の作成:
    • 新しい空のWord文書を作成する。
表データに基づいたページの生成:
    • 読み込んだ表データの各行に対応するページを新しい文書に追加する。
    • 各ページの右上に「機器名称」と「申請区分」を含むヘッダーを挿入する。
画像の挿入:
    • 選択されたフォルダから、対応する番号の画像を各ページに挿入する。
文書の保存:
    • すべての編集を終えた新しいWord文書を指定された場所に保存する。

PDFを挿入したかったら画像に変換しちゃえ!!

「画像が挿入できるのは分かったけどPDFも出来ない?」

と思ってPDFファイルを挿入するのは難しそうだったので、それならPDFファイルを画像ファイルにしたらいいんです。

ということでPDFファイルを一括で画像に変換しちゃいましょう!

※コピペでは動作しませんのでご注意を

import tkinter as tk
from tkinter import filedialog, messagebox
import fitz  # PyMuPDF
import os

def select_folder(e):
    """フォルダを選択して、パスをエントリに設定する"""
    folder_selected = filedialog.askdirectory()
    if folder_selected:
        e.delete(0, tk.END)
        e.insert(0, folder_selected)

def convert_pdf_to_img():
    """指定されたフォルダ内のPDFをJPGに変換して保存する"""
    folder = input_folder_entry.get()
    output_folder = output_folder_entry.get()
    
    if not os.path.isdir(folder) or not os.path.isdir(output_folder):
        messagebox.showerror("Error", "指定されたフォルダが存在しません。")
        return

    for file_name in os.listdir(folder):
        if file_name.endswith('.pdf'):
            pdf_path = os.path.join(folder, file_name)
            document = fitz.open(pdf_path)

            for page_num in range(len(document)):
                page = document.load_page(page_num)
                pix = page.get_pixmap()
                output_image_path = os.path.join(output_folder, f"{file_name}_page_{page_num + 1}.jpg")
                pix.save(output_image_path)

    messagebox.showinfo("完了", "PDFの画像変換が完了しました。")

# GUIの設定
root = tk.Tk()
root.title("PDF to JPG Converter")

# 入力フォルダ
tk.Label(root, text="PDFフォルダ:").grid(row=0, column=0)
input_folder_entry = tk.Entry(root, width=50)
input_folder_entry.grid(row=0, column=1)
tk.Button(root, text="選択", command=lambda: select_folder(input_folder_entry)).grid(row=0, column=2)

# 出力フォルダ
tk.Label(root, text="出力フォルダ:").grid(row=1, column=0)
output_folder_entry = tk.Entry(root, width=50)
output_folder_entry.grid(row=1, column=1)
tk.Button(root, text="選択", command=lambda: select_folder(output_folder_entry)).grid(row=1, column=2)

# 変換開始ボタン
tk.Button(root, text="変換開始", command=convert_pdf_to_img).grid(row=2, column=1)

root.mainloop()

 

こうやって「こういうこと出来ないかな」という思いつきで試してみると結構出来たりするのでPythonは本当に便利なプログラミング言語だと思います。

思いついたらとりあえずググれ

ExcelやCSVだけじゃなくWordも!Pythonの驚異的な拡張性

僕もそうでしたがPython初心者の方はPythonでExcelやCSVファイルを扱えることは知っていても、WordのようなOfficeドキュメントも編集できることを知らない方が多いでしょう。

でも実は様々なライブラリやモジュールを使えば、PythonでWordドキュメントの自動編集や加工を行うことができます。

例えば今回のようなPython-Docxモジュールなどがその一例です。

Wordファイルを自動で生成したり、テンプレートに値を流し込んだり、文書の書式を一括で変更したりとプログラムでOfficeドキュメントを自在に操作できます。

またExcelやCSVと組み合わせれば、データソースからWordドキュメントを自動生成するレポートツールなども作成可能です。

企業の業務で頻繁に発生するこうした定型作業をPythonで自動化できます。

Python自動化の可能性は計り知れません

Pythonを本気で学びたい人はUdemyでの勉強がおススメです。私も実際に入ってますし、なによりPythonのコースが豊富です。

これからの必須スキルであるPythonを本気で学んで今後の仕事に活かして生きましょう♪

多彩な講座から自分に合った講座を探そう!

プログラミング言語カテゴリー

  • この記事を書いた人

SHIN

ガジェット好きの凡人会社員
未経験からシステム業務をしてる人
※Pythonでの業務効率化に挑戦中
自分の勉強の為の自由帳ブログ運営

-Python, 仕事の話