python-pptx icon indicating copy to clipboard operation
python-pptx copied to clipboard

I need move a slide from one ppt to another ppt

Open a6708051 opened this issue 1 year ago β€’ 5 comments

I've a project and one of the requirements is to move a slide from one presentation to another! I use this code, but generated PPT shows an error when opened in PowerPoint.

for shape in slide_to_copy.shapes:
    shape_type = str(shape.shape_type)
    if shape_type.startswith('PICTURE'):
        with io.BytesIO(shape.image.blob) as image_stream:
            left = shape.left
            top = shape.top
            width = shape.width
            height = shape.height
            
            try:
                target_slide.shapes.add_picture(image_stream, left, top, width=width, height=height)
            except Exception as e:
                print(f"An error occurred while adding the picture: {e}")
    else:
        new_shape = deepcopy(shape)
        new_shape.left = shape.left
        new_shape.top = shape.top
        new_shape.width = shape.width
        new_shape.height = shape.height
        target_slide.shapes._spTree.insert_element_before(new_shape.element, 'p:extLst')

a6708051 avatar Dec 18 '24 10:12 a6708051

The supported way is to build a presentation based off the one with the slides already in. I'm not the developer (@scanny is) but I'm sure copying in is not supported. It's actually a rather fiddly process to get all the parts right - which is probably why Powerpoint is unhappy.

MartinPacker avatar Dec 18 '24 10:12 MartinPacker

You can copy presentations slides, here is an example on how you can do this: (tested with: python-pptx 1.0.2 on arch-linux)

def copy_slide(self, source_slide: object, target_presentation: Presentation) -> None:
        """Copies a slide from one presentation to another."""
        source_layout = source_slide.slide_layout
        dest_slide = target_presentation.slides.add_slide(source_layout)

        for shape in source_slide.shapes:
            new_element = deepcopy(shape.element)
            dest_slide.shapes._spTree.insert_element_before(new_element, "p:extLst")

        for rel in source_slide.part.rels.values():
            if "notesSlide" not in rel.reltype:
                target = rel._target
                if "chart" in rel.reltype:
                    partname = target.package.next_partname(ChartPart.partname_template)
                    xlsx_blob = target.chart_workbook.xlsx_part.blob
                    target = ChartPart(
                        partname, target.content_type, deepcopy(target._element), package=target.package,
                    )
                    target.chart_workbook.xlsx_part = EmbeddedXlsxPart.new(xlsx_blob, target.package)
                dest_slide.part.rels._add_relationship(rel.reltype, target, rel.rId)

I also created a program which allows you to copy slides, have a look here: https://gist.github.com/pulgamecanica/0eecf91f92d30724839c0ec85f627352

This tool lets you copy slides between PowerPoint presentations with ease, saving you time and effort. Whether you need to extract specific slides, consolidate content, or build a new presentation from scratch, this program has got you covered!

Features πŸš€

  • Load Multiple Presentations: Seamlessly load PowerPoint presentations (.pptx files).
  • View Slides: Browse through the slides in any loaded presentation.
  • Copy Slides: Copy specific slides to another presentation.
  • Beautiful Console Interface: Thanks to the rich library, enjoy an interactive and visually appealing command-line experience.

How to Use πŸ› οΈ

  1. Run the Program: Start the program by executing the Python script.
  2. Load Presentations: Select "Load a Presentation" and provide the path to your .pptx file.
  3. Copy Slides: Choose a source presentation, select the slide to copy, and decide whether to add it to an existing presentation or create a new one.
  4. Repeat as Needed: Keep loading, copying, and saving to your heart's content!

Requirements πŸ“‹

  • Required Libraries: pptx, rich

Example Output 🌟

Screenshot From 2024-12-24 16-26-42


Screenshot From 2024-12-24 16-27-47

pulgamecanica avatar Dec 24 '24 15:12 pulgamecanica

You can copy presentations slides, here is an example on how you can do this: (tested with: python-pptx 1.0.2 on arch-linux)

def copy_slide(self, source_slide: object, target_presentation: Presentation) -> None:
        """Copies a slide from one presentation to another."""
        source_layout = source_slide.slide_layout
        dest_slide = target_presentation.slides.add_slide(source_layout)

        for shape in source_slide.shapes:
            new_element = deepcopy(shape.element)
            dest_slide.shapes._spTree.insert_element_before(new_element, "p:extLst")

        for rel in source_slide.part.rels.values():
            if "notesSlide" not in rel.reltype:
                target = rel._target
                if "chart" in rel.reltype:
                    partname = target.package.next_partname(ChartPart.partname_template)
                    xlsx_blob = target.chart_workbook.xlsx_part.blob
                    target = ChartPart(
                        partname, target.content_type, deepcopy(target._element), package=target.package,
                    )
                    target.chart_workbook.xlsx_part = EmbeddedXlsxPart.new(xlsx_blob, target.package)
                dest_slide.part.rels._add_relationship(rel.reltype, target, rel.rId)

