I apologize, I have been looking for a solution but can't find enough documentation to figure it out. I am trying to import a default slide layout required for school, it has a special background and a Title Block and a Subtitle Block. I assumed when I import this, python-pptx would just automatically create placeholders 0 and 1 for those two text blocks but when I try and edit the placeholders, I get an attribute error:
AttributeError: 'Presentation' object has no attribute 'placeholders'
My code is as follows:
from pptx import Presentation
prs = Presentation('SeniorDesignTitleSlide.pptx')
Presentation_Title = prs.placeholders[0]
Presentation_Subtitle = prs.placeholders[1]
Presentation_Title.text = 'This Is a Test'
Presentation_Subtitle.text = 'Is This Working?'
prs.save('SlideLayoutImportTest.pptx')
Edit[0]: I do realize I am just opening that particular presentation, but how do I access and edit the single slide that’s in it ?
Edit[1]: I’ve found a few posts from 2015 about python-pptx expanding on this feature, but there’s no further information that it actually occurred.
How does python-pptx assign placeholders for imported slide layouts? Or does it even do this? Does it need to be a .potx file?
Thank you in advance.
Placeholders belong to a slide object, not a presentation object. So the first thing is to get ahold of a slide.
A slide is created from a slide layout, which it essentially clones to get some starting shapes, including placeholders in many cases.
So the first step is to figure out which slide layout you want. The easiest way to do this is to open the "starting" presentation (sometimes called a "template" presentation) and inspect it's slide master and layouts using the View > Master > Slide Master... menu option.
Find the one you want, count down to it from the first layout, starting at 0, and that gives you the index of that slide layout.
Then your code looks something like this:
from pptx import Presentation
prs = Presentation('SeniorDesignTitleSlide.pptx')
slide_layout = prs.slide_layouts[0] # assuming you want the first one
slide = prs.slides.add_slide(slide_layout)
Presentation_Title = slide.placeholders[0]
Presentation_Subtitle = slide.placeholders[1]
Presentation_Title.text = 'This Is a Test'
Presentation_Subtitle.text = 'Is This Working?'
prs.save('SlideLayoutImportTest.pptx')
The placeholders collection behaves like a dict as far as indexed access goes, so the 0 and 1 used as indices above are unlikely to match exactly in your case (although the 0 will probably work; the title is always 0).
This page of the documentation explains how to discover what indices your template has available: http://python-pptx.readthedocs.io/en/latest/user/placeholders-using.html
The page before that one has more on placeholder concepts:
http://python-pptx.readthedocs.io/en/latest/user/placeholders-understanding.html
Related
I am working on my final year project, so I working on a website where a user can come and read PDF, I am adding some features such as converting currency to their country currency, I am using flask and pymuPDF for my project and I don't know how I can modify the text at a pdf
anyone can help me with this problem
I heard here that using pymuPDF or pypdf2 can work, but I didn't find any solution for replacing text
Using the redaction facility of PyMuPDF is probably the adequate thing to do.
The approach:
Identify the location of the text to replace
Erase the text and replace it using redactions
Care must be taken to get hold of the original font, and whether or not the new text is longer / short than the original.
import fitz # import PyMuPDF
doc = fitz.open("myfile.pdf")
page = doc[number] # page number 0-based
# suppose you want to replace all occurrences of some text
disliked = "delete this"
better = "better text"
hits = page.search_for("delete this") # list of rectangles where to replace
for rect in hit:
page.add_redact_annot(rect, better, fontname="helv", fontsize=11,
align=fitz.TEXT_ALIGN_CENTER, ...) # more parameters
page.apply_annots(images=fitz.PDF_REDACT_IMAGE_NONE) # don't touch images
doc.save("replaced.pdf", garbage=3, deflate=True)
This works well with short text and medium quality expectations.
With some more effort, the original font properties, color, font size, etc. can be identified to produce a close-to-perfect result.
I created a Map using python folium in jupyter lab. On the Map I display some geoJson-Files as shapes.
What Works so far:
The Shapes from the GeoJson file are displayed nicely on the map. I can change the color of the shapes based on a self generated style_function which checks feature['properties']['id'] to adjust the style type accordingly.
I'm also able to get a GeoJsonPopup on_click to a shape. The Popup shows id and the content of the id property of that shape.
geo_popup = folium.GeoJsonPopup(fields=['id'])
my_json = folium.GeoJson(file.path, style_function=style_function, popup=geo_popup)
my_json.add_to(map)
What I want:
I want to display in the popup some content based on the id. Very basic Example: if id = 1 i want to display 'This is the region Alpha' or if id = 2 -> 'This area is beautiful'.
Alternatively, if that is not possible, I would like to present a Link in the Popup where i can Access a Page with a parameter to show dedicated content for that id.
What I tried
I tried to derive a class from folium.GeoJsonPopup and somehow write content to the render function. But, however, I don't really get how it works and therefor all I did wasn't successful. Probably I took somewhere the wrong path and the solution is pretty easy.
Thanks for advice!
I followed the linked sample in the comment to the question. Therefore I had to add the needed dict entries to the the features properties.
Therefore I can link to this question. I used the .update from the solutions last comment to add the values.
I'm trying to print out a slide from Powerpoint. I've accessed the slide using the following code:
from win32com import client
powerpoint = client.Dispatch("Powerpoint.Application")
presentation = powerpoint.presentations.Open(filepath)
slide = presentation.Slides[10]
print(slide.name) # Just to check I have in fact got the slide
When printing Word docs I can just call PrintOut() on the document but it doesn't seem to work for Powerpoint.
Does anyone have any solutions?
presentation.PrintOut()
prints the entire presentation, but I just want a specific slide.
Ok I figured out I can specify a range using:
presentation.PrintOut(From=1, To=1)
And I can iterate the slides to match the name using a loop:
count = 1
for slide in presentation.Slides:
if slide.name == "Slide1":
presentation.PrintOut(From=count, To=count)
break
count += 1
I am new with python-pptx. But I am familiar with its basic working. I have searched a lot but I could not find a way to change a particular text by another text in all slides. That text may be in any text_frame of a slide. like all slides in a ppt have 'java' keyword, I want to change it by 'python' using python pptx in slides.
for slide in ppt.slides:
if slide.has_text_frame:
#do something with text frames
Something like this should help, you'll need to iterate the shape objects in each slide.shapes and check for a TextFrame and the existence of your keyword:
def replace_text_by_keyword(ppt, keyword, replacement):
for slide in ppt.slides:
for shp in slide.shapes:
if shp.has_text_frame and keyword in shp.text:
thisText = shp.text.replace(keyword, replacement)
shp.text = thisText
This example is just a simple str.replace of course if you have more complicated replacement/text-updating algorithm, you can modify as needed.
In addition when replacing text, you cannot simply replace it, you will loose all formatting.
Your text is contained in text_frame. Text_frame contain paragraphs, and paragraphs are made up of runs. A run contains all your formatting. You need to get to paragraph, then the run, then update text.
"A run exists to provide character level formatting, including font typeface, size, and color, an optional hyperlink target URL, bold, italic, and underline styles, strikethrough, kerning, and a few capitalization styles like all caps." (see reference below)
You'll need to do something like this:
prs = Presentation('data/p1.pptx')
for slide in prs.slides:
for shape in slide.shapes:
if not shape.has_text_frame:
continue
for paragraph in shape.text_frame.paragraphs:
for run in paragraph.runs:
run.text=newText(run.text)
prs.save('data/p1.pptx')
Official documentation(working with text): python-pptx.readthedocs.io
Visual representation of what this means Duplicate post
I am trying to use an existing template design of powerpoint using python-pptx library. My problem is that I have two or more different templates ready and when I viewed their slide master, the "title and content layout" of each template are not on the same order. So, the index that I will use will be 1 if I used the first templates and 2 for the second templates.
Using the python-pptx library:
Sample Python Code 1 for fist templates
bullet_slide_layout = self.prs.slide_layouts[1]
Sample Python Code 2 for second templates
bullet_slide_layout = self.prs.slide_layouts[2]
Both of them works, but I do not want to change the indices every now and then whenever a new template design is added.
Please help. Also, If I am not clear with the problem I presented, please tell me. Thank you
If you want to retrieve a slide layout by something other than its position in the layout sequence, you will have to write something of your own.
There are a few approaches:
Use the slide layout name
Use the slide layout id
Characterize the slide by the number and type of placeholders it contains and perhaps their size and position.
So as an example, something simple would be:
def get_layout_by_name(prs, layout_name):
for layout in prs.slide_layouts:
if layout.name == layout_name:
return layout
return None