Passer au contenu principal

์—‘์…€ ์ž๋™ํ™”

Python์˜ openpyxl ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Excel ํŒŒ์ผ์„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ  ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ณต์ ์ธ ๋ฐ์ดํ„ฐ ์ž…๋ ฅ, ๋ณด๊ณ ์„œ ์ƒ์„ฑ, ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋“ฑ์„ ์ž๋™ํ™”ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์„ค์น˜ํ•˜๊ธฐโ€‹

# openpyxl ์„ค์น˜
pip install openpyxl

# ์ฐจํŠธ ๊ธฐ๋Šฅ๊นŒ์ง€ ์‚ฌ์šฉํ•˜๋ ค๋ฉด
pip install openpyxl[charts]

๊ธฐ๋ณธ ์ž‘์—…โ€‹

์›Œํฌ๋ถ ์ƒ์„ฑ ๋ฐ ์ €์žฅโ€‹

from openpyxl import Workbook

# ์ƒˆ ์›Œํฌ๋ถ ์ƒ์„ฑ
wb = Workbook()

# ํ™œ์„ฑ ์‹œํŠธ ๊ฐ€์ ธ์˜ค๊ธฐ
ws = wb.active

# ์‹œํŠธ ์ด๋ฆ„ ๋ณ€๊ฒฝ
ws.title = "๋งค์ถœ ๋ฐ์ดํ„ฐ"

# ์…€์— ๊ฐ’ ์“ฐ๊ธฐ
ws['A1'] = "์•ˆ๋…•ํ•˜์„ธ์š”"
ws['B1'] = 42
ws['C1'] = 3.14

# ํŒŒ์ผ ์ €์žฅ
wb.save('example.xlsx')

๊ธฐ์กด ํŒŒ์ผ ์ฝ๊ธฐโ€‹

from openpyxl import load_workbook

# ์—‘์…€ ํŒŒ์ผ ์—ด๊ธฐ
wb = load_workbook('example.xlsx')

# ์‹œํŠธ ์ด๋ฆ„ ๋ชฉ๋ก
print(wb.sheetnames) # ['๋งค์ถœ ๋ฐ์ดํ„ฐ', 'Sheet2']

# ํŠน์ • ์‹œํŠธ ์„ ํƒ
ws = wb['๋งค์ถœ ๋ฐ์ดํ„ฐ']

# ๋˜๋Š” ํ™œ์„ฑ ์‹œํŠธ
ws = wb.active

# ์…€ ๊ฐ’ ์ฝ๊ธฐ
value = ws['A1'].value
print(value)

์…€ ๋‹ค๋ฃจ๊ธฐโ€‹

์…€ ์ ‘๊ทผ ๋ฐฉ๋ฒ•โ€‹

# ๋ฐฉ๋ฒ• 1: ์…€ ์ขŒํ‘œ ์‚ฌ์šฉ
ws['A1'] = "์ด๋ฆ„"

# ๋ฐฉ๋ฒ• 2: row, column ์ธ๋ฑ์Šค ์‚ฌ์šฉ (1๋ถ€ํ„ฐ ์‹œ์ž‘)
ws.cell(row=1, column=1).value = "์ด๋ฆ„"
ws.cell(row=1, column=2).value = "๋‚˜์ด"

# ์…€ ๊ฐ’ ์ฝ๊ธฐ
name = ws['A1'].value
age = ws.cell(row=1, column=2).value

์—ฌ๋Ÿฌ ์…€์— ๋ฐ์ดํ„ฐ ์“ฐ๊ธฐโ€‹

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# ํ–‰ ๋‹จ์œ„๋กœ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€
data = [
["์ด๋ฆ„", "๋‚˜์ด", "์ง์—…"],
["๊น€์ฒ ์ˆ˜", 30, "๊ฐœ๋ฐœ์ž"],
["์ด์˜ํฌ", 28, "๋””์ž์ด๋„ˆ"],
["๋ฐ•๋ฏผ์ˆ˜", 35, "๊ธฐํš์ž"]
]

for row in data:
ws.append(row)

wb.save('์ง์›๋ช…๋‹จ.xlsx')

๋ฒ”์œ„๋กœ ์…€ ์ฝ๊ธฐโ€‹