I also created a program which allows you to copy slides, have a look here: https://gist.github.com/pulgamecanica/0eecf91f92d30724839c0ec85f627352

This tool lets you copy slides between PowerPoint presentations with ease, saving you time and effort. Whether you need to extract specific slides, consolidate content, or build a new presentation from scratch, this program has got you covered!

Features πŸš€

  • Load Multiple Presentations: Seamlessly load PowerPoint presentations (.pptx files).
  • View Slides: Browse through the slides in any loaded presentation.
  • Copy Slides: Copy specific slides to another presentation.
  • Beautiful Console Interface: Thanks to the rich library, enjoy an interactive and visually appealing command-line experience.

How to Use πŸ› οΈ

  1. Run the Program: Start the program by executing the Python script.
  2. Load Presentations: Select "Load a Presentation" and provide the path to your .pptx file.
  3. Copy Slides: Choose a source presentation, select the slide to copy, and decide whether to add it to an existing presentation or create a new one.
  4. Repeat as Needed: Keep loading, copying, and saving to your heart's content!

Requirements πŸ“‹

  • Required Libraries: pptx, rich

Example Output 🌟

Screenshot From 2024-12-24 16-26-42

Screenshot From 2024-12-24 16-27-47

You can copy presentations slides, here is an example on how you can do this: (tested with: python-pptx 1.0.2 on arch-linux)

def copy_slide(self, source_slide: object, target_presentation: Presentation) -> None:
        """Copies a slide from one presentation to another."""
        source_layout = source_slide.slide_layout
        dest_slide = target_presentation.slides.add_slide(source_layout)

        for shape in source_slide.shapes:
            new_element = deepcopy(shape.element)
            dest_slide.shapes._spTree.insert_element_before(new_element, "p:extLst")

        for rel in source_slide.part.rels.values():
            if "notesSlide" not in rel.reltype:
                target = rel._target
                if "chart" in rel.reltype:
                    partname = target.package.next_partname(ChartPart.partname_template)
                    xlsx_blob = target.chart_workbook.xlsx_part.blob
                    target = ChartPart(
                        partname, target.content_type, deepcopy(target._element), package=target.package,
                    )
                    target.chart_workbook.xlsx_part = EmbeddedXlsxPart.new(xlsx_blob, target.package)
                dest_slide.part.rels._add_relationship(rel.reltype, target, rel.rId)

I also created a program which allows you to copy slides, have a look here: https://gist.github.com/pulgamecanica/0eecf91f92d30724839c0ec85f627352

This tool lets you copy slides between PowerPoint presentations with ease, saving you time and effort. Whether you need to extract specific slides, consolidate content, or build a new presentation from scratch, this program has got you covered!

Features πŸš€

  • Load Multiple Presentations: Seamlessly load PowerPoint presentations (.pptx files).
  • View Slides: Browse through the slides in any loaded presentation.
  • Copy Slides: Copy specific slides to another presentation.
  • Beautiful Console Interface: Thanks to the rich library, enjoy an interactive and visually appealing command-line experience.

How to Use πŸ› οΈ

  1. Run the Program: Start the program by executing the Python script.
  2. Load Presentations: Select "Load a Presentation" and provide the path to your .pptx file.
  3. Copy Slides: Choose a source presentation, select the slide to copy, and decide whether to add it to an existing presentation or create a new one.
  4. Repeat as Needed: Keep loading, copying, and saving to your heart's content!

Requirements πŸ“‹

  • Required Libraries: pptx, rich

Example Output 🌟

Screenshot From 2024-12-24 16-26-42

Screenshot From 2024-12-24 16-27-47

I have try! but when i open pptx file, it show me a error! image

a6708051 avatar Jan 06 '25 07:01 a6708051

I believe this happens because the ID is copied as well, you can try and change the name of the slide, also you can ignore the error and still open the presentation.

pulgamecanica avatar Jan 06 '25 07:01 pulgamecanica

The below code has worked for me. Here you can split the presentation into chunks - you can specify the number of chunks and the amount of slides you want for each chunk. Hence if you want the whole presentation - specify 1 chunk with the total number of slides.

