
「大量のExcelやPowerPointファイルをPDFに変換する作業、フォルダごとに整理し直すのが面倒…」
「手作業での変換は時間がかかるし、ミスも心配…」
そんなお悩みを抱えるあなたへ!この記事では、Microsoft Officeドキュメント(Excel、PowerPoint)を、元のフォルダ構造を保ったままPDFファイルに一括変換するPythonスクリプトをご紹介します。さらに、エラーが発生した場合にはログも出力されるので、問題点の把握も簡単。日々の定型業務を自動化し、貴重な時間を有効活用しましょう!
目次
こんな方におすすめ!
- 大量のOfficeファイルを定期的にPDFに変換する必要がある方
- 変換後のファイルを元のフォルダ構成で管理したい方
- 手作業による変換ミスや時間のロスを減らしたい方
- プログラミング(Python)で業務効率化に挑戦してみたい方
スクリプトの主な機能
- 指定フォルダ内の一括処理: 入力フォルダを指定するだけで、サブフォルダ内のファイルも全て処理対象に。
- Excel・PowerPoint対応: .xlsx, .xls, .xlsm (Excel) や .pptx, .ppt, .pptm (PowerPoint) ファイルをPDFに変換します。
- フォルダ構造の完全維持: 入力フォルダのサブフォルダ構造を、そのまま出力先フォルダに再現します。
- GUIによる簡単操作: 入力フォルダと出力フォルダは、使い慣れたダイアログで選択できます。
- エラーログ出力: 変換中にエラーが発生した場合、詳細なログファイル(conversion_log.log)が生成されるため、原因究明が容易です。
- 一時ファイルのスキップ: Officeが自動生成する一時ファイル(~$で始まるファイル)は処理対象外とし、エラーを防ぎます。
準備するもの
- Windows環境: このスクリプトはWindows OS上で動作します。
- Microsoft Office: ExcelおよびPowerPointがインストールされている必要があります。
- Pythonのインストール: Pythonが未導入の場合は、Python公式サイトからダウンロードしてインストールしてください。
- pywin32ライブラリ: PythonからOfficeアプリケーションを操作するために必要です。コマンドプロンプトやターミナルで以下のコマンドを実行してインストールします。
pip install pywin32【完全版】Python PDF自動変換スクリプト
以下が、OfficeファイルをPDFに一括変換するPythonスクリプトです。
import os
import tkinter as tk
from tkinter import filedialog
import win32com.client
import logging
import pythoncom # pywin32ライブラリの一部
# 定数
XL_TYPE_PDF = 0 # Excel: PDF形式
PP_SAVE_AS_PDF = 32 # PowerPoint: PDF形式
# ログ設定
log_file_name = 'conversion_log.log'
try:
script_dir = os.path.dirname(os.path.abspath(__file__))
log_file_path = os.path.join(script_dir, log_file_name)
except NameError:
script_dir = os.getcwd()
log_file_path = os.path.join(script_dir, log_file_name)
logging.basicConfig(
filename=log_file_path,
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
encoding='utf-8'
)
def select_folder(title_msg):
"""フォルダ選択ダイアログを表示し、選択されたフォルダパスを返す"""
root = tk.Tk()
root.withdraw()
root.attributes('-topmost', True)
folder_path = filedialog.askdirectory(title=title_msg)
root.destroy()
return folder_path
def convert_excel_to_pdf(excel_app_instance, input_file_path, output_file_path):
"""ExcelファイルをPDFに変換する"""
workbook = None
try:
logging.info(f"Excelファイル変換開始: {input_file_path}")
workbook = excel_app_instance.Workbooks.Open(input_file_path, ReadOnly=True)
workbook.ExportAsFixedFormat(Type=XL_TYPE_PDF, Filename=output_file_path)
logging.info(f"Excelファイル変換成功: {output_file_path}")
return True
except Exception as e:
logging.error(f"Excelファイル変換エラー ({input_file_path}): {e}")
return False
finally:
if workbook:
workbook.Close(SaveChanges=False)
def convert_ppt_to_pdf(ppt_app_instance, input_file_path, output_file_path):
"""PowerPointファイルをPDFに変換する"""
presentation = None
try:
logging.info(f"PowerPointファイル変換開始: {input_file_path}")
presentation = ppt_app_instance.Presentations.Open(input_file_path, ReadOnly=True, WithWindow=False)
presentation.SaveAs(output_file_path, FileFormat=PP_SAVE_AS_PDF)
logging.info(f"PowerPointファイル変換成功: {output_file_path}")
return True
except Exception as e:
logging.error(f"PowerPointファイル変換エラー ({input_file_path}): {e}")
return False
finally:
if presentation:
presentation.Close()
def main_process():
logging.info("処理開始")
com_initialized_here = False
try:
pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
com_initialized_here = True
except AttributeError:
try:
pythoncom.CoInitialize()
com_initialized_here = True
except pythoncom.com_error as e_coinit:
if e_coinit.hresult == -2147417850: # RPC_E_CHANGED_MODE
logging.info("COMは既に別のモードで初期化されています。続行します。")
else:
logging.error(f"COMライブラリの初期化に失敗しました (CoInitialize): {e_coinit}")
print(f"COMライブラリの初期化に失敗しました: {e_coinit}。処理を終了します。")
return
except pythoncom.com_error as e:
if e.hresult == -2147417850: # RPC_E_CHANGED_MODE
logging.info("COMは既に別のモードで初期化されています。続行します。")
else:
logging.error(f"COMライブラリの初期化に失敗しました (CoInitializeEx): {e}")
print(f"COMライブラリの初期化に失敗しました: {e}。処理を終了します。")
return
input_dir = select_folder("変換元のOfficeファイルが含まれるフォルダを選択してください")
if not input_dir:
logging.warning("入力フォルダが選択されませんでした。処理を終了します。")
print("入力フォルダが選択されませんでした。処理を終了します。")
if com_initialized_here:
pythoncom.CoUninitialize()
return
output_dir = select_folder("PDFファイルの出力先フォルダを選択してください")
if not output_dir:
logging.warning("出力フォルダが選択されませんでした。処理を終了します。")
print("出力フォルダが選択されませんでした。処理を終了します。")
if com_initialized_here:
pythoncom.CoUninitialize()
return
logging.info(f"入力フォルダ: {input_dir}")
logging.info(f"出力フォルダ: {output_dir}")
print(f"入力フォルダ: {input_dir}")
print(f"出力フォルダ: {output_dir}")
print(f"ログファイルは次の場所に生成されます: {log_file_path}")
excel_app = None
ppt_app = None
try:
try:
excel_app = win32com.client.Dispatch("Excel.Application")
excel_app.Visible = False
excel_app.DisplayAlerts = False
except Exception as e_excel_dispatch:
logging.error(f"Excelアプリケーションの起動に失敗しました: {e_excel_dispatch}")
excel_app = None
try:
ppt_app = win32com.client.Dispatch("Powerpoint.Application")
except Exception as e_ppt_dispatch:
logging.error(f"PowerPointアプリケーションの起動に失敗しました: {e_ppt_dispatch}")
ppt_app = None
if not excel_app and not ppt_app:
logging.error("ExcelおよびPowerPointアプリケーションの起動に両方失敗しました。処理を終了します。")
print("Officeアプリケーションの起動に失敗したため、処理を実行できません。")
return
converted_files = 0
failed_files = 0
for current_root, _, files_in_current_root in os.walk(input_dir):
files_to_process = [f for f in files_in_current_root if not f.startswith('~$')]
for file_item in files_to_process:
full_input_file_path = os.path.join(current_root, file_item)
file_name_lower = file_item.lower()
relative_path_from_input = os.path.relpath(current_root, input_dir)
if relative_path_from_input == '.':
output_sub_directory_path = output_dir
else:
output_sub_directory_path = os.path.join(output_dir, relative_path_from_input)
output_file_name_base = os.path.splitext(file_item)[0]
final_output_pdf_path = os.path.join(output_sub_directory_path, output_file_name_base + ".pdf")
if not os.path.exists(output_sub_directory_path):
try:
os.makedirs(output_sub_directory_path)
logging.info(f"出力サブフォルダ作成: {output_sub_directory_path}")
except OSError as e_makedirs:
logging.error(f"出力サブフォルダ作成失敗 ({output_sub_directory_path}): {e_makedirs}")
failed_files += 1
continue
if file_name_lower.endswith(('.xlsx', '.xls', '.xlsm')):
if excel_app:
if convert_excel_to_pdf(excel_app, full_input_file_path, final_output_pdf_path):
converted_files += 1
else:
failed_files += 1
else:
logging.warning(f"Excelアプリケーションが利用できないため、スキップ: {full_input_file_path}")
failed_files +=1
elif file_name_lower.endswith(('.pptx', '.ppt', '.pptm')):
if ppt_app:
if convert_ppt_to_pdf(ppt_app, full_input_file_path, final_output_pdf_path):
converted_files += 1
else:
failed_files += 1
else:
logging.warning(f"PowerPointアプリケーションが利用できないため、スキップ: {full_input_file_path}")
failed_files += 1
logging.info(f"変換成功: {converted_files} ファイル, 変換失敗: {failed_files} ファイル")
print(f"処理完了。変換成功: {converted_files} ファイル, 変換失敗: {failed_files} ファイル")
if failed_files > 0:
print(f"詳細はログファイル ({log_file_path}) を確認してください。")
except Exception as e_main:
logging.critical(f"予期せぬエラーが発生しました: {e_main}", exc_info=True)
print(f"予期せぬエラーが発生しました: {e_main}")
finally:
if excel_app:
try:
excel_app.Quit()
except Exception as e_excel_quit:
logging.error(f"Excelアプリケーションの終了中にエラー: {e_excel_quit}")
if ppt_app:
try:
ppt_app.Quit()
except Exception as e_ppt_quit:
logging.error(f"PowerPointアプリケーションの終了中にエラー: {e_ppt_quit}")
if com_initialized_here:
pythoncom.CoUninitialize()
logging.info("処理終了")
if __name__ == "__main__":
main_process()スクリプトの使い方
- 保存: 上記のコードをテキストエディタ(VSCode、メモ帳など)にコピーし、ファイル名を例えば office_to_pdf_converter.py として保存します。
- 実行: コマンドプロンプトを開き、保存したファイルがあるディレクトリに移動して、以下のコマンドでスクリプトを実行します。
python office_to_pdf_converter.py- フォルダ選択:
- 最初に「変換元のOfficeファイルが含まれるフォルダを選択してください」というダイアログが表示されるので、PDFにしたいOfficeファイルが格納されている親フォルダを選択します。
- 次に「PDFファイルの出力先フォルダを選択してください」というダイアログが表示されるので、変換後のPDFファイルを保存したいフォルダを選択します。
- 処理実行: 選択後、自動的に変換処理が開始されます。コンソールに進捗(入力・出力フォルダ、ファイル数など)が表示されます。
- ログ確認: 処理完了後、スクリプトと同じ場所に conversion_log.log というログファイルが生成されます。エラーが発生した場合は、このファイルで詳細を確認できます。
スクリプトのポイント解説
このスクリプトは、いくつかのPython標準ライブラリとpywin32ライブラリを組み合わせて実現されています。
- osモジュール: ファイルやフォルダのパスを扱ったり(os.path.join, os.path.splitext, os.path.relpath)、フォルダ内を探索したり(os.walk)、フォルダを作成したり(os.makedirs)するために使用しています。フォルダ構造を維持する上で中心的な役割を果たします。
- tkinterモジュール: Python標準のGUIライブラリです。filedialogを使って、ユーザーが直感的にフォルダを選択できるようにしています。
- win32com.client (pywin32の一部): WindowsのCOM (Component Object Model) を介して、ExcelやPowerPointといったOfficeアプリケーションをPythonから操作するための強力なライブラリです。ファイルの開封、PDF形式での保存、アプリケーションの終了などを行います。
- loggingモジュール: 処理の記録やエラー発生時の情報をファイルに出力するために使用します。問題発生時の原因究明に役立ちます。
- pythoncom (pywin32の一部): COMライブラリの初期化 (CoInitializeEx) と解放 (CoUninitialize) を行い、スクリプトがOfficeアプリケーションと正しく連携できるようにします。特に、スレッドに関連する設定 (COINIT_APARTMENTTHREADED) は、Officeオートメーションで重要です。
- フォルダ構造の維持: os.walkで入力フォルダを再帰的に探索し、os.path.relpathで入力ルートからの相対パスを取得。これを元に出力先のサブフォルダパスを構築し、os.makedirsで必要に応じてフォルダを作成することで、元の構造を正確に再現しています。
ご利用にあたっての注意点
- このスクリプトはWindows環境専用です。
- Microsoft Office (Excel, PowerPoint) がPCにインストールされている必要があります。
- パスワードで保護されたファイルや、破損しているファイルは正常に変換できない場合があります。これらのエラーはログに出力されます。
- 処理するファイル数が多い場合や、ファイルサイズが大きい場合は、変換に時間がかかることがあります。
- スクリプト実行中は、Officeアプリケーション(ExcelやPowerPoint)を手動で操作しないでください。予期せぬ動作の原因となる可能性があります。
まとめ|OfficeファイルのPDF変換を自動化して業務効率をアップ!
このPythonスクリプトを使えば、面倒なOfficeファイルのPDF変換作業とフォルダ整理から解放され、大幅な時間短縮とミスの削減が期待できます。手作業に追われる日々から一歩踏み出し、自動化の力で業務効率を向上させましょう!
今回のスクリプトはExcelとPowerPointに対応していますが、少し変更を加えることでWord文書(.docx, .doc)の変換に対応させることも可能です。ぜひ、ご自身の業務に合わせてカスタマイズしてみてください。
この情報が、あなたの業務改善の一助となれば幸いです。ぜひお試しいただき、ご意見や改善点などあればコメントでお知らせください!

