🐱
yaml形式のパラメータシートをExcelに変換するpythonスクリプト(ChatGPT製)
概要
例えばEC2のパラメータを以下のようにyaml形式で作成したとする。
webサーバ:
概要:
インスタンス名: web-server-01
インスタンスID: 自動生成
OSイメージ:
AMI: ami-xxxxxxxxxxxx
高度なネットワーク設定:
ネットワークインターフェース1:
サブネット: web-server-subnet-1a
セキュリティグループ: web-server-secg-01
プライマリIP: 172.16.xx.xx
~略~
---
appサーバ:
概要:
インスタンス名: app-server-01
インスタンスID: 自動生成
OSイメージ:
AMI: ami-xxxxxxxxxxxx
高度なネットワーク設定:
ネットワークインターフェース1:
サブネット: app-server-subnet-1a
セキュリティグループ: app-server-secg-01
プライマリIP: 172.16.xx.xx
~略~
世に数多あるExcel形式のパラメータシートは修正時の変更差分を見るのに苦労するが(セルの色を変える、目grepなど)、
yaml形式であればgit管理でプルリクなり、VScodeの機能なり、何ならWinMergeなどで変更差分を一発でバシッと簡単に見ることができるので、レビューの負担が下がる。
ただし、yaml形式のままだと納品時などで都合が悪いので、Excel形式に変換する。
yamlファイル内で---のセパレータで区切るとシートを分けて作成される。
セルはすべて左揃え、格子をかけた状態で作成される。
python xxxxx.py yyyyy.yaml
の形で実行する。
Excelファイルはyamlファイルと同じ名前で作成される。
コード
import yaml
from openpyxl import Workbook
from openpyxl.styles import PatternFill, Border, Side, Alignment
import sys
import os
def yaml_to_excel(input_file, output_file):
with open(input_file, 'r', encoding='utf-8') as f:
documents = list(yaml.safe_load_all(f))
workbook = Workbook()
workbook.remove(workbook.active) # Remove default sheet
def max_depth(d, depth=0):
"""Returns the maximum depth of a dictionary."""
if not isinstance(d, dict):
return depth
return max(max_depth(v, depth + 1) for v in d.values())
depth = max(max_depth(doc) for doc in documents)
def write_data(d, sheet, start_row=2, start_col=1):
"""Writes the data recursively into the Excel sheet."""
row = start_row
for key, value in d.items():
if isinstance(value, dict):
cell = sheet.cell(row=row, column=start_col, value=key)
cell.alignment = Alignment(horizontal="left")
row = write_data(value, sheet, row, start_col + 1)
else:
key_cell = sheet.cell(row=row, column=start_col, value=key)
value_cell = sheet.cell(row=row, column=depth, value=value)
key_cell.alignment = Alignment(horizontal="left")
value_cell.alignment = Alignment(horizontal="left")
row += 1
return row
for content in documents:
for sheet_name, data in content.items():
current_sheet = workbook.create_sheet(title=sheet_name)
current_sheet.cell(row=1, column=1, value="設定項目").alignment = Alignment(horizontal="left")
current_sheet.cell(row=1, column=depth, value="設定値").alignment = Alignment(horizontal="left")
# Fill cells with light blue color
blue_fill = PatternFill(start_color="D9EBF5", end_color="D9EBF5", fill_type="solid")
for col in range(1, depth + 1):
current_sheet.cell(row=1, column=col).fill = blue_fill
write_data(data, current_sheet)
# Adding borders and adjusting the width of the columns
thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin'))
for sheet in workbook.worksheets:
for row in sheet.iter_rows():
for cell in row:
cell.border = thin_border
for column in sheet.columns:
max_length = 0
column = [cell for cell in column]
for cell in column:
try:
if len(str(cell.value)) > max_length:
max_length = len(str(cell.value))
except:
pass
# adding some extra padding and a correction factor for width
adjusted_width = (max_length + 8) * 1.4
sheet.column_dimensions[column[0].column_letter].width = adjusted_width
workbook.save(output_file)
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python script_name.py <input_yaml_file>")
sys.exit(1)
input_filename = sys.argv[1]
output_filename = os.path.splitext(input_filename)[0] + '.xlsx'
yaml_to_excel(input_filename, output_filename)
生成されたExcelファイルのイメージ
感想
- ChatGPTスゴイ(語彙力)
- クリーンなコードにするとかエラーハンドリングとかはあまり考慮してません
Discussion