# ํŠน์ • ๋ฒ”์œ„ ์ฝ๊ธฐ
for row in ws['A1:C4']:
for cell in row:
print(cell.value, end='\t')
print()

# ๋ชจ๋“  ํ–‰ ์ˆœํšŒ
for row in ws.iter_rows(min_row=2, values_only=True):
print(row)

# ๋ชจ๋“  ์—ด ์ˆœํšŒ
for col in ws.iter_cols(min_col=1, max_col=3, values_only=True):
print(col)

# ํŠน์ • ๋ฒ”์œ„์˜ ๊ฐ’๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ
for row in ws.iter_rows(min_row=2, max_row=5, min_col=1, max_col=3, values_only=True):
name, age, job = row
print(f"{name}: {age}์„ธ, {job}")

์…€ ์Šคํƒ€์ผ๋งโ€‹

ํฐํŠธ ์Šคํƒ€์ผโ€‹

from openpyxl.styles import Font

# ๊ตต๊ฒŒ, ํฌ๊ธฐ, ์ƒ‰์ƒ
ws['A1'].font = Font(
name='๋ง‘์€ ๊ณ ๋”•',
size=14,
bold=True,
italic=False,
color='FF0000' # ๋นจ๊ฐ„์ƒ‰ (RGB ํ—ฅ์Šค)
)

์…€ ๋ฐฐ๊ฒฝ์ƒ‰โ€‹

from openpyxl.styles import PatternFill

# ๋ฐฐ๊ฒฝ์ƒ‰ ์ฑ„์šฐ๊ธฐ
ws['A1'].fill = PatternFill(
start_color='FFFF00', # ๋…ธ๋ž€์ƒ‰
end_color='FFFF00',
fill_type='solid'
)

ํ…Œ๋‘๋ฆฌโ€‹

from openpyxl.styles import Border, Side

# ํ…Œ๋‘๋ฆฌ ์Šคํƒ€์ผ
thin_border = Border(
left=Side(style='thin'),
right=Side(style='thin'),
top=Side(style='thin'),
bottom=Side(style='thin')
)

ws['A1'].border = thin_border

์ •๋ ฌโ€‹

from openpyxl.styles import Alignment

# ๊ฐ€์šด๋ฐ ์ •๋ ฌ
ws['A1'].alignment = Alignment(
horizontal='center',
vertical='center',
wrap_text=True # ํ…์ŠคํŠธ ์ค„๋ฐ”๊ฟˆ
)

์ˆซ์ž ํ˜•์‹โ€‹

# ํ†ตํ™” ํ˜•์‹
ws['B2'].number_format = '#,##0์›'

# ๋ฐฑ๋ถ„์œจ
ws['C2'].number_format = '0.00%'

# ๋‚ ์งœ
ws['D2'].number_format = 'yyyy-mm-dd'

# ์†Œ์ˆ˜์ 
ws['E2'].number_format = '0.00'

์ˆ˜์‹ ์‚ฌ์šฉํ•˜๊ธฐโ€‹

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# ๋ฐ์ดํ„ฐ ์ž…๋ ฅ
ws['A1'] = "์ƒํ’ˆ"
ws['B1'] = "๋‹จ๊ฐ€"
ws['C1'] = "์ˆ˜๋Ÿ‰"
ws['D1'] = "ํ•ฉ๊ณ„"

ws['A2'] = "์‚ฌ๊ณผ"
ws['B2'] = 1000
ws['C2'] = 5

# ์ˆ˜์‹ ์ž…๋ ฅ (B2 * C2)
ws['D2'] = "=B2*C2"

# SUM ํ•จ์ˆ˜
ws['A10'] = "์ดํ•ฉ"
ws['D10'] = "=SUM(D2:D9)"

# ํ‰๊ท 
ws['A11'] = "ํ‰๊ท "
ws['D11'] = "=AVERAGE(D2:D9)"

# IF ํ•จ์ˆ˜
ws['E2'] = "=IF(D2>5000, '๊ณ ๊ฐ€', '์ €๊ฐ€')"

wb.save('์ˆ˜์‹์˜ˆ์ œ.xlsx')

์ฐจํŠธ ๋งŒ๋“ค๊ธฐโ€‹

๋ง‰๋Œ€ ์ฐจํŠธโ€‹

from openpyxl import Workbook
from openpyxl.chart import BarChart, Reference

