Excel に添付された画像をトリムしてPower Pointに張り付ける方法

Excelに画像を張り付けてデータ整理したのち、その画像を資料用にPower Pointに張り付ける方法を紹介します。VBAを使うこともできますが、pythonを使う方法を紹介します。

# pythonのパッケージ準備
pythonでWindows Officeを操作するためのパッケージにwin32comというのがあります。win32comを使えば、VBAでExcelやPower Pointを操作するのと同じようなコードでExcelやPower Pointを操作できます。そこで、準備として、win32comをpipでインストールしてください。

```shell
pip install pywin32
```

#　画像を張り付けたExcelファイル
画像を挿入してExcel上で見やすいように整理します。
Excelに画像を挿入するとVBAではWorkbooks(1).WorkSheets(1).Shapes(number)で取得できます。
画像を挿入した順に数字(number)がつきます。

![Imgur](https://i.imgur.com/GCbim7x.png)

#　pythonコード
win32comを使って、Excelの画像をPower Pointに張り付けます。
pythonとして実行するときは、下記コードをそのまま実行すれば、original.xlsxの画像をpaste.pptxに張り付きます。

ただし、クリップボードを使ってコピーしますので、実行中はctr + Cのコピーが使えなくなると思います。

JUPYTER NOTEBOOKを使う場合は、close_excel_by_forceとclose_ppt_by_forceのコメントアウトを外して、コードを有効にしなれば、ExcelとPower Pointが立ち上がったままになります。プロセスを直接終了させる必要があります。

```python
import win32com.client
import os

def close_excel_by_force(app):
    import win32process
    import win32gui
    import win32api
    import win32con
    import time

    # Get the window's process id's
    hwnd = app.Hwnd
    t, p = win32process.GetWindowThreadProcessId(hwnd)
    # Ask window nicely to close
    win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
    # Allow some time for app to close
    time.sleep(10)
    # If the application didn't close, force close
    try:
        handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, p)
        if handle:
            win32api.TerminateProcess(handle, 0)
            win32api.CloseHandle(handle)
    except:
        pass

def close_ppt_by_force(app):
    import win32process
    import win32gui
    import win32api
    import win32con
    import time

    # Get the window's process id's
    import psutil
    process = [proc for proc in psutil.process_iter() if proc.name() == "POWERPNT.EXE"]
    p = process[0].pid

    # Allow some time for app to close
    time.sleep(10)
    # If the application didn't close, force close
    try:
        handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, p)
        if handle:
            win32api.TerminateProcess(handle, 0)
            win32api.CloseHandle(handle)
    except:
        pass


directory = os.path.dirname(os.path.abspath(__file__))
excelfile = os.path.join(directory, "original.xlsx")
pptfile = os.path.join(directory,"paste.pptx")


try:
    #start power point and excel
    PowerPoint=win32com.client.Dispatch("PowerPoint.Application")
    Excel=win32com.client.Dispatch("Excel.Application")

    #make a powerpoint file and an excel file
    presentation=PowerPoint.Presentations.Add(True)
    workbook=Excel.Workbooks.Open(Filename=excelfile,ReadOnly=1,UpdateLinks=False)

    count =0
    for ws in workbook.Worksheets:
        for chart in ws.Shapes:
            #  Trim a picture
            pf = chart.PictureFormat
            pf.CropLeft = 20
            pf.CropTop = 20

            #copy picture to clipboard
            chart.CopyPicture()

            #Add a new blank slide to Power Point
            Slide=presentation.Slides.Add(presentation.Slides.Count+1,12)

            #paste the picture to the slide
            p = Slide.Shapes.Paste()
            p.Left=100
            p.Top=100

            #Add a text
            textBox = Slide.Shapes.AddTextbox(Orientation=1,
                Left=100,Top=10,Width=200,Height=50)
            textBox.TextFrame.TextRange.Text = "Test Box"
            print(count)
            count = count+1

except Exception as e:
    print("error")
    print(str(e))
finally:
    #save power point file
    presentation.SaveAs(pptfile)
    presentation.Saved=False
    presentation.Close()

    #close the excel file.
    #If "Saved" option is True, the workbook will be closed forcely without checking update.
    #It is becauce it is regarded that the file has already been saved.
    workbook.Saved=True
    workbook.Close()

    print("Finished Copying picutes from Excel to Powerpoint Presentation")

    #quit excel
    Excel.Quit()
    #<caution> when you run this script on jupyter notebook, uncomment the following script line.
    #close_excel_by_force(Excel)
    print("Quit Excel")

    #quit excel
    PowerPoint.Quit()
    #<caution> when you run this script on jupyter notebook, uncomment the following script line.
    #close_ppt_by_force(PowerPoint)
    print("Quit Power Point")

```

# 結果
上記コードを実行するとExcelの画像がトリムされてPower Pointに張り付けれ、次のようになります。

![Imgur](https://i.imgur.com/dZEI30L.png)