Ejemplo n.º 1
0
def PPT_convertor(filepath):
    try:
        Application = win32com.client.Dispatch("PowerPoint.Application")
        Application.Visible = True
        if filepath.endswith(".ppt"):
            new_filepath = filepath.replace(".ppt", r".pptx")
        elif filepath.endswith(".pps"):
            new_filepath = filepath.replace(".pps", r".pptx")
        Presentation = Application.Presentations.Open(filepath)
        Presentation.Saveas(new_filepath)
        Presentation.Close()
        return new_filepath
    except Exception as e:
        print(e)
    finally:
        Application.Quit()
Ejemplo n.º 2
0
def grab_slides(files_slides_messages, file_slide_sizes, output_directory):

    if not Path(output_directory).is_dir():
        raise Exception(
            'Must input a directory in which to output the slide files.')
    dt_string = nm.get_YYYYMMDDHHMMSS_string(datetime.now(), '-', '_')
    output_directory = Path(output_directory) / dt_string
    output_directory.mkdir()

    sizes_and_files = {}
    for file_path in files_slides_messages.keys():
        if file_slide_sizes[file_path] in sizes_and_files.keys():
            sizes_and_files[file_slide_sizes[file_path]].append(file_path)
        else:
            sizes_and_files[file_slide_sizes[file_path]] = [file_path]

    ppt_instance_old = win32com.client.Dispatch('PowerPoint.Application')
    ppt_instance_new = win32com.client.Dispatch('PowerPoint.Application')

    for size in sizes_and_files.keys():

        ########### Copy the first file as the new slide destination file ###########
        first_path = sizes_and_files[size][0]
        new_prs = Presentation(first_path)

        # Helps to prevent loading of the same file's slide master multiple times
        design_index_cache = {}

        # Add successful search details messages to slide notes of first presentation
        for index_slide, message in files_slides_messages[first_path]:
            if new_prs.slides[index_slide].has_notes_slide:
                notes_text = new_prs.slides[
                    index_slide].notes_slide.notes_text_frame.text
                new_prs.slides[
                    index_slide].notes_slide.notes_text_frame.text = message + notes_text
            else:
                new_prs.slides[
                    index_slide].notes_slide.notes_text_frame.text = message

        # Delete the slides not wanted
        first_path_indices = [
            files_slides_messages[first_path][ind][0]
            for ind in range(len(files_slides_messages[first_path]))
        ]
        delete_slides = [
            i for i in range(len(new_prs.slides))
            if i not in first_path_indices
        ]
        new_prs = delete_slides_by_indices(new_prs, delete_slides)

        file_name = 'w={},h={}_{}.pptx'.format(size[0], size[1], dt_string)
        file_path = str(Path(output_directory) / file_name)
        new_prs.save(file_path)

        # Then open it with a windowless Powerpoint instance
        read_only, has_title, window = False, False, False
        new_prs = ppt_instance_new.Presentations.open(file_path, read_only,
                                                      has_title, window)

        ########### For each original presentation other than the one already dealt with... ###########
        for path_to_presentation in sizes_and_files[size]:
            if path_to_presentation == first_path:
                continue
            else:
                if not isinstance(files_slides_messages, dict) or not Path(
                        path_to_presentation).exists() or not isinstance(
                            files_slides_messages[path_to_presentation], list):
                    raise Exception(
                        'files_slides_messages must be a dictionary with keys as filepaths and values as lists of corresponding slide indices to grab.'
                    )
                # ... open it with another windowless Powerpoint instance
                old_prs = ppt_instance_old.Presentations.open(
                    path_to_presentation, read_only, has_title, window)

                # ... and copy-paste each requested slide from old to new (some pastes fail for unknown reason, so repeat up to 10 times)
                for slide_number_zero_indexing, message in files_slides_messages[
                        path_to_presentation]:
                    insert_index = -1
                    repeat = 1
                    while repeat < 10:
                        try:
                            old_prs.Slides(slide_number_zero_indexing +
                                           1).Copy()
                            new_prs.Slides.Paste(Index=insert_index)
                            repeat = 10
                        except:
                            repeat += 1
                    if path_to_presentation not in design_index_cache.keys():
                        new_prs.Designs.Load(path_to_presentation)
                        design_index_cache[path_to_presentation] = len(
                            list(new_prs.Designs)) - 1
                    new_prs.Slides(len(new_prs.Slides)).Design = list(
                        new_prs.Designs)[
                            design_index_cache[path_to_presentation]]

                    # append search messages to each slide's notes
                    notes_text = new_prs.Slides(len(
                        new_prs.Slides)).NotesPage.Shapes.Placeholders(
                            2).TextFrame.TextRange.Text
                    new_prs.Slides(len(
                        new_prs.Slides)).NotesPage.Shapes.Placeholders(
                            2).TextFrame.TextRange.Text = message + notes_text
                old_prs.Close()

        n_slides = len(new_prs.Slides)
        new_prs.SaveAs(file_path)
        new_prs.Close()
        print('Successfully output {} slides to {}'.format(
            n_slides, file_path))

    # Kill ppt_instances
    ppt_instance_new.Quit()
    del ppt_instance_new
    # ppt_instance_old.Quit()
    del ppt_instance_old