wb = Workbook()
ws = wb.active

# ๋ฐ์ดํ„ฐ ์ž…๋ ฅ
data = [
["์›”", "๋งค์ถœ"],
["1์›”", 1000],
["2์›”", 1500],
["3์›”", 1200],
["4์›”", 1800],
]

for row in data:
ws.append(row)

# ์ฐจํŠธ ์ƒ์„ฑ
chart = BarChart()
chart.title = "์›”๋ณ„ ๋งค์ถœ"
chart.x_axis.title = "์›”"
chart.y_axis.title = "๋งค์ถœ (๋งŒ์›)"

# ๋ฐ์ดํ„ฐ ๋ฒ”์œ„ ์„ค์ •
data_ref = Reference(ws, min_col=2, min_row=1, max_row=5)
categories = Reference(ws, min_col=1, min_row=2, max_row=5)

chart.add_data(data_ref, titles_from_data=True)
chart.set_categories(categories)

# ์ฐจํŠธ ์ถ”๊ฐ€
ws.add_chart(chart, "D2")

wb.save('์ฐจํŠธ์˜ˆ์ œ.xlsx')

์„  ์ฐจํŠธโ€‹

from openpyxl.chart import LineChart, Reference

# ์„  ์ฐจํŠธ ์ƒ์„ฑ
chart = LineChart()
chart.title = "์ฃผ๊ฐ„ ๋ฐฉ๋ฌธ์ž ์ˆ˜"
chart.style = 10
chart.y_axis.title = '๋ฐฉ๋ฌธ์ž'
chart.x_axis.title = '์š”์ผ'

data_ref = Reference(ws, min_col=2, min_row=1, max_col=3, max_row=8)
chart.add_data(data_ref, titles_from_data=True)

categories = Reference(ws, min_col=1, min_row=2, max_row=8)
chart.set_categories(categories)

ws.add_chart(chart, "E2")

์› ์ฐจํŠธโ€‹

from openpyxl.chart import PieChart, Reference

chart = PieChart()
chart.title = "ํŒ๋งค ๋น„์œจ"

data_ref = Reference(ws, min_col=2, min_row=1, max_row=5)
labels = Reference(ws, min_col=1, min_row=2, max_row=5)

chart.add_data(data_ref, titles_from_data=True)
chart.set_categories(labels)

ws.add_chart(chart, "D2")

์‹ค์ „ ์˜ˆ์ œโ€‹

1. ์ž๋™ ๋งค์ถœ ๋ณด๊ณ ์„œ ์ƒ์„ฑโ€‹

from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.chart import BarChart, Reference
from datetime import datetime

def create_sales_report(sales_data, filename):
"""๋งค์ถœ ๋ณด๊ณ ์„œ ์ž๋™ ์ƒ์„ฑ"""

wb = Workbook()
ws = wb.active
ws.title = "๋งค์ถœ ํ˜„ํ™ฉ"

# ์ œ๋ชฉ
ws['A1'] = "์›”๊ฐ„ ๋งค์ถœ ๋ณด๊ณ ์„œ"
ws['A1'].font = Font(size=16, bold=True)
ws['A1'].alignment = Alignment(horizontal='center')
ws.merge_cells('A1:E1')

# ์ž‘์„ฑ์ผ
ws['A2'] = f"์ž‘์„ฑ์ผ: {datetime.now().strftime('%Y-%m-%d')}"

# ํ—ค๋”
headers = ["์ œํ’ˆ๋ช…", "ํŒ๋งค์ˆ˜๋Ÿ‰", "๋‹จ๊ฐ€", "๋งค์ถœ์•ก", "๋น„๊ณ "]
ws.append([]) # ๋นˆ ํ–‰
ws.append(headers)

# ํ—ค๋” ์Šคํƒ€์ผ
header_fill = PatternFill(start_color='4472C4', end_color='4472C4', fill_type='solid')
header_font = Font(color='FFFFFF', bold=True)

for col in range(1, 6):
cell = ws.cell(row=4, column=col)
cell.fill = header_fill
cell.font = header_font
cell.alignment = Alignment(horizontal='center')

# ๋ฐ์ดํ„ฐ ์ž…๋ ฅ
total_sales = 0
for item in sales_data:
product, quantity, price = item
sales = quantity * price
total_sales += sales

