import collections
import collections.abc
from pptx import Presentation
from pptx.util import Inches
from pptx.chart.data import CategoryChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.dml.color import RGBColor
import webcolors
import os
import pandas as pd
import openpyxl
from colorama import Fore, Style
def create_presentation():
prs = Presentation()
return prs
def add_slide(prs, slide_layout):
slide = prs.slides.add_slide(slide_layout)
return slide
def add_title_slide(slide, title_text):
title = slide.shapes.title
title.text = title_text
if len(slide.placeholders) > 1:
slide.placeholders[1].text = ''
def add_title_content_slide(slide):
title = slide.shapes.title
title.text = input(Fore.YELLOW + Style.BRIGHT + "Input title: ")
while True:
content_choice = input(Fore.YELLOW + Style.BRIGHT + 'Do you want to insert a graph or a table? (graph/table): ')
if content_choice == 'graph':
print()
print(Fore.LIGHTYELLOW_EX + Style.BRIGHT + 'Graph')
while True:
chart_data = CategoryChartData()
chart_data.categories = input(
Fore.MAGENTA + Style.BRIGHT + 'Enter graph categories (comma-separated): ').split(',')
series_name = input(Fore.MAGENTA + Style.BRIGHT + 'Enter series name for the graph: ')
series_values = [float(value) for value in
input(Fore.MAGENTA + Style.BRIGHT + 'Enter series values (comma-separated): ').split(
',')]
if len(chart_data.categories) == len(series_values):
chart_data.add_series(series_name, series_values)
break
else:
print(Fore.RED + Style.BRIGHT + 'Number of categories and values must be the same.')
x, y, cx, cy = Inches(2), Inches(2), Inches(6), Inches(4)
chart = slide.shapes.add_chart(XL_CHART_TYPE.PIE, x, y, cx, cy, chart_data).chart
chart.has_legend = True
chart.legend.position = 2
chart.legend.include_in_layout = False
for i, point in enumerate(chart.series[0].points):
while True:
color_code = input(Fore.MAGENTA + Style.BRIGHT + f"Enter color for Pie Chart:")
try:
rgb_color = webcolors.hex_to_rgb(color_code)
fill = point.format.fill
fill.solid()
fill.fore_color.rgb = RGBColor(rgb_color.red, rgb_color.green, rgb_color.blue)
break
except ValueError:
try:
rgb_color = webcolors.name_to_rgb(color_code)
fill = point.format.fill
fill.solid()
fill.fore_color.rgb = RGBColor(rgb_color.red, rgb_color.green, rgb_color.blue)
break
except ValueError:
print(Fore.RED + Style.BRIGHT + f'Invalid color code: {color_code}')
break
elif content_choice == 'table':
print()
print(Fore.LIGHTYELLOW_EX + Style.BRIGHT + 'Table')
table_data_source = input(
Fore.MAGENTA + Style.BRIGHT + 'Enter the source of the table data (input/excel): ')
if table_data_source == 'input':
num_rows = get_positive_integer_input(Fore.CYAN + Style.BRIGHT + 'Enter the number of rows in the table: ')
num_cols = get_positive_integer_input(Fore.CYAN + Style.BRIGHT + 'Enter the number of columns in the table: ')
table = slide.shapes.add_table(num_rows, num_cols, Inches(3), Inches(2), Inches(4), Inches(3)).table
for row in range(num_rows):
print()
for col in range(num_cols):
while True:
cell_value = input(
Fore.MAGENTA + Style.BRIGHT + f'Enter value for cell ({row + 1}, {col + 1}): ')
if cell_value.strip():
table.cell(row, col).text = cell_value
break
else:
print(Fore.RED + Style.BRIGHT + 'Cell value cannot be empty.')
elif table_data_source == 'excel':
file_path = input(Fore.CYAN + Style.BRIGHT + 'Enter the path of the Excel file: ')
sheet_name = input(Fore.CYAN + Style.BRIGHT + 'Enter the name of the Excel sheet: ')
try:
workbook = openpyxl.load_workbook(file_path, read_only=True)
sheet = workbook[sheet_name]
num_rows = sheet.max_row
num_cols = sheet.max_column
table = slide.shapes.add_table(num_rows, num_cols, Inches(3), Inches(2), Inches(4),
Inches(3)).table
for row in range(num_rows):
for col in range(num_cols):
cell_value = sheet.cell(row + 1, col + 1).value
if cell_value is not None:
table.cell(row, col).text = str(cell_value)
except FileNotFoundError:
print(Fore.RED + Style.BRIGHT + f'File not found at path: {file_path}')
except KeyError:
print(Fore.RED + Style.BRIGHT + f'No sheet found with name: {sheet_name}')
break
else:
print(Fore.RED + Style.BRIGHT + 'Invalid choice! Please enter either "graph" or "table".')
def add_section_header_slide(slide):
title = slide.shapes.title
title.text = input(Fore.YELLOW + Style.BRIGHT + 'Enter title: ')
if len(slide.placeholders) > 1:
slide.placeholders[1].text = ''
while True:
image = input(Fore.MAGENTA + Style.BRIGHT + 'Do you want to insert an image? (y/n): ')
if image == 'y':
while True:
img_path = input(Fore.MAGENTA + Style.BRIGHT + 'Enter image path: ')
try:
pic = slide.shapes.add_picture(img_path, Inches(0.5), Inches(1), height=Inches(3),width=Inches(3))
break
except FileNotFoundError:
print(Fore.RED + Style.BRIGHT + f'Error: Image file not found at "{img_path}"')
elif image == 'n':
break
else:
print(Fore.RED + Style.BRIGHT + 'Invalid choice! Please enter either "y" or "n".')
def determine_text_color(bg_color):
r, g, b = bg_color
brightness = (r * 299 + g * 587 + b * 114) / 1000
if brightness > 125:
return '000000'
else:
return 'FFFFFF'
def get_positive_integer_input(prompt):
while True:
try:
value = int(input(prompt))
if value <= 0 :
raise ValueError
return value
except ValueError:
print(Fore.RED + Style.BRIGHT + 'Invalid input. Please enter a positive integer.')
def generate_presentation():
prs = create_presentation()
while True:
try:
print()
number_of_slides = get_positive_integer_input(Fore.YELLOW + Style.BRIGHT + 'Enter the number of slides: ')
for i in range(1, number_of_slides + 1):
print()
print(Fore.LIGHTYELLOW_EX + Style.BRIGHT + f"Slide - {i}")
type_of_slide = get_num_between_1_and_3(
Fore.MAGENTA + Style.BRIGHT + f'''Enter the layout of slide {i}:
1. Title slide
2. Graph or Table slide
3. Image slide
option - ''')
if type_of_slide not in [1, 2, 3]:
print(Fore.RED + Style.BRIGHT + "Invalid slide layout choice. Please try again.")
return
slide_layouts = prs.slide_layouts
slide_layout = slide_layouts[type_of_slide - 1]
slide = add_slide(prs, slide_layout)
if type_of_slide == 1:
if i == number_of_slides - 1:
add_title_slide(slide, "Thank You")
else:
slide_title = input(Fore.YELLOW + Style.BRIGHT + 'Input title: ')
add_title_slide(slide, slide_title)
elif type_of_slide == 2:
add_title_content_slide(slide)
elif type_of_slide == 3:
add_section_header_slide(slide)
print()
while True:
slide_color = input(Fore.YELLOW + Style.BRIGHT + '''Enter the color for the slide
(color name or hexadecimal code): ''')
if slide_color.startswith('#'):
slide_color = slide_color[1:]
try:
slide.background.fill.solid()
slide.background.fill.fore_color.rgb = RGBColor.from_string(slide_color)
text_color = determine_text_color(webcolors.hex_to_rgb(slide_color))
for shape in slide.shapes:
if shape.has_text_frame:
for paragraph in shape.text_frame.paragraphs:
for run in paragraph.runs:
run.font.color.rgb = RGBColor.from_string(text_color)
for shape in slide.shapes:
if shape.has_chart:
chart = shape.chart
if chart.has_legend:
legend = chart.legend
legend_text_color = determine_text_color(webcolors.hex_to_rgb(slide_color))
legend.font.color.rgb = RGBColor.from_string(legend_text_color)
break
except ValueError:
try:
rgb_color = webcolors.name_to_rgb(slide_color)
slide.background.fill.solid()
slide.background.fill.fore_color.rgb = RGBColor(rgb_color.red, rgb_color.green,
rgb_color.blue)
text_color = determine_text_color((rgb_color.red, rgb_color.green, rgb_color.blue))
for shape in slide.shapes:
if shape.has_text_frame:
for paragraph in shape.text_frame.paragraphs:
for run in paragraph.runs:
run.font.color.rgb = RGBColor.from_string(text_color)
for shape in slide.shapes:
if shape.has_chart:
chart = shape.chart
if chart.has_legend:
legend = chart.legend
legend_text_color = determine_text_color(
(rgb_color.red, rgb_color.green, rgb_color.blue))
legend.font.color.rgb = RGBColor.from_string(legend_text_color)
break
except ValueError:
print(Fore.RED + Style.BRIGHT + "Invalid color entered.")
thank_you_slide_layout = prs.slide_layouts[0]
thank_you_slide = add_slide(prs, thank_you_slide_layout)
add_title_slide(thank_you_slide, "Thank You")
except ValueError:
print(Fore.RED + Style.BRIGHT + "Invalid input. Please enter a valid number of slides.")
return
break
file_name = f"sales_report.pptx"
prs.save(f"")
os.startfile(f"")
print(Fore.LIGHTBLUE_EX + Style.BRIGHT + '''Hey want to create a PPT?
Dont worry we got you!!!
Just type the required fields below.''')
generate_presentation()