6

So it seems there's something weird going on with PIL ImageGrab.grabclipboard()

import win32com.client
from PIL import ImageGrab

o = win32com.client.Dispatch('Excel.Application')
o.visible = False

wb = o.Workbooks.Open(path)
ws = wb.Worksheets['Global Dash']

ws.Range(ws.Cells(1,1),ws.Cells(66,16)).CopyPicture()  
img = ImageGrab.grabclipboard()
imgFile = os.path.join(path_to_img,'test.jpg')
img.save(imgFile)

When I run this, I notice that if I ctrl-V , the image is actually correctly saved on the clipboard, but my img variable returns None, meaning ImageGrab.grabclipboard() is somehow not working. Any ideas?

David Yang
  • 2,101
  • 13
  • 28
  • 46
  • It looks like `PIL` doesn't support the format of the image attached to the clipboard. Try to set a different format: `.CopyPicture(Format:=xlBitmap)` or extract the clipboard with another library. – Florent B. Jun 30 '17 at 16:03
  • got invalid syntax with your arguments, and removing the colon gives me a NameError: 'xlBitmap' is not defined – David Yang Jun 30 '17 at 16:13
  • 1
    The example from my comment is for VBA. You need to convert it to python by providing the missing arguments and constants (`xlBitmap = 2`). – Florent B. Jun 30 '17 at 16:23
  • Right, should have recognized that from the `:= `, thanks! However, still having the same issue as before, while the image is clearly in my clipboard because i can manually paste it, i can't get `ImageGrab.grabclipboard()` to grab anything – David Yang Jun 30 '17 at 16:26

6 Answers6

7

Here I have a solution which might help you.

import excel2img
excel2img.export_img("example.xlsx/example.csv","image.png/image.bmp","sheet!B2:H22")

This is working perfectly for me.

RobC
  • 22,977
  • 20
  • 73
  • 80
1

To clarify those comments of Florent B. and David Yang

Add optional parameter Format into .CopyPicture() will make ImageGrab.getclipboard() work as expected.

The following code will be
ws.Range(ws.Cells(1,1),ws.Cells(66,16)).CopyPicture(Format = 2)

Number 2 is xlBitmap, refer to https://learn.microsoft.com/en-us/office/vba/api/excel.range.copypicture

1

I just replaced ws.Range(ws.Cells(1,1),ws.Cells(66,16)).CopyPicture() by ws.Range(ws.Cells(1,1),ws.Cells(66,16)).Copy() and it worked perfectly.

So this is the entire code.

import win32com.client
from PIL import ImageGrab

o = win32com.client.Dispatch('Excel.Application')
o.visible = False

wb = o.Workbooks.Open(path)
ws = wb.Worksheets['Global Dash']

ws.Range(ws.Cells(1,1),ws.Cells(66,16)).Copy()  
img = ImageGrab.grabclipboard()
imgFile = os.path.join(path_to_img,'test.jpg')
img.save(imgFile)
Dharman
  • 30,962
  • 25
  • 85
  • 135
tem
  • 101
  • 4
  • Got it [Dharman](https://stackoverflow.com/users/1839439/dharman), I'll avoid such phrases in my future contributions. – tem Mar 11 '22 at 14:10
0

I just tried the method posted in the comments under the question and it actually works!
Pay attention to use win32com.client.constants to get the xlBitmap.
In addition, my environment is Python 3.6 and I haven't tried it again in Python 2.7.

win32c = win32com.client.constants
ws.Range(ws.Cells(1,1),ws.Cells(66,16)).CopyPicture(Format= win32c.xlBitmap)

img = ImageGrab.grabclipboard()
imgFile = os.path.join(path_to_img,'test.jpg')
img.save(imgFile)
Kn.Bk
  • 21
  • 4
  • I am getting a AttributeError: xlBitmap error when adding the format = win32c.sxlbitmap – Jim.W Dec 12 '19 at 22:58
0

This solution worked for me. Try to start Excel with:

o = win32com.client.gencache.EnsureDispatch("Excel.Application")

Then use win32com.client.constants to get the xlBitmap

wb = o.Workbooks.Open(workbook_file_name)
ws = wb.Worksheets("Vs. Disk or Retrofit Chart View")
ws.Range(ws.Cells(22,1),ws.Cells(62,8)).CopyPicture(Format= win32com.client.constants.xlBitmap)  
img = ImageGrab.grabclipboard()
imgFile = os.path.join(os.getcwd(),'test.jpg')
img.save(imgFile)
0

The best way to do it is:

import win32com.client
from PIL import ImageGrab

wb_file_name = 'Input.xlsx'
outputPNGImage = 'Output.png'

xls_file = win32com.client.gencache.EnsureDispatch("Excel.Application")

wb = xls_file.Workbooks.Open(Filename=wb_file_name)
xls_file.DisplayAlerts = False 
ws = wb.Worksheets("Desired_Tab")
ws.Range(ws.Cells(1,1),ws.Cells(15,3)).CopyPicture(Format= win32com.client.constants.xlBitmap)  # example from cell (1,1) to cell (15,3)
img = ImageGrab.grabclipboard()
img.save(outputPNGImage)
wb.Close(SaveChanges=False, Filename=wb_file_name)
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 21 '21 at 15:16