remark = "๋ชฉํ‘œ๋‹ฌ์„ฑ" if sales >= 1000000 else "๋…ธ๋ ฅํ•„์š”"

ws.append([product, quantity, price, sales, remark])

# ๋ฐ์ดํ„ฐ ์Šคํƒ€์ผ
thin_border = Border(
left=Side(style='thin'),
right=Side(style='thin'),
top=Side(style='thin'),
bottom=Side(style='thin')
)

for row in ws.iter_rows(min_row=4, max_row=ws.max_row, min_col=1, max_col=5):
for cell in row:
cell.border = thin_border
cell.alignment = Alignment(horizontal='center')

# ์ˆซ์ž ํ˜•์‹
for row in range(5, ws.max_row + 1):
ws.cell(row=row, column=2).number_format = '#,##0' # ์ˆ˜๋Ÿ‰
ws.cell(row=row, column=3).number_format = '#,##0์›' # ๋‹จ๊ฐ€
ws.cell(row=row, column=4).number_format = '#,##0์›' # ๋งค์ถœ์•ก

# ํ•ฉ๊ณ„ ํ–‰
total_row = ws.max_row + 1
ws.cell(row=total_row, column=1).value = "์ด ๋งค์ถœ"
ws.cell(row=total_row, column=4).value = f"=SUM(D5:D{ws.max_row})"
ws.cell(row=total_row, column=1).font = Font(bold=True)
ws.cell(row=total_row, column=4).font = Font(bold=True)
ws.cell(row=total_row, column=4).fill = PatternFill(
start_color='FFC000', end_color='FFC000', fill_type='solid'
)

# ์ฐจํŠธ ์ถ”๊ฐ€
chart = BarChart()
chart.title = "์ œํ’ˆ๋ณ„ ๋งค์ถœ ํ˜„ํ™ฉ"
chart.y_axis.title = '๋งค์ถœ์•ก (์›)'

data_ref = Reference(ws, min_col=4, min_row=4, max_row=ws.max_row - 1)
categories = Reference(ws, min_col=1, min_row=5, max_row=ws.max_row - 1)

chart.add_data(data_ref, titles_from_data=True)
chart.set_categories(categories)

ws.add_chart(chart, "G4")

# ์—ด ๋„ˆ๋น„ ์กฐ์ •
ws.column_dimensions['A'].width = 15
ws.column_dimensions['B'].width = 12
ws.column_dimensions['C'].width = 12
ws.column_dimensions['D'].width = 15
ws.column_dimensions['E'].width = 12

wb.save(filename)
print(f"๋ณด๊ณ ์„œ ์ƒ์„ฑ ์™„๋ฃŒ: {filename}")

# ์‚ฌ์šฉ ์˜ˆ์ œ
sales_data = [
("๋…ธํŠธ๋ถ", 15, 1200000),
("๋งˆ์šฐ์Šค", 50, 25000),
("ํ‚ค๋ณด๋“œ", 30, 80000),
("๋ชจ๋‹ˆํ„ฐ", 20, 350000),
("ํ—ค๋“œ์…‹", 25, 120000)
]

create_sales_report(sales_data, "๋งค์ถœ๋ณด๊ณ ์„œ.xlsx")

2. ์—ฌ๋Ÿฌ ์—‘์…€ ํŒŒ์ผ ํ†ตํ•ฉโ€‹

from openpyxl import Workbook, load_workbook
import os

def merge_excel_files(folder_path, output_file):
"""์—ฌ๋Ÿฌ ์—‘์…€ ํŒŒ์ผ์„ ํ•˜๋‚˜๋กœ ํ†ตํ•ฉ"""

wb_output = Workbook()
ws_output = wb_output.active
ws_output.title = "ํ†ตํ•ฉ ๋ฐ์ดํ„ฐ"

# ํ—ค๋”๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ ํ”Œ๋ž˜๊ทธ
header_written = False

# ํด๋” ๋‚ด ๋ชจ๋“  ์—‘์…€ ํŒŒ์ผ ์ฒ˜๋ฆฌ
for filename in os.listdir(folder_path):
if not filename.endswith(('.xlsx', '.xls')):
continue

file_path = os.path.join(folder_path, filename)
print(f"์ฒ˜๋ฆฌ ์ค‘: {filename}")

