So I have a excel which contains a table like this:
I want to get the same table in powerpoint using Python
Work Done till now:
Read the excel to python and store in pandas df
Add df to powerpoint
Code for the same effort:
from pd2ppt import df_to_table
import pandas as pd
from pptx import Presentation
from pptx.util import Inches
path =r"Sample PPT.pptx"
prs = Presentation(path)
title_slide_layout = prs.slide_layouts[5]
slide = prs.slides.add_slide(title_slide_layout)
title = slide.shapes.title
title.text = "Summary Table"
top = Inches(1.5)
left =Inches(0.25)
width =Inches(9.25)
height= Inches(5.0)
df_to_table(slide, df,left, top, width, height)
All I need is how to do color formatting in this table using Python?
Each cell in a PowerPoint table has its own fill, which can do everything other FillFormat objects can do::
from pptx.dml.color import RGBColor
cell = table.cell(0, 0) # ---or whatever cell you choose---
fill = cell.fill
fill.solid()
fill.fore_color.rgb = RGBColor(0xFA, 0x00, 0x37)
The FillFormat object interface is further described in the documentation here:
https://python-pptx.readthedocs.io/en/latest/api/dml.html#fillformat-objects
Related
I’m having some issues with reportlab and writing a PDF. When the PDF is written it only consumes a little less than 2/3 of the page width (letter). The heading, for example, wraps and never makes it past the halfway point of the document.
I’m at a loss for how to get my tables and paragraph to use the full width of the page.
Any insight is greatly appreciated.
Thank you in advance.
import io
import os
from django.core.files.base import ContentFile
from jsignature.utils import draw_signature
from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_RIGHT, TA_CENTER, TA_LEFT
from reportlab.lib.units import inch
from reportlab.pdfgen import canvas
from reportlab.platypus import SimpleDocTemplate, Paragraph, Table
from PIL import Image
# create pdf with table and paragraphs
def create_pdf(participant):
# create a file-like buffer to receive PDF data
buffer = io.BytesIO()
# define styles
styles = getSampleStyleSheet()
style_general = ParagraphStyle(
name='left',
parent=styles['Normal'],
fontSize=12,
fontName='Helvetica',
alignment=TA_LEFT)
style_image = ParagraphStyle(
name='left',
fontSize=30,
parent=styles['Normal'],
alignment=TA_LEFT)
style_heading = ParagraphStyle(
name='center',
fontSize=18,
fontName='Helvetica-Bold',
parent=styles['Heading1'],
leading=18,
alignment=TA_CENTER)
# create a simple document with page size in buffer
doc = SimpleDocTemplate(buffer, pagesize=letter, author='Me')
# create a list of paragraphs
AllParagraphs = []
# convert png image to jpeg
jpeg_image = get_jpeg_image(participant)
# add rows and columns so that the data can align
table_data = [
[Paragraph("My Heading - It should span the full page width", style_heading)],
[
Paragraph('Name:', style_general),
Paragraph(
f'{participant.first_name} {participant.middle_initial} {participant.last_name}',
style_general)
],
[
Paragraph(f'Signature:', style_general),
# image height of 30 to prevent overlapping since fontSize is 30,
# image width of double to maintain aspect ratio
Paragraph(
"<img src='{0}' valign='middle' width=60 height=30 />".format(
jpeg_image),
style_image)
]
]
# set rows and columns into Table object
table_element = Table(table_data)
# add table to list of paragraphs
AllParagraphs.append(table_element)
# build document with list of paragraphs
doc.build(AllParagraphs)
# get content of buffer
buffer.seek(0)
pdf_data = buffer.getvalue()
# save buffer content to django File object
file_data = ContentFile(pdf_data)
# name pdf file
file_data.name = f'{participant.last_name}.pdf'
# delete jpeg file
os.remove(jpeg_image)
# save pdf file to parent model
participant.pdf = file_data
participant.save()
For those interested in the answer: adjusting the table style to span multiple columns was the right approach.
In this case a table is being used to best align the signature elements, so spanning the columns similar to how you would in html or css is the solution.
...
# existing code for placement reference
# set rows and columns into Table object
table_element = Table(table_data)
# add table to list of paragraphs
# new code for spanning
# style table object to make single cells span both columns
table_element.setStyle(TableStyle([
('SPAN', (0, 0), (1, 0)),
]))
I am aware of adding URL to PPT, but due to certain privacy issues that cannot be done.
Is there any other way to import plotly charts to ppt? or any equivalent open source app that can be used?
Thank you in advance!
it's pretty straight forward to save as a static image https://plotly.com/python/static-image-export/
create a powerpoint https://python-pptx.readthedocs.io/en/latest/user/quickstart.html#
I don't have powerpoint or a Windows o/s. It's not clear that powerpoint works with active HTML
import plotly.express as px
import pandas as pd
import numpy as np
from pathlib import Path
df = pd.DataFrame({
"time": pd.date_range("1-Jul-2021", periods=200, freq="1H"),
"desired_light": np.random.choice(["ON", "OFF"], 200),
})
# build a figure
fig = px.bar(df, x="time", color="desired_light", height=400, title="Restaurant bills")
# export fingure as a static file: https://plotly.com/python/static-image-export/
fname = Path.cwd().joinpath("SO.png")
fig.write_image(fname)
# create a powerpoint from an image: https://python-pptx.readthedocs.io/en/latest/user/quickstart.html
from pptx import Presentation
from pptx.util import Inches
prs = Presentation()
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)
left = top = Inches(1)
pic = slide.shapes.add_picture(str(fname), left, top)
prs.save(Path.cwd().joinpath('SO.pptx'))
I just want to add a shadow to the shapes that I am creating while using python-pptx.
I have read as many documents about using shadows in python-pptx as I can find but I can not figure out how to actually do it.
I tried shadow = shape.shadow to create a 'ShadowFormat' object but when I try to do shadow.visible I get the error AttributeError: 'ShadowFormat' object has no attribute 'visible'
If anyone could explain how this is done and give an example it would be much appreciated!
Extra info:
This is the page linking to the topic: https://python-pptx.readthedocs.io/en/latest/dev/analysis/shp-shadow.html however there is no example on how to create a shadow for a shape in powerpoint.
I have imported the following modules:
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE
from pptx.enum.action import PP_ACTION
from pptx.util import Cm
from pptx.enum.dml import MSO_THEME_COLOR_INDEX
from pptx.enum.text import MSO_AUTO_SIZE
from pptx.util import Pt
I am using python-pptx v0.6.18 and python v3.8
Edit
Example that creates the shape but no shadow appears:
#Import modules
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE
from pptx.util import Cm
from pptx.enum.dml import MSO_THEME_COLOR_INDEX
from pptx.util import Pt
#Open powerpoint file
prs = Presentation('filename.pptx')
#Create a slide
slidelayout = prs.slide_layouts[0]
slide = prs.slides.add_slide(slidelayout)
shapes = slide.shapes
#Add a shape
shape = shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, Cm(10), Cm(10), Cm(10), Cm(10))
#Create a shadow
shadow = shape.shadow
shadow.inherit = False
shadow.visible = True
shadow.distance = Pt(10)
shadow.shadow_type = 'outer'
shadow.angle = 45
shadow.blur_radius = Pt(5)
shadow.color = MSO_THEME_COLOR_INDEX.ACCENT_5
shadow.transparency = '50'
shadow.distance = Pt(5)
shape.shadow.style = 'outer'
#Save the powerpoint file
prs.save('filename2.pptx')
Example that creates the error message:
#Import modules
from pptx import Presentation
from pptx.enum.shapes import MSO_SHAPE
from pptx.util import Cm
from pptx.enum.dml import MSO_THEME_COLOR_INDEX
from pptx.util import Pt
#Open powerpoint file
prs = Presentation('filename.pptx')
#Create a slide
slidelayout = prs.slide_layouts[0]
slide = prs.slides.add_slide(slidelayout)
shapes = slide.shapes
#Add a shape
shape = shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE, Cm(10), Cm(10), Cm(10), Cm(10))
#Create a shadow
shadow = shape.shadow
shadow.visible
#Save the powerpoint file
prs.save('filename2.pptx')
The feature <ShadowFormat.visible - applies a reasonable standard shadow override.> is currently out of the scope of pptx.
The command <shadow.inherit = False> is used to remove the default setting with the shadow.
By default, the shadow visibility is set to true. If you want to show the shadow, you can either:
set <shadow.inherit = True>
remove <shadow.inherit = False>
You can use Aspose.Slides for Python to manipulate the shapes. This is a paid library, but you can get a temporary license to evaluate it. The following code example shows you how to add a shape with a shadow to a presentation:
import aspose.slides as slides
# Create a new presentation.
with slides.Presentation() as presentation:
# Create a shape.
shape = presentation.slides[0].shapes.add_auto_shape(slides.ShapeType.ROUND_CORNER_RECTANGLE, 10, 10, 20, 20)
# Set a shadow for the shape.
shape.effect_format.enable_outer_shadow_effect()
shape.effect_format.outer_shadow_effect.distance = 10
shape.effect_format.outer_shadow_effect.direction = 45
shape.effect_format.outer_shadow_effect.blur_radius = 5
shape.effect_format.outer_shadow_effect.shadow_color.color = presentation.master_theme.color_scheme.accent5.color
# Save the presentation.
presentation.save("example.pptx", slides.export.SaveFormat.PPTX)
The result:
Alternatively, you can use Aspose.Slides Cloud SDK for Python. This product provides a REST-based API for presentation processing. It is also a paid product, but you can make 150 free API calls per month for experimentation, learning, and any other purpose. The following code example creates the same shape with the shadow using Aspose.Slides Cloud:
import asposeslidescloud
from asposeslidescloud.apis.slides_api import SlidesApi
from asposeslidescloud.models.shape import Shape
from asposeslidescloud.models.effect_format import EffectFormat
from asposeslidescloud.models.outer_shadow_effect import OuterShadowEffect
slides_api = SlidesApi(None, "my_client_id", "my_client_secret")
# Let's a presentation exists in a storage.
file_name = "example.pptx"
slide_index = 1
color_scheme = slides_api.get_color_scheme(file_name, slide_index)
# Prepare DTO for a shape with the shadow.
shape = Shape()
shape.shape_type = "RoundCornerRectangle"
shape.x = 10
shape.y = 10
shape.width = 20
shape.height = 20
shape.effect_format = EffectFormat()
shape.effect_format.outer_shadow = OuterShadowEffect()
shape.effect_format.outer_shadow.distance = 10
shape.effect_format.outer_shadow.direction = 45
shape.effect_format.outer_shadow.blur_radius = 5
shape.effect_format.outer_shadow.shadow_color = color_scheme.accent5
# Create the shape.
slides_api.create_shape(file_name, slide_index, shape)
I work as a Support Developer at Aspose.
from pptx import Presentation
from pptx.util import Inches
prs = Presentation("my_pptfile_begin.pptx")
left = Inches(0.6)
top = Inches(1.7)
blank_slide_1 = prs.slide_layouts[6]
add_the_slide = prs.slides.add_slide(blank_slide_1)
img_path1 = 'Three_Part_Set_Difference_excel_printout.png'
slide1=prs.slides[1]
pic = slide1.shapes.add_picture(img_path1, left, top)
blank_slide_2 = prs.slide_layouts[6]
add_the_slide = prs.slides.add_slide(blank_slide_2)
img_path2 = 'my_image.png'
slide2=prs.slides[2]
pic = slide2.shapes.add_picture(img_path2, left, top)
logoleft = Inches(4.7)
logotop = Inches(1.8)
blank_slide_3 = prs.slide_layouts[6]
add_the_slide = prs.slides.add_slide(blank_slide_3)
img_path3 = 'logo_slide.png'
slide3=prs.slides[3]
pic = slide3.shapes.add_picture(img_path3, logoleft, logotop)
prs.save('my_pptfile_Final.pptx')
How to remove the blank text boxes (or as a matter of fact all textboxes)?
I do not need any text boxes in my Powerpoint output file
If you're talking about empty placeholder shapes, just use a slide layout that has no placeholders.
In the default template used when you call Presentation() by itself (without an argument), that is the seventh layout I believe (prs.slide_layouts[6]).
But you need to adjust that for whatever starting .pptx file you're using ("my_pptfile_begin.pptx" in your case) by looking at it in slide-master view and counting down to the blank layout (or adding one if it doesn't have one).
blank_slide_3 = prs.slide_layouts[x] where x the slide number of the default template of your pptx application or your company's default template.
Therefore you need to know the default template and know the blank slide with no textboxes of that template based on the defaults of your ppt application
I'm using xlwings on a Mac and would like to set the foreground color of text in a cell from Python. I see that range.color will change background color which I could use but it has an additional problem that the cell borders are overwritten by the new BG color.
Is there any way to change foreground text color from Python and/or prevent the cell borders being overwritten by a new BG color?
The new API is :
Range("A1").api.Font.ColorIndex = 3
xlwings is currently still a bit light on stylistic features. However, as described here, you can work around like this on Mac by accessing the underlying appscript object directly:
some_rgb_vale = (22, 22, 200)
xw.Range('A1').xl_range.font_object.color.set(some_rgb_vale)
Update:
Nowadays, this is now natively supported by xlwings including Hex color notation:
import xlwings as xw
book = xw.Book()
sheet = book.sheets[0]
sheet["A1"].value = "Some Text"
sheet["A1"].font.color = "#ff0000"
this worked for me
import xlwings as xw
import sys,os
FN = "test.xlsx"
path = os.path.abspath(os.path.dirname(sys.argv[0]))
fn = path + "/" + FN
wb = xw.Book (fn)
ws = wb.sheets["Tabelle1"]
# set background color
ws["B1"].value = "Field1"
ws["B1"].color = (255,255,204)
# set font to bold
ws["B2"].value = "Field2"
ws.range("B2").api.Font.Bold = True
# set font color to green
# color-index see here
ws["B3"].value = "Field3"
ws.range("B3").api.Font.ColorIndex = 4
This solution is working fine for me.
from xlwings.utils import rgb_to_int
import xlwings as xw
sht.range('A1').api.Font.Color = rgb_to_int((192, 192, 192))