It seems this issue was brought up and requested back in 2015 but I cannot find any updates on it. I'm trying to copy an entire slide (including its text and images) from another presentation into my working presentation by doing something like the following:
prs = Presentation('CurrentPresentation.pptx')
prs1 = Presentation('OtherPresentation.pptx')
# Wanted_Slide = prs1.slides[0]
New_Slide = prs.slides.add_slide(prs1.slide_layout[0])
But all this does is add a totally blank slide (with the wanted slide's background) with slide layout 0, which totally makes sense. I know that's not the right way to do it. I tried the below and it did add a slide, but it was just a duplicate one of what was already in the prs presentation (I guess I found a way to duplicate a slide already in the presentation inadvertently):
def Add_Slide(self):
xml_slides = prs.slides._sldIdLst
xml_slides1 = prs1.slides._sldIdLst
slides = list(xml_slides)
slides1 = list(xml_slides1)
xml_slides.append(slides1[0])
The above code is a manipulation of a slide delete method I found online.
Or does anyone have any sort of recommendation on how to completely copy a slide and all of its contents over to a working presentation?
I apologize if no developments have been made and this post is a rehash. Thank you in advance.
There's an issue in the library's repo that has some code to do this, but it's rough, it doesn't work for all cases.
from pptx.parts.chart import ChartPart
from pptx.parts.embeddedpackage import EmbeddedXlsxPart
from pptx import Presentation
import copy
def _get_blank_slide_layout(pres):
layout_items_count = [len(layout.placeholders) for layout in pres.slide_layouts]
min_items = min(layout_items_count)
blank_layout_id = layout_items_count.index(min_items)
return pres.slide_layouts[blank_layout_id]
def move_slide(pres1, pres, index):
"""Duplicate the slide with the given index in pres1 and "moves" it into pres.
Adds slide to the end of the presentation"""
source = pres1.slides[index]
blank_slide_layout = _get_blank_slide_layout(pres)
dest = pres.slides.add_slide(blank_slide_layout)
for shape in source.shapes:
newel = copy.deepcopy(shape.element)
dest.shapes._spTree.insert_element_before(newel, 'p:extLst')
for key, value in source.part.rels.items():
# Make sure we don't copy a notesSlide relation as that won't exist
if "notesSlide" not in value.reltype:
target = value._target
# if the relationship was a chart, we need to duplicate the embedded chart part and xlsx
if "chart" in value.reltype:
partname = target.package.next_partname(
ChartPart.partname_template)
xlsx_blob = target.chart_workbook.xlsx_part.blob
target = ChartPart(partname, target.content_type,
copy.deepcopy(target._element), package=target.package)
target.chart_workbook.xlsx_part = EmbeddedXlsxPart.new(
xlsx_blob, target.package)
dest.part.rels.add_relationship(value.reltype, target,value.rId)
This function is an alteration of what is on the github comments at the location cited above. It works well for me, haven't tested it with charts or anything. It's slightly altered from what was posted on the site, because there was the rough example noted by the original answer, and there was a more thorough answer for duplicating within a presentation. Figured I'd post since it took me a while to get this all put together.
This solution has mainly worked with one exception. After copying the slide over to the destination presentation when I open the destination presentation I get the following warning:
PowerPoint couldn't read some content in xxx.pptx and removed it. Please check your presentation to see if the rest of it looks ok.
The rest of the presentation does look fine and after saving and reopening the warning goes away. Do you know of a way to make it so this warning doesn't appear or if there is a way to resolve it with Python (saving/closing again?).
Related
from PIL import Image
import requests
import streamlit as st
from streamlit_lottie import st_lottie
#find more emojis at the link he set line 4 will show how your website would be layedout for users to see
st.set_page_config(page_title="My Webpage", page_icon=":tada:", layout="wide")
def load_lottieurl(url):
r =requests.get(url)
if r.status_code != 200:
return None
return r.json()
#lottie files are for animation to be put on your webiste (pip install requests)(pip install streamlit-lottie)(pip install pillow)
lottie_coding = load_lottieurl("https://assets7.lottiefiles.com/packages/lf20_2znxgjyt.json")
img_william = Image.open("images\william.png")
img_tacos = Image.open("images\tacos.png")
#header section / st.container will organize the code it will work fine without
with st.container():
st.subheader("hello i am william and this is my first website made by python header :wave:")
st.title("this would be were the title would go ")
st.write("this would be a small paragraph you wold write this area")
#st.write is for small paragrahps / st.title is to start the paragraps )
# what i am doing with the 3 lines and quotes on line 15 and that i am diving space on the website
with st.container():
st.write("---")
left_column, right_column = st.columns(2)
with left_column:
st.header("this will be the column for the left side ")
st.write('##')
st.write(
"""
i am currently doing what the tutotial is telling me to do even though i am quite cofnused:
- i will master this and i will understtand the concepts of making a website with this framework
- i will be great i bless god for changing how i act and i am as a person
- i know allot of people do not want to see me win but god does and thats all i need
- rome was not built in a day and they will say the samething about my journey
i am confused but if i keep puttingand effort in everyday i will master this in jesues name
"
""
)
i am having difficulty uploading images to python I am using the framework called streamlit and i have been following a tutorial on how to make my own website and when i do what he does to upload the image it tells me in the terminal that no such file in the directory i have made a file for the images that includes the code in the same file so i am very confused please help i am also using a chromebook
if images folder is in the working directory and you want to display the images, all you need is the code below.
st.image("images/william.png")
st.image("images/tacos.png")
but displaying image with PIL, you can do the following
img_william = Image.open("images/william.png")
img_tacos = Image.open("images/tacos.png")
st.image(img_william)
st.image(img_tacos)
Then apply this last method:
right click on your images folder and copy full path.
from pathlib import Path
SCR_DIR = 'C:\\users\\Desktop\\images' # Edit 'C:\\users\\Desktop\\images' with the coppied path you made at the first step. But maintain \\ when editting
img_william = Image.open(Path(SRC_DIR, "william.png"))
img_tacos = Image.open(Path(SRC_DIR, "tacos.png"))
st.image(img_william)
st.image(img_tacos)
Your scr_dir hould be something like
SCR_DIR = 'C:\\user\\My files\\Webpage\\images'
I am pretty sure you are missing something out.
I wanted change the all fonts in about 100 powerpoint files, without opening the files. There are several shape types in each slide and each might have a different font. I used python-pptx package and wrote the following code to change the fonts of all texts in a powerpoint presentation. Although it does not give any error, it does not work, and the fonts in the file are still whatever they were, for example Arial. I also added print(shape.text) to make sure that it has found all texts, and it seems that there is no issue there. Is it a bug? Or am I missing anything?
prs = Presentation('f10.pptx')
for i, slide in enumerate(prs.slides):
for shape in slide.shapes:
print (shape.has_text_frame)
if shape.has_text_frame:
print(shape.text)
for p in shape.text_frame.paragraphs:
for r in p.runs:
print(r.font.name)
r.font.name = 'Tahoma'
print(r.font.name)
prs.save('f10_tahoma.pptx')
Besides, it seems that the package does not work for utf-8 characters. I added a text-box on the last slide by adding:
text_frame = shape.text_frame
text_frame.clear() # not necessary for newly-created shape
p = text_frame.paragraphs[0]
run = p.add_run()
run.text = 'سلام '
font = run.font
font.name = 'Andalus'
font.size = Pt(18)
before saving the file to add a textbox with utf-8 characters. It adds it there, and when I check the font it shows that it is set to Andalus, but actually it is not Andalus.
With Aspose.Slides for Python via .NET, you can easily change all fonts for all texts in your presentations. The following code example shows you how to do this:
import aspose.slides as slides
with slides.Presentation('example.pptx') as presentation:
for slide in presentation.slides:
for shape in slide.shapes:
if isinstance(shape, slides.AutoShape):
for paragraph in shape.text_frame.paragraphs:
for portion in paragraph.portions:
portion.portion_format.latin_font = slides.FontData('Tahoma')
You can also evaluate Aspose.Slides Cloud SDK for Python for presentation manipulating. This REST-based API allows you to make 150 free API calls per month for API learning and presentation processing.
Aspose Slides Online Viewer can be used to view presentations without PowerPoint installed.
I work at Aspose.
What language is the text of the file? Run.font properties work fine for UTF-8, but there is a separate font for cursive scripts like Arabic. Access to that secondary font is not implemented in python-pptx unfortunately, but that could explain at least part of the behavior you're seeing.
For roman character text (like that we're using here), there are a couple things to check.
The font in question needs to be installed on the machine PowerPoint is running on when the document is opened. Otherwise PowerPoint will substitute a font.
The font (typeface) name used in the XML will not always exactly match what appears in the PowerPoint drop-down selection box. You need to give that name to python-pptx in the exact form it should appear in the XML. You may need to make an example file that works by hand, perhaps containing a single slide with a single textbox for simplicity, and then inspect the XML of that file to find the "spelling" used for that typeface by PowerPoint.
You could do that with code like this:
prs = Presentation("example.pptx")
shape = prs.slides[0].shapes[0]
print(shape._element.xml)
You should be able to locate the typeface name somewhere in an element like <p:rPr> or <p:defRPr>.
I want to replace the text in a textbox in Powerpoint with Python-pptx.
Everything I found online didn't work for me and the documentation isn't that helpful for me.
So I have a Textbox with the Text:
$$Name 1$$
$$Name 2$$
and I want to change the $$Name1 $$ to Tom.
How can I achieve that?
A TextFrame object defined in python-pptx helps in manipulating contents of a textbox. You can do something like:
from python-pptx import Presentation
"""open file"""
prs = Presentaion('pptfile.pptx')
"""get to the required slide"""
slide = prs.slides[0]
"""Find required text box"""
for shape in slide.shapes:
if not shape.has_text_frame:
continue
text_frame = shape.text_frame
if "Name 1" == text_frame.text:
text_frame.text = "Tom"
"""save the file"""
prs.save("pptfile.pptx")
Try this:
import pptx
input_pptx = "Input File Path"
prs = pptx.Presentation((input_pptx))
testString = "$$Name1 $$"
replaceString = 'Tom'
title_slide_layout = prs.slide_layouts[0]
slide = prs.slides.add_slide(title_slide_layout)
for slide in prs.slides:
for shape in slide.shapes:
if shape.has_text_frame:
if(shape.text.find(testString))!=-1:
shape.text = shape.text.replace(testString, replaceString)
if not shape.has_table:
continue
prs.save('C:/test.pptx')
Ok thank you. I just found out, that my PowerPoint example was totaly messed up. No everything works fine with a new PowerPoint blanked
In order to keep original formatting, we need to replace the text at the run level.
from pptx import Presentation
ppt = Presentation(file_path_of_pptx)
search_str = '$$Name1$$'
replace_str = 'Tom'
for slide in ppt.slides:
for shape in slide.shapes:
if shape.has_text_frame:
for paragraph in shape.text_frame.paragraphs:
for run in paragraph.runs:
print(run.text)
if(run.text.find(search_str))!=-1:
run.text = run.text.replace(search_str, replace_str)
ppt.save(file_path_of_new_pptx)
Since PowerPoint splits the text of a paragraph into seemingly random runs (and on top each run carries its own - possibly different - character formatting) you can not just look for the text in every run, because the text may actually be distributed over a couple of runs and in each of those you'll only find part of the text you are looking for.
Doing it at the paragraph level is possible, but you'll lose all character formatting of that paragraph, which might screw up your presentation quite a bit.
Using the text on paragraph level, doing the replacement and assigning that result to the paragraph's first run while removing the other runs from the paragraph is better, but will change the character formatting of all runs to that of the first one, again screwing around in places, where it shouldn't.
Therefore I wrote a rather comprehensive script that can be installed with
python -m pip install python-pptx-text-replacer
and that creates a command python-pptx-text-replacer that you can use to do those replacements from the command line, or you can use the class TextReplacer in that package in your own Python scripts. It is able to change text in tables, charts and wherever else some text might appear, while preserving any character formatting specified for that text.
Read the README.md at https://github.com/fschaeck/python-pptx-text-replacer for more detailed information on usage. And open an issue there if you got any problems with the code!
Also see my answer at python-pptx - How to replace keyword across multiple runs? for an example of how the script deals with character formatting...
I intend to create the following chart using Python PPTX.
Below code achieve the color setting, font size and number format. However, I am not yet able to rotate the data label, as I believe this API is not yet available in python-pptx 0.6.5
lbl = plot.data_labels
lbl.font.size = config["DATA_LABEL_FONT_SIZE"]
lbl.font.color.rgb = config["DATA_LABEL_FONT_COLOR"]
lbl.number_format = config["DATA_LABEL_NUMBER_FORMAT"]
lbl.position = config["DATA_LABEL_POSITION"]
To get started, I have created two minimal slides before and after rotating, and use opc-diag tool to find the diff.
<a:bodyPr rot="-5400000" spcFirstLastPara="1" vertOverflow="ellipsis"
vert="horz" wrap="square" lIns="38100" tIns="19050" rIns="38100"
bIns="19050" anchor="ctr" anchorCtr="1">\n
<a:spAutoFit/>\n </a:bodyPr>\n
I believe I need to add rot="-5400000" XML element to lbl (plot.data_labels), but not clear on how to achieve this. I have used dir(), ._element and .xml on the chart and its children but not able to find <a:bodyPr> tag.
I tried below and it works.
if config["DATA_LABEL_VERTICAL"]:
txPr = lbl._element.get_or_add_txPr()
txPr.bodyPr.set('rot','-5400000')
I have an existing PowerPoint presentation with 20 slides. This presentation serves as an template with each slide having different backgrounds. I want to take this (existing) PowerPoint presentation, insert an image in slide number 4 (do nothing with the first 3) and save it as a new PowerPoint presentation.
This is what I have up until now. This code loads an existing presentation and saves it as a new one. Now I just need to know how to use this to insert an image to slide number 4 like described above.
Note: I am using normal Python.
from pptx import Presentation
def open_PowerPoint_Presentation(oldFileName, newFileName):
prs = Presentation(oldFileName)
#Here I guess I need to type something to complete the task.
prs.save(newFileName)
open_PowerPoint_Presentation('Template.pptx', 'NewTemplate.pptx')
I'm not really familiar with this module, but I looked at their quickstart
from pptx.util import Inches
from pptx import Presentation
def open_PowerPoint_Presentation(oldFileName, newFileName, img, left, top):
prs = Presentation(oldFileName)
slide = prs.slides[3]
pic = slide.shapes.add_picture(img, left, top)
prs.save(newFileName)
open_PowerPoint_Presentation('Template.pptx', 'NewTemplate.pptx',
'mypic.png', Inches(1), Inches(1))