try:
wb = load_workbook(file_path)
ws = wb.active

# ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ
for i, row in enumerate(ws.iter_rows(values_only=True), 1):
# ์ฒซ ๋ฒˆ์งธ ํŒŒ์ผ์˜ ํ—ค๋”๋งŒ ํฌํ•จ
if i == 1:
if not header_written:
ws_output.append(row)
header_written = True
else:
ws_output.append(row)

except Exception as e:
print(f"์˜ค๋ฅ˜ ({filename}): {e}")

wb_output.save(output_file)
print(f"\nํ†ตํ•ฉ ์™„๋ฃŒ: {output_file}")
print(f"์ด ํ–‰ ์ˆ˜: {ws_output.max_row}")

# ์‚ฌ์šฉ ์˜ˆ์ œ
merge_excel_files('/Users/username/๋ถ„๊ธฐ๋ณ„๋ฐ์ดํ„ฐ', 'ํ†ตํ•ฉ๋ฐ์ดํ„ฐ.xlsx')

3. ์†ก์žฅ ์ž๋™ ์ƒ์„ฑโ€‹

from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, Border, Side
from datetime import datetime

def create_invoice(invoice_data, filename):
"""์†ก์žฅ ์ž๋™ ์ƒ์„ฑ"""

wb = Workbook()
ws = wb.active

# ํšŒ์‚ฌ ์ •๋ณด
ws['A1'] = "์ฃผ์‹ํšŒ์‚ฌ ํ…Œํฌ์†”๋ฃจ์…˜"
ws['A1'].font = Font(size=18, bold=True)

ws['A2'] = "์„œ์šธ์‹œ ๊ฐ•๋‚จ๊ตฌ ํ…Œํ—ค๋ž€๋กœ 123"
ws['A3'] = "Tel: 02-1234-5678"
ws['A4'] = "์‚ฌ์—…์ž๋ฒˆํ˜ธ: 123-45-67890"

# ์†ก์žฅ ์ œ๋ชฉ
ws['A6'] = "๊ฑฐ ๋ž˜ ๋ช… ์„ธ ์„œ"
ws['A6'].font = Font(size=16, bold=True)
ws['A6'].alignment = Alignment(horizontal='center')
ws.merge_cells('A6:F6')

# ๊ณ ๊ฐ ์ •๋ณด
ws['A8'] = "๋ฐ›๋Š” ๋ถ„:"
ws['B8'] = invoice_data['customer_name']
ws['A9'] = "๋‚ ์งœ:"
ws['B9'] = datetime.now().strftime('%Y๋…„ %m์›” %d์ผ')
ws['A10'] = "์†ก์žฅ๋ฒˆํ˜ธ:"
ws['B10'] = invoice_data['invoice_number']

# ํ…Œ์ด๋ธ” ํ—ค๋”
headers = ["๋ฒˆํ˜ธ", "ํ’ˆ๋ชฉ", "์ˆ˜๋Ÿ‰", "๋‹จ๊ฐ€", "๊ธˆ์•ก", "๋น„๊ณ "]
ws.append([]) # ๋นˆ ํ–‰
ws.append(headers)

# ํ—ค๋” ์Šคํƒ€์ผ
header_row = 12
for col in range(1, 7):
cell = ws.cell(row=header_row, column=col)
cell.font = Font(bold=True)
cell.alignment = Alignment(horizontal='center')

# ํ’ˆ๋ชฉ ๋ฐ์ดํ„ฐ
total = 0
for i, item in enumerate(invoice_data['items'], 1):
product, quantity, price, note = item
amount = quantity * price
total += amount

ws.append([i, product, quantity, price, amount, note])

# ์ˆซ์ž ํ˜•์‹
row = ws.max_row
ws.cell(row=row, column=3).number_format = '#,##0'
ws.cell(row=row, column=4).number_format = '#,##0์›'
ws.cell(row=row, column=5).number_format = '#,##0์›'

# ํ…Œ๋‘๋ฆฌ
thin_border = Border(
left=Side(style='thin'),
right=Side(style='thin'),
top=Side(style='thin'),
bottom=Side(style='thin')
)

for row in ws.iter_rows(min_row=12, max_row=ws.max_row, min_col=1, max_col=6):
for cell in row:
cell.border = thin_border
cell.alignment = Alignment(horizontal='center')

