エンジニアのはしがき

プログラミングの日々の知見を書き連ねているブログです

Windows10でPythonコードからxlsxを開いて印刷させた

f:id:tansantktk:20211023200845j:plain

事務処理上、Windowsでエクセルを開いて加工したり、印刷したりということが必要になることがあるのですが、どうにも手作業が面倒なのでPythonコード化してみました。 割と簡単に書けるので面倒な手作業はPythonで実行するのがおすすめです。

動作環境

  • Windows10
  • Python3.7

macOS等の場合はここで記載のソースでは動作しませんのでご注意ください。

インストール

Pythonpywin32, openpyxlを使ってエクセルを操作します。エクセルの拡張子はいくつかありますがxlsxで動作確認済みです。

$ pip install pywin32
$ pip install openpyxl

既存のエクセルを開いてセルを加工した後に印刷する

セル加工と印刷を同時に実行してますが、必要に応じて加工下さい。

import os.path
import win32api
import win32print
import openpyxl
import traceback

# エクセルファイルを印刷する
def print_excel(file_path):
    # win32apiでデフォルト設定のプリンタから印刷をする
    win32api.ShellExecute(
        0,
        "print",
        file_path,
        "/c:""%s" % win32print.GetDefaultPrinter(),
        ".",
        0
    )

# アクティブなシートを設定する
def set_active_sheet(sheet_number, file_path):
    wb = openpyxl.load_workbook(file_path)
    # すべてのシートをtabSelectedをFalseにして非アクティブにする
    all_sheet_names = wb.sheetnames
    for sheet_name in all_sheet_names:
        ws = wb[sheet_name]
        ws.sheet_view.tabSelected = False
    wb.save(file_path)
    wb.close()
    # {sheet_number}番目のシートをアクティブにする
    wb = openpyxl.load_workbook(file_path)
    ws = wb.worksheets[sheet_number]
    wb.active = sheet_number
    ws.sheet_view.tabSelected = True
    wb.save(file_path)
    wb.close()

# 特定のセルの値を置き換える
def write_cell(sheet_number, target_cell, new_cell_value, file_path):
    wb = openpyxl.load_workbook(file_path)
    ws = wb.worksheets[sheet_number]
    ws[target_cell] = new_cell_value
    wb.save(file_path)
    wb.close()

try:
    # 対象のエクセルファイルの絶対パスを指定
    xlsx_path = "***********.xlsx"
    # 印刷するエクセルのシートだけをアクティブにする
    set_active_sheet(sheet_number=0, file_path=xlsx_path)
    # エクセルのセルの値を置き換える(例ではD18セルを"hogefuga"に置き換えています)
    write_cell(
        sheet_number=0, 
        target_cell='D18', 
        new_cell_value="hogefuga", 
        file_path=xlsx_path)
    # 印刷開始
    print_excel(xlsx_path)

    print('completed!')
except:
    print('****** Exception ******')
    traceback.print_exc()

既存のエクセルを開いてPDF化する

PDF化することも可能です。

import win32com.client
import traceback
import os

def print_excel(target_file_path, output_path):
    # 既にPDFが存在する場合は処理に失敗するので削除をしておく
    if os.path.exists(output_path):
        print(f"{target_file_path} -> deleting old pdf...")
        os.remove(output_path)

    excel = win32com.client.Dispatch("Excel.Application")
    # エクセルを展開
    print(f"{target_file_path} -> open file...")
    file = excel.Workbooks.Open(target_file_path)
    # 対象シートを指定
    file.WorkSheets(1).Select()
    print(f"{target_file_path} -> exporting...")
    # PDF出力 
    file.ActiveSheet.ExportAsFixedFormat(0, output_path)
    print(f"{target_file_path} -> completed!")

try:
    # 第1引数に開く既存エクセルの絶対パス、第2引数にPDFをエクスポートする絶対パスを指定する
    print_excel("*************.xlsx", "*************.pdf")
    print("completed!")
except:
    print('****** Exception ******')
    traceback.print_exc()