[PYTHON] Continuously insert images into PowerPoint running on pywin32

It looks like this ↓

202004272092216.png

Assuming use on Windows, call and execute the .py file from the following powershell cmdlet. The cmdlet name is rather long, but there should be no problem because the completion works.

There is also a more direct way for working with Office products while it's running, but since powershell 6 [System.Runtime.InteropServices.Marshal]: : GetActiveObject () is no longer available, so pywin32 is used instead.

function Add-Image2ActivePptSlideWithPython {
    <#
        .SYNOPSIS
Use pywin32 to continuously insert images into currently open PowerPoint slides
    #>
    if ((Get-Process | Where-Object ProcessName -EQ "POWERPNT").Count -lt 1) {
        return
    }
    $targetPath = @($input).Fullname
    if (-not $targetPath) {
        return
    }

    if ((Read-Host "Is the "Do not compress images in files" setting turned on?(y/n)") -ne "y") {
        return
    }

    $tmp = New-TemporaryFile
    $targetPath | Out-File -Encoding utf8 -FilePath $tmp.FullName #With BOM
    
    #Place the python script described below in the same directory as this script.
    $pyCodePath = "{0}\activeppt_insert-image.py" -f $PSScriptRoot
    'python -B "{0}" "{1}"' -f $pyCodePath, $tmp.FullName | Invoke-Expression
    Remove-Item -Path $tmp.FullName
}

At the beginning, [Disable image compression](https://support.office.com/ja-jp/article/%E7%94%BB%E5%83%8F%E3%81%AE%E5% 9C% A7% E7% B8% AE% E3% 82% 92% E7% 84% A1% E5% 8A% B9% E3% 81% AB% E3% 81% 99% E3% 82% 8B-81a6b603-0266- 4451-b08e-fc1bf58da658) I'm checking if it's done (because if you forget this, the resolution of the inserted image will drop).

On the actual command line, pass the image object you want to insert via the pipeline as shown below.

ls -File | Add-Image2ActivePptSlideWithPython

There is also a way to pass the path of the image passed via the pipeline as an argument, but in that case it is troublesome to escape special characters and the upper limit of the argument, so I write it to a temporary file created with New-TemporaryFile. At this time, even if ʻUTF8` is specified according to the powershell specifications, BOM will be attached, so be careful about the character code.

The called python file should look like this: If you run PowerPoint with PowerPoint running, ʻActivePresentation` will catch the running process. I've made sure the caller has PowerPoint running in advance, but I'm trying to do nothing if the presentation isn't open. Also, if you catch an invisible zombie process, it will terminate the process itself.

activeppt_insert-image.py


"""
Use pywin32 to insert a series of images into the currently open PowerPoint slide
"""
import win32com.client
import argparse

class vb:
    msoFalse        = 0
    msoTrue         = -1
    ppLayoutBlank   = 12

def main(file_list_path):
    pptApp = win32com.client.Dispatch("PowerPoint.Application")
    if pptApp.Presentations.Count < 1:
        if not pptApp.Visible:
            pptApp.Quit()
        return

    with open(file_list_path, "r", encoding="utf_8_sig") as f:
        all_lines = f.read()
    image_path_list = all_lines.splitlines()

    presen = pptApp.ActivePresentation
    slide_width = presen.PageSetup.SlideWidth
    slide_height = presen.PageSetup.SlideHeight

    for img_path in image_path_list:
        slide_index = presen.Slides.Count + 1
        presen.Slides.Add(slide_index, vb.ppLayoutBlank)
        last_slide = presen.Slides(slide_index)
        inserted_img = last_slide.Shapes.AddPicture(
            FileName = img_path,
            LinkToFile = vb.msoFalse,
            SaveWithDocument = vb.msoTrue,
            Left = 0,
            Top = 0
            )
        inserted_img.Left = (slide_width - inserted_img.Width) / 2
        inserted_img.Top = (slide_height - inserted_img.Height) / 2
        print(f"inserted: {img_path}")

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("file_list_path")
    args = parser.parse_args()
    main(args.file_list_path)

Finally

(´-\ ) .. oO (GetActiveObject ()` will be implemented soon ...)

Recommended Posts

Continuously insert images into PowerPoint running on pywin32
Automatically paste images into PowerPoint materials with python + α