# ํ•ฉ๊ณ„
ws.append([])
total_row = ws.max_row + 1
ws.cell(row=total_row, column=4).value = "ํ•ฉ๊ณ„"
ws.cell(row=total_row, column=5).value = total
ws.cell(row=total_row, column=4).font = Font(bold=True, size=12)
ws.cell(row=total_row, column=5).font = Font(bold=True, size=12)
ws.cell(row=total_row, column=5).number_format = '#,##0์›'

# VAT (10%)
vat_row = total_row + 1
vat = total * 0.1
ws.cell(row=vat_row, column=4).value = "VAT (10%)"
ws.cell(row=vat_row, column=5).value = vat
ws.cell(row=vat_row, column=5).number_format = '#,##0์›'

# ์ด์•ก
grand_total_row = vat_row + 1
ws.cell(row=grand_total_row, column=4).value = "์ด์•ก"
ws.cell(row=grand_total_row, column=5).value = total + vat
ws.cell(row=grand_total_row, column=4).font = Font(bold=True, size=14)
ws.cell(row=grand_total_row, column=5).font = Font(bold=True, size=14)
ws.cell(row=grand_total_row, column=5).number_format = '#,##0์›'

# ์—ด ๋„ˆ๋น„
ws.column_dimensions['A'].width = 8
ws.column_dimensions['B'].width = 20
ws.column_dimensions['C'].width = 10
ws.column_dimensions['D'].width = 12
ws.column_dimensions['E'].width = 15
ws.column_dimensions['F'].width = 15

wb.save(filename)
print(f"์†ก์žฅ ์ƒ์„ฑ ์™„๋ฃŒ: {filename}")

# ์‚ฌ์šฉ ์˜ˆ์ œ
invoice_data = {
'customer_name': '(์ฃผ)๊ธ€๋กœ๋ฒŒํ…Œํฌ',
'invoice_number': 'INV-2024-001',
'items': [
("์›น ์‚ฌ์ดํŠธ ๊ฐœ๋ฐœ", 1, 5000000, "๋ฉ”์ธ ํ”„๋กœ์ ํŠธ"),
("์œ ์ง€๋ณด์ˆ˜ (1๊ฐœ์›”)", 1, 500000, "์›”๊ฐ„"),
("๋„๋ฉ”์ธ ๋“ฑ๋ก", 1, 15000, "์—ฐ๊ฐ„"),
("ํ˜ธ์ŠคํŒ…", 12, 30000, "์›”๊ฐ„")
]
}

create_invoice(invoice_data, "์†ก์žฅ_2024_001.xlsx")

4. ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋ฐ ํ”ผ๋ฒ— ํ…Œ์ด๋ธ”โ€‹

from openpyxl import Workbook
from collections import defaultdict

def create_sales_analysis(raw_data, filename):
"""๋งค์ถœ ๋ฐ์ดํ„ฐ ๋ถ„์„ ๋ฐ ์š”์•ฝ"""

wb = Workbook()

# ์›๋ณธ ๋ฐ์ดํ„ฐ ์‹œํŠธ
ws_raw = wb.active
ws_raw.title = "์›๋ณธ ๋ฐ์ดํ„ฐ"

# ํ—ค๋”
headers = ["๋‚ ์งœ", "์ œํ’ˆ", "์นดํ…Œ๊ณ ๋ฆฌ", "์ˆ˜๋Ÿ‰", "๋‹จ๊ฐ€", "๋งค์ถœ"]
ws_raw.append(headers)

# ๋ฐ์ดํ„ฐ ์ž…๋ ฅ
for row in raw_data:
ws_raw.append(row)

# ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์ง‘๊ณ„
category_sales = defaultdict(int)
product_sales = defaultdict(int)

for row in raw_data:
date, product, category, quantity, price, sales = row
category_sales[category] += sales
product_sales[product] += sales

# ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์š”์•ฝ ์‹œํŠธ
ws_category = wb.create_sheet("์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋งค์ถœ")
ws_category.append(["์นดํ…Œ๊ณ ๋ฆฌ", "๋งค์ถœ์•ก"])

for category, sales in sorted(category_sales.items(), key=lambda x: x[1], reverse=True):
ws_category.append([category, sales])

