Pythonを使ったカスタムExcelレポートの生成:完全ガイド
Excelレポートの自動生成や視認性を高めるために、Pythonは強力なライブラリ群を提供しています。その中でもOpenPyXLとPillowは、動的なデータでテンプレートを埋め、Excelレポートをカスタマイズする際に役立ちます。この投稿では、Pythonスクリプトを活用してカスタムExcelレポートを生成する方法について解説します。このソリューションは、頻繁にExcelファイルを扱う企業や開発者に特に役立ちます。
このスクリプトの機能とは?
このPythonスクリプトは以下を目的としています:
- Excelテンプレートの読み込みと動的データの埋め込み。
- テキスト、画像、チェックボックスのカスタマイズ。
- 条件に基づく行の非表示またはグループ化。
- 画像のリサイズと配置、特定セル内での中央配置を含む。
- タイムスタンプ付きの新しいExcelファイルとしてエクスポート。
それでは、スクリプトを見ていきましょう。
完全なコード
以下はカスタムExcelレポートを生成するための完全なスクリプトです:
from openpyxl import load_workbook, Workbook
from datetime import datetime
from openpyxl.drawing.image import Image
import re
from openpyxl.drawing.spreadsheet_drawing import AbsoluteAnchor
from openpyxl.drawing.xdr import XDRPoint2D, XDRPositiveSize2D
from openpyxl.utils.units import pixels_to_EMU
from openpyxl.utils import get_column_letter, column_index_from_string
from django.conf import settings
from PIL import Image as PILImage
import os
def set_image_with_offset(sheet, img, cell_coordinate, offset_x=0, offset_y=0):
col_letter = ''.join(filter(str.isalpha, cell_coordinate)) # 列文字を抽出
row_number = int(''.join(filter(str.isdigit, cell_coordinate))) # 行番号を抽出
col_idx = column_index_from_string(col_letter) - 1
row_idx = row_number - 1
col_width = sheet.column_dimensions[col_letter].width or 10 # デフォルトの列幅
row_height = sheet.row_dimensions[row_number].height or 15 # デフォルトの行高さ
col_pixels = col_width * 7.5 # 1列幅単位 ≈ 7.5ピクセル
row_pixels = row_height * 0.75 # 1行高さ単位 ≈ 0.75ピクセル
cell_x = col_idx * col_pixels
cell_y = row_idx * row_pixels
final_x = cell_x + offset_x
final_y = cell_y + offset_y
pos = XDRPoint2D(pixels_to_EMU(final_x), pixels_to_EMU(final_y))
size = XDRPositiveSize2D(pixels_to_EMU(img.width), pixels_to_EMU(img.height))
img.anchor = AbsoluteAnchor(pos=pos, ext=size)
sheet.add_image(img)
def center_image_in_cell(sheet, img, cell_coordinate):
col_letter = ''.join(filter(str.isalpha, cell_coordinate))
row_number = int(''.join(filter(str.isdigit, cell_coordinate)))
col_width = sheet.column_dimensions[col_letter].width or 10
row_height = sheet.row_dimensions[row_number].height or 15
col_pixels = col_width * 7.5
row_pixels = row_height * 0.75
img_width, img_height = img.width, img.height
offset_x = int((col_pixels - img_width) / 2 * pixels_to_EMU(1))
offset_y = int((row_pixels - img_height) / 2 * pixels_to_EMU(1))
img.anchor = AbsoluteAnchor(
pos=XDRPoint2D(pixels_to_EMU(offset_x), pixels_to_EMU(offset_y)),
ext=XDRPositiveSize2D(pixels_to_EMU(img_width), pixels_to_EMU(img_height)),
)
sheet.add_image(img)
def gen_xlsx(template_file, selected_sheets, prefix_filename, data):
checked_image_path = f"{settings.BASE_DIR}/report/checkbox_checked.jpg"
unchecked_image_path = f"{settings.BASE_DIR}/report/checkbox_unchecked.jpg"
workbook = load_workbook(template_file)
for sheet_name in workbook.sheetnames:
if sheet_name not in selected_sheets:
del workbook[sheet_name]
for sheet_name in selected_sheets:
sheet = workbook[sheet_name]
for row in sheet.iter_rows():
for cell in row:
if cell.value and isinstance(cell.value, str) and cell.value.startswith("<") and cell.value.endswith(">"):
placeholder = cell.value.strip("<>")
value = data.get(placeholder)
if isinstance(value, str):
cell.value = value
elif isinstance(value, bool):
img = Image(checked_image_path if value else unchecked_image_path)
center_image_in_cell(sheet, img, cell.coordinate)
cell.value = None
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_path = f"{prefix_filename}_{timestamp}.xlsx"
workbook.save(output_path)
return output_path
if __name__ == "__main__":
data = {
"customer": "佐藤 太郎",
"inspect_date": "2025-02-01",
"lot_no": "LOT12345",
"staff_name": "検査チーム",
"size": "中型",
"pcs": "30個",
"hardness.d1_act": "12.5",
"hardness.acc": True,
"hardness.spe_acc": False,
"dimension_app.d1_act": "45.8",
"dimension_app.acc": True,
"dimension_app.spe_acc": True,
}
output_file = gen_xlsx(
template_file="./inspection_template.xlsx",
selected_sheets=["hardness", "dimensions"],
prefix_filename="./reports/inspection_report",
data=data,
)
print(f"生成されたファイル: {output_file}")
デモデータの説明
- 顧客情報:名前、検査日、ロット番号などの一般情報を含みます。
- 測定結果と判定:セルごとに動的なデータを入力します。数値やチェックボックスの真偽値を扱います。
- チェックボックスロジック:例えば
"hardness.acc": True
は、チェック済み画像を挿入します。
スクリプトの使用方法
<customer>
や<inspect_date>
などのプレースホルダーを含むExcelテンプレートを用意します。- データ辞書で、プレースホルダーに対応するキーと値を定義します。
gen_xlsx
関数を呼び出し、テンプレートファイル、シート名、出力ファイルのプレフィックス、およびデータ辞書を指定します。- スクリプトを実行し、カスタマイズされたExcelファイルを生成します。
まとめ
このスクリプトは、Excelレポートの生成を効率化するための強力なツールです。検査レポートや財務報告書など、さまざまな用途に応じてカスタマイズ可能です。ぜひこのスクリプトを活用して、Excelの自動化と効率化を体験してください! 🚀
Related Posts
- Djangoでの耐障害性ソフトウェア設計
- การออกแบบซอฟต์แวร์ที่ทนต่อความล้มเหลวด้วย Django
- Designing Fault-Tolerant Software with Django
- アウトプットの力:優れたプログラマーになるための方法
- พลังของการลงมือทำ: วิธีพัฒนาตัวเองให้เป็นโปรแกรมเมอร์ที่เก่งขึ้น
- The Power of Output: How to Become a Better Programmer
- 提高 Django 性能:开发者和企业主的缓存指南
- Django のパフォーマンス向上: 開発者とビジネスオーナーのためのキャッシュガイド
- ปรับปรุงประสิทธิภาพของ Django: คู่มือแคชสำหรับนักพัฒนาและเจ้าของธุรกิจ
- Boost Your Django Performance: A Guide to Caching for Developers and Business Owners
Articles
- OCR Document Managerのご紹介:書類を簡単にテキスト化できるWebアプリ
- แนะนำ OCR Document Manager: แปลงเอกสารเป็นข้อความได้ง่ายๆ บนเว็บ
- Introducing OCR Document Manager: Extract Text from Documents with Ease
- ผมกำลังทดสอบเครื่องมือ AI ที่ช่วยหาสินค้ามาแรงก่อนใคร — คุณสนใจไหม?
- まだバズっていない「売れ筋商品」をAIで発見するツールを作っています ― 興味ありますか?
- Testing an AI Tool That Finds Winning Products Before They Trend — Interested?
- あなたのウェブサイトがリードを失っている理由 — それは「沈黙」です
- เว็บไซต์ของคุณกำลังเสียโอกาส — เพราะมัน "เงียบเกินไป"
- Your Website Is Losing Leads After Hours — Here’s the Fix
- スマート農業を革新するAgentic AIとは?あなたの農場が今すぐ導入すべき理由
- Agentic AI คืออะไร? ทำไมฟาร์มของคุณถึงควรใช้ตั้งแต่วันนี้
- How Agentic AI is Revolutionizing Smart Farming — And Why Your Farm Needs It Now
- LangChain + Ollama で RAGチャットボットを作る方法
- How to Apply RAG Chatbot with LangChain + Ollama
- วิธีสร้าง RAG Chatbot ด้วย LangChain + Ollama
- การใช้งาน SCPI กับอุปกรณ์ EXFO: คู่มือฉบับใช้งานจริง
- SCPI を使った EXFO 機器の自動化:実践ガイド
- Automating EXFO Instruments with SCPI: A Practical Guide
- レガシーコードを扱いやすくするためのデザインパターン
- Design Patterns ที่ช่วยให้จัดการ Legacy Code ได้ง่ายขึ้น
Our Products
Related Posts
- Djangoでの耐障害性ソフトウェア設計
- การออกแบบซอฟต์แวร์ที่ทนต่อความล้มเหลวด้วย Django
- Designing Fault-Tolerant Software with Django
- アウトプットの力:優れたプログラマーになるための方法
- พลังของการลงมือทำ: วิธีพัฒนาตัวเองให้เป็นโปรแกรมเมอร์ที่เก่งขึ้น
- The Power of Output: How to Become a Better Programmer
- 提高 Django 性能:开发者和企业主的缓存指南
- Django のパフォーマンス向上: 開発者とビジネスオーナーのためのキャッシュガイド
- ปรับปรุงประสิทธิภาพของ Django: คู่มือแคชสำหรับนักพัฒนาและเจ้าของธุรกิจ
- Boost Your Django Performance: A Guide to Caching for Developers and Business Owners
Articles
- OCR Document Managerのご紹介:書類を簡単にテキスト化できるWebアプリ
- แนะนำ OCR Document Manager: แปลงเอกสารเป็นข้อความได้ง่ายๆ บนเว็บ
- Introducing OCR Document Manager: Extract Text from Documents with Ease
- ผมกำลังทดสอบเครื่องมือ AI ที่ช่วยหาสินค้ามาแรงก่อนใคร — คุณสนใจไหม?
- まだバズっていない「売れ筋商品」をAIで発見するツールを作っています ― 興味ありますか?
- Testing an AI Tool That Finds Winning Products Before They Trend — Interested?
- あなたのウェブサイトがリードを失っている理由 — それは「沈黙」です
- เว็บไซต์ของคุณกำลังเสียโอกาส — เพราะมัน "เงียบเกินไป"
- Your Website Is Losing Leads After Hours — Here’s the Fix
- スマート農業を革新するAgentic AIとは?あなたの農場が今すぐ導入すべき理由
- Agentic AI คืออะไร? ทำไมฟาร์มของคุณถึงควรใช้ตั้งแต่วันนี้
- How Agentic AI is Revolutionizing Smart Farming — And Why Your Farm Needs It Now
- LangChain + Ollama で RAGチャットボットを作る方法
- How to Apply RAG Chatbot with LangChain + Ollama
- วิธีสร้าง RAG Chatbot ด้วย LangChain + Ollama
- การใช้งาน SCPI กับอุปกรณ์ EXFO: คู่มือฉบับใช้งานจริง
- SCPI を使った EXFO 機器の自動化:実践ガイド
- Automating EXFO Instruments with SCPI: A Practical Guide
- レガシーコードを扱いやすくするためのデザインパターン
- Design Patterns ที่ช่วยให้จัดการ Legacy Code ได้ง่ายขึ้น