Automating Excel Reports with Openpyxl
This guide demonstrates how to generate professional Excel reports programmatically. Unlike pandas which is great for data analysis, openpyxl gives you granular control over Excel features like formulas, cell styling, and charts.
Modules Used:
- openpyxl: To create and modify Excel files.
random: To generate dummy data for demonstration.
Installation
pip install openpyxl
The Code
Save this as report_gen.py.
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment
from openpyxl.chart import BarChart, Reference
import random
def create_report(filename):
wb = Workbook()
ws = wb.active
ws.title = "Sales Report"
# 1. Add Headers
headers = ["Product", "Region", "Q1", "Q2", "Q3", "Q4", "Total", "Average"]
ws.append(headers)
# 2. Add Dummy Data
products = ["Laptop", "Mouse", "Keyboard", "Monitor", "Headset"]
regions = ["North", "South", "East", "West"]
# Generate 20 rows of data
for _ in range(20):
product = random.choice(products)
region = random.choice(regions)
q1 = random.randint(1000, 5000)
q2 = random.randint(1000, 5000)
q3 = random.randint(1000, 5000)
q4 = random.randint(1000, 5000)
# Note: We don't calculate Total/Avg here, we let Excel do it via formulas
ws.append([product, region, q1, q2, q3, q4])
# 3. Add Formulas and Formatting
# Iterate starting from row 2 (since row 1 is headers)
for row in range(2, ws.max_row + 1):
# Add Excel Formulas
ws[f'G{row}'] = f"=SUM(C{row}:F{row})"
ws[f'H{row}'] = f"=AVERAGE(C{row}:F{row})"
# Apply Currency Format to numerical columns (C to H)
for col in range(3, 9):
cell = ws.cell(row=row, column=col)
cell.number_format = '$#,##0.00'
# 4. Style the Headers
header_font = Font(bold=True, color="FFFFFF")
header_fill = PatternFill(start_color="4F81BD", end_color="4F81BD", fill_type="solid")
for cell in ws[1]:
cell.font = header_font
cell.fill = header_fill
cell.alignment = Alignment(horizontal="center")
# 5. Add a Bar Chart
chart = BarChart()
chart.type = "col"
chart.style = 10
chart.title = "Quarterly Sales Overview"
chart.y_axis.title = 'Revenue'
chart.x_axis.title = 'Data Points'
# Define data range for the chart (Q1 to Q4 columns)
data = Reference(ws, min_col=3, min_row=1, max_col=6, max_row=ws.max_row)
chart.add_data(data, titles_from_data=True)
# Place the chart at cell J2
ws.add_chart(chart, "J2")
wb.save(filename)
print(f"Report saved successfully to {filename}")
if __name__ == "__main__":
create_report("quarterly_sales.xlsx")