# ์ œํ’ˆ๋ณ„ ์š”์•ฝ ์‹œํŠธ
ws_product = wb.create_sheet("์ œํ’ˆ๋ณ„ ๋งค์ถœ")
ws_product.append(["์ œํ’ˆ", "๋งค์ถœ์•ก"])

for product, sales in sorted(product_sales.items(), key=lambda x: x[1], reverse=True):
ws_product.append([product, sales])

# ์Šคํƒ€์ผ ์ ์šฉ (๋ชจ๋“  ์‹œํŠธ)
for ws in wb.worksheets:
# ํ—ค๋” ์Šคํƒ€์ผ
for cell in ws[1]:
cell.font = Font(bold=True)

# ์ˆซ์ž ํ˜•์‹
if ws.max_row > 1:
for row in range(2, ws.max_row + 1):
if ws.max_column >= 2:
ws.cell(row=row, column=ws.max_column).number_format = '#,##0์›'

wb.save(filename)
print(f"๋ถ„์„ ์™„๋ฃŒ: {filename}")

# ์‚ฌ์šฉ ์˜ˆ์ œ
sales_data = [
["2024-01-01", "๋…ธํŠธ๋ถ", "์ „์ž์ œํ’ˆ", 2, 1200000, 2400000],
["2024-01-02", "๋งˆ์šฐ์Šค", "์ „์ž์ œํ’ˆ", 5, 25000, 125000],
["2024-01-03", "์ฑ…์ƒ", "๊ฐ€๊ตฌ", 3, 150000, 450000],
["2024-01-04", "์˜์ž", "๊ฐ€๊ตฌ", 4, 80000, 320000],
["2024-01-05", "ํ‚ค๋ณด๋“œ", "์ „์ž์ œํ’ˆ", 3, 80000, 240000],
]

create_sales_analysis(sales_data, "๋งค์ถœ๋ถ„์„.xlsx")

5. CSV to Excel ๋ณ€ํ™˜๊ธฐโ€‹

import csv
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill

def csv_to_excel(csv_file, excel_file):
"""CSV ํŒŒ์ผ์„ ์Šคํƒ€์ผ์ด ์ ์šฉ๋œ Excel๋กœ ๋ณ€ํ™˜"""

wb = Workbook()
ws = wb.active

# CSV ์ฝ๊ธฐ
with open(csv_file, 'r', encoding='utf-8') as f:
reader = csv.reader(f)

for i, row in enumerate(reader, 1):
ws.append(row)

# ์ฒซ ํ–‰ ์Šคํƒ€์ผ (ํ—ค๋”)
if i == 1:
for cell in ws[i]:
cell.font = Font(bold=True, color='FFFFFF')
cell.fill = PatternFill(
start_color='4472C4',
end_color='4472C4',
fill_type='solid'
)

# ์—ด ๋„ˆ๋น„ ์ž๋™ ์กฐ์ •
for column in ws.columns:
max_length = 0
column_letter = column[0].column_letter

for cell in column:
if cell.value:
max_length = max(max_length, len(str(cell.value)))

adjusted_width = min(max_length + 2, 50)
ws.column_dimensions[column_letter].width = adjusted_width

wb.save(excel_file)
print(f"๋ณ€ํ™˜ ์™„๋ฃŒ: {csv_file} -> {excel_file}")

# ์‚ฌ์šฉ ์˜ˆ์ œ
csv_to_excel('data.csv', 'data.xlsx')

์ž์ฃผ ๋ฌป๋Š” ์งˆ๋ฌธโ€‹

Q1. .xls ํŒŒ์ผ๋„ ์ฝ์„ ์ˆ˜ ์žˆ๋‚˜์š”?โ€‹

A: openpyxl์€ .xlsx ์ „์šฉ์ž…๋‹ˆ๋‹ค. .xls ํŒŒ์ผ์€ xlrd ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

# .xls ํŒŒ์ผ ์ฝ๊ธฐ
import xlrd

workbook = xlrd.open_workbook('old_file.xls')
sheet = workbook.sheet_by_index(0)

# ์…€ ๊ฐ’ ์ฝ๊ธฐ
value = sheet.cell_value(0, 0)

Q2. ๋Œ€์šฉ๋Ÿ‰ ์—‘์…€ ํŒŒ์ผ์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋‚˜์š”?โ€‹