This should also work regardless of your operating system (I am on Linux).

from pptx import Presentation
import os

def split_pptx(file: str, dest: str, n: int) -> int:
    """
    Presentation file splitter
    """

    prs = Presentation(file)
    splits = [Presentation(file) for _ in range(0, len(prs.slides), n)]
    slides = [s.slides._sldIdLst[i * n:n * (i + 1)] for i, s in enumerate(splits)]

    for x, rl in enumerate(slides):
        part = splits[x]
        for slide in part.slides._sldIdLst:
            if slide in rl:
                continue
            rId = slide.rId
            part.part.drop_rel(rId)
            del part.slides._sldIdLst[part.slides._sldIdLst.index(slide)]

        part.save(f'{dest}/{x}_{os.path.basename(file)}')

    return len(splits)

if __name__ == '__main__':
    split_pptx(
        file='/path/to/input/presentation.pptx',
        dest='/path/to/output/directory',
        n=1
    )

Hope this helps!

sashaKorovkina avatar Jan 07 '25 10:01 sashaKorovkina

https://github.com/scanny/python-pptx/issues/1036#issuecomment-2561236356

This is really extremely useful. I haven't delved deeply into this library, but I've been trying to copy Slide 1 in PPT1 as Slide 1 in PPT2. I attempted to create a new slide in PPT2 and then create corresponding shapes in the newly created slide according to all the shapes in Slide 1 of PPT1, and also copy the corresponding properties over. However, there are many problems with this approach. For example, the colors are incorrect, the background color is wrong, the shapes are not right, and the groups need to be processed recursively. This is quite complicated and has cost me a lot of time. The code you provided has been of great help to me and has saved me a great deal of time. If possible, I'd like to treat you to a cup of coffee.

wild-deer avatar Apr 25 '25 08:04 wild-deer

#1036 (comment)

This is really extremely useful. I haven't delved deeply into this library, but I've been trying to copy Slide 1 in PPT1 as Slide 1 in PPT2. I attempted to create a new slide in PPT2 and then create corresponding shapes in the newly created slide according to all the shapes in Slide 1 of PPT1, and also copy the corresponding properties over. However, there are many problems with this approach. For example, the colors are incorrect, the background color is wrong, the shapes are not right, and the groups need to be processed recursively. This is quite complicated and has cost me a lot of time. The code you provided has been of great help to me and has saved me a great deal of time. If possible, I'd like to treat you to a cup of coffee.

Any time β˜• hehe If you come to western Europe let me know :)

pulgamecanica avatar Apr 25 '25 08:04 pulgamecanica

I'm wondering about whether this code could be packaged so that my md2pptx's RunPython capability could invoke it. I had been considering writing my own copy function - as a sample. But if it's been done better than I would've done then why would I bother.

Consider open sourcing it as a callable function, please.

MartinPacker avatar Apr 25 '25 08:04 MartinPacker

https://github.com/scanny/python-pptx/issues/1036#issuecomment-2829704590 I will definitely contact you if I travel from East Asia to Western Europe.

wild-deer avatar Apr 25 '25 08:04 wild-deer

    def save_presentation(self, presentation: Presentation, file_path: str) -> None:
        """Saves a presentation to a specified path."""
        presentation.save(file_path)
        console.print(f"[green]Saved presentation to {file_path}[/green]")

There is a small question. Why does the above code throw an exception but can still correctly save the PPT?

wild-deer avatar Apr 25 '25 09:04 wild-deer

What is the exception? I'm sure the owner of the code (not me) needs a little more to go on.

(Also, you've intrigued me with this [green] incantation. Some console control codes?

MartinPacker avatar Apr 25 '25 09:04 MartinPacker

Image ⬇

Image

wild-deer avatar Apr 25 '25 09:04 wild-deer

The exception has been caught, but no information has been output.

wild-deer avatar Apr 25 '25 09:04 wild-deer

Hello folks: Anyone able to fix the above issue?

bazooka720 avatar Jun 26 '25 15:06 bazooka720

@bazooka720 this project accepts contributions by sponsorship only so you'll need to discuss with the author directly to negotiate.

darylteo avatar Jul 04 '25 00:07 darylteo

#coment Pulgamecanica Nice job! We are actualy working on a solution like your one, but we are facing issues when we try to copy masters, and color palette, and to keep image links. Do you have any idea about how to handle it?

Ashitaaka avatar Aug 26 '25 13:08 Ashitaaka