フォルダ内にある複数のExcelファイルを、指定したプリンタへまとめて印刷

Pythonでフォルダ内のExcelファイルをプリンタ選択して一括印刷する方法

フォルダ内にある複数のExcelファイルを、指定したプリンタへまとめて印刷するPythonコードを作成しました。

最初に使用するプリンタをプルダウンから選択し、その後、印刷対象のExcelファイルが入っているフォルダを選択します。 フォルダ直下にあるすべてのxlsxファイルを順番に開き、ブック全体を印刷します。

主な機能

  • プリンタをプルダウンから選択
  • 印刷対象のフォルダをダイアログで選択
  • フォルダ直下のxlsxファイルを一括印刷
  • 各Excelブックの全ワークシートをA4に設定
  • Excelファイルを読み取り専用で開く
  • Excelの一時ファイルを印刷対象から除外
  • 処理終了後に元の既定プリンタへ戻す
  • 印刷に成功したファイル数と失敗したファイル数を表示

必要な環境

  • Windows
  • Microsoft Excel
  • Python
  • pywin32

ライブラリのインストール

コマンドプロンプトで、次のコマンドを実行します。

pip install pywin32

完成版コード

次のコードを「フォルダにあるエクセルを一括印刷.py」などの名前で保存します。

import traceback
from pathlib import Path
import tkinter as tk
from tkinter import filedialog, messagebox, ttk

import pythoncom
import win32com.client
import win32print


XL_PAPER_A4 = 9


def show_message(title, text, error=False):
    root = tk.Tk()
    root.withdraw()
    root.attributes("-topmost", True)

    if error:
        messagebox.showerror(title, text, parent=root)
    else:
        messagebox.showinfo(title, text, parent=root)

    root.destroy()


def get_printers():
    flags = (
        win32print.PRINTER_ENUM_LOCAL
        | win32print.PRINTER_ENUM_CONNECTIONS
    )

    printer_names = {
        printer_info[2]
        for printer_info in win32print.EnumPrinters(flags)
        if printer_info[2]
    }

    return sorted(printer_names, key=str.casefold)


def select_printer():
    printers = get_printers()

    if not printers:
        show_message(
            "プリンタ選択エラー",
            "利用可能なプリンタが見つかりません。",
            error=True,
        )
        return None

    result = {"printer": None}

    root = tk.Tk()
    root.title("プリンタ選択")
    root.attributes("-topmost", True)
    root.resizable(False, False)

    window_width = 720
    window_height = 155

    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()

    x = (screen_width - window_width) // 2
    y = (screen_height - window_height) // 2

    root.geometry(
        f"{window_width}x{window_height}+{x}+{y}"
    )

    tk.Label(
        root,
        text="使用するプリンタを選択してください",
        font=("Yu Gothic UI", 10),
    ).pack(pady=(15, 6))

    combo = ttk.Combobox(
        root,
        values=printers,
        state="readonly",
        width=85,
    )
    combo.pack(padx=15)

    try:
        default_printer = win32print.GetDefaultPrinter()
    except Exception:
        default_printer = ""

    if default_printer in printers:
        combo.set(default_printer)
    else:
        combo.current(0)

    def on_ok(event=None):
        selected = combo.get().strip()

        if selected:
            result["printer"] = selected
            root.destroy()

    def on_cancel(event=None):
        root.destroy()

    button_frame = tk.Frame(root)
    button_frame.pack(pady=15)

    tk.Button(
        button_frame,
        text="OK",
        width=12,
        command=on_ok,
    ).pack(side=tk.LEFT, padx=6)

    tk.Button(
        button_frame,
        text="キャンセル",
        width=12,
        command=on_cancel,
    ).pack(side=tk.LEFT, padx=6)

    root.bind("<Return>", on_ok)
    root.bind("<Escape>", on_cancel)
    root.protocol("WM_DELETE_WINDOW", on_cancel)

    combo.focus_set()
    root.mainloop()

    return result["printer"]


def select_folder():
    root = tk.Tk()
    root.withdraw()
    root.attributes("-topmost", True)

    folder = filedialog.askdirectory(
        title="印刷するExcelファイルがあるフォルダを選択してください",
        parent=root,
    )

    root.destroy()

    return folder


def set_all_sheets_to_a4(workbook):
    for index in range(1, workbook.Worksheets.Count + 1):
        worksheet = workbook.Worksheets(index)

        try:
            worksheet.PageSetup.PaperSize = XL_PAPER_A4
        except Exception as error:
            raise RuntimeError(
   

コメント

このブログの人気の投稿

IJCAD(AutoCAD互換CAD) コマンド早見表

設計定数を求めるための代表N値について

WEB地図(国土地理院など)のズームレベルについて