A: read_only=True์™€ write_only=True ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

# ์ฝ๊ธฐ ์ „์šฉ ๋ชจ๋“œ (๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ )
wb = load_workbook('large_file.xlsx', read_only=True)

# ์“ฐ๊ธฐ ์ „์šฉ ๋ชจ๋“œ
wb = Workbook(write_only=True)
ws = wb.create_sheet()

for row in data:
ws.append(row)

wb.save('output.xlsx')

Q3. ๊ธฐ์กด ์—‘์…€ ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜๋ฉด ์„œ์‹์ด ์‚ฌ๋ผ์ ธ์š”.โ€‹

A: openpyxl์€ ์ผ๋ถ€ ๊ณ ๊ธ‰ ์„œ์‹์„ ๋ณด์กดํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ค‘์š”ํ•œ ์„œ์‹์€ ๋ฐฑ์—…ํ•˜๊ณ  ์ž‘์—…ํ•˜์„ธ์š”.

# ํŒŒ์ผ ๋ณต์‚ฌ๋ณธ ๋งŒ๋“ค๊ธฐ
import shutil
shutil.copy('original.xlsx', 'backup.xlsx')

# ๋ณต์‚ฌ๋ณธ ์ˆ˜์ •
wb = load_workbook('original.xlsx')
# ... ์ž‘์—… ...
wb.save('original.xlsx')

Q4. ์—ฌ๋Ÿฌ ์‹œํŠธ๋ฅผ ํ•œ ๋ฒˆ์— ์ž‘์—…ํ•  ์ˆ˜ ์žˆ๋‚˜์š”?โ€‹

A: ๋„ค, ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๋ชจ๋“  ์‹œํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

wb = load_workbook('workbook.xlsx')

for sheet_name in wb.sheetnames:
ws = wb[sheet_name]
print(f"์ฒ˜๋ฆฌ ์ค‘: {sheet_name}")

# ๊ฐ ์‹œํŠธ ์ž‘์—…
for row in ws.iter_rows(values_only=True):
print(row)

Q5. pandas์™€ openpyxl ์ค‘ ์–ด๋–ค ๊ฒƒ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋‚˜์š”?โ€‹

A: ๋ฐ์ดํ„ฐ ๋ถ„์„์ด ์ฃผ ๋ชฉ์ ์ด๋ฉด pandas, ์„œ์‹๊ณผ ์ฐจํŠธ๊ฐ€ ์ค‘์š”ํ•˜๋ฉด openpyxl์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

# pandas๋กœ Excel ์ฝ๊ธฐ/์“ฐ๊ธฐ
import pandas as pd

df = pd.read_excel('data.xlsx')
df.to_excel('output.xlsx', index=False)

# openpyxl๋กœ ์„œ์‹ ์ ์šฉ
from openpyxl import load_workbook
from openpyxl.styles import Font

wb = load_workbook('output.xlsx')
ws = wb.active
ws['A1'].font = Font(bold=True)
wb.save('output.xlsx')

๋‹ค์Œ ๋‹จ๊ณ„โ€‹

์—‘์…€ ์ž๋™ํ™”๋ฅผ ๋ฐฐ์› ๋‹ค๋ฉด, ๋‹ค์Œ ์ฃผ์ œ๋กœ ๋„˜์–ด๊ฐ€์„ธ์š”:

  • ์›น ์ž๋™ํ™”: Selenium์œผ๋กœ ๋ธŒ๋ผ์šฐ์ € ์ œ์–ดํ•˜๊ธฐ
  • ์ž‘์—… ์Šค์ผ€์ค„๋ง: ์ •๊ธฐ์ ์ธ ๋ณด๊ณ ์„œ ์ž๋™ ์ƒ์„ฑํ•˜๊ธฐ
  • ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”: matplotlib, seaborn์œผ๋กœ ๊ทธ๋ž˜ํ”„ ๋งŒ๋“ค๊ธฐ

์—‘์…€ ์ž๋™ํ™”๋Š” ์—…๋ฌด ์ƒ์‚ฐ์„ฑ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์‹ค์šฉ์ ์ธ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ ์—…๋ฌด์— ์ ์šฉํ•ด๋ณด์„ธ์š”!