3

New to win32com. Below is my code for converting xlsx file to webpage and capturing the range of cells as .png. The problem I am facing is that some times the code run fine but sometimes it throws errors.

import os
import sys
import win32com.client
from win32com.client.gencache import EnsureDispatch
from win32com.client import constants
from win32com.client import DispatchEx

import PIL
from PIL import ImageGrab


# #---------------------------standalone--------------------------------
path = r'path'
Temp='folder'
#
## ---------------------------------------------------------------------
filename1='Images.html'

images='Images_files'

def A(source):


    xl = EnsureDispatch('Excel.Application')
    wb = xl.Workbooks.Open(yourExcelFile)
    wb.SaveAs(newFileName, constants.xlHtml)
    xl.Workbooks.Close()
    xl.Quit()
    del xl



Allsheets=[]
def B():

    xlApp = win32com.client.DispatchEx('Excel.Application')
    xlApp.Visible = True
    wb = xlApp.Workbooks.Open(os.path.join(path,Temp,source))

    for sh in wb.Sheets:
        Allsheets.append(sh.Name)

    num=1     
    array=["AC7:AF10", "AC28:AF31","AC49:AF52"]
    for sheet_4 in Allsheets[:4]:
        xlApp.Worksheets(sheet_4).Activate()
        win32c = win32com.client.constants
        ws = xlApp.ActiveSheet

        for i in range(len(array)):
            ws.Range(array[i]).CopyPicture(Format=win32c.xlBitmap) 
            img = ImageGrab.grabclipboard()
            img.save(os.path.join(path,Temp,images,'TextBox0'+ f"{num:02}"+'.png'))
            num=num+1



    n=13 
    arry=["K5:M5","X5:Z5","K26:M26","X26:Z26","K47:M47","X47:Z47"]    
    for sheet_name in Allsheets[5:]:

        xlApp.Worksheets(sheet_name).Activate()
        win32c = win32com.client.constants
        ws = xlApp.ActiveSheet

        for i in range(len(arry)):
            ws.Range(arry[i]).CopyPicture(Format=win32c.xlBitmap) 
            img = ImageGrab.grabclipboard()
            img.save(os.path.join(path,Temp,images,'Avg0'+ f"{n:02}"+'.png'))
            n=n+1


    wb.Close(True)
    xlApp.Quit()

for f in os.listdir(os.path.join(path,Temp)):
    if f.endswith('.xlsx'):
        source=f

yourExcelFile = os.path.join(path,Temp,source)
newFileName = os.path.join(path,Temp,filename1)


A(source)
B()

The above code works fine for most of the times but throws the below error for the same input data it was working before. I have tried deleting gen_py and rerunning the code. Have referred almost all the solutions but nothing is clear and working as of now. Please someone suggest a solution.

    img.save(os.path.join(path,Temp,images,'TextBox0'+ f"{num:02}"+'.png'))

AttributeError: 'NoneType' object has no attribute 'save'

5
  • The error means that ImageGrab.grabclipboard() returned None, i. e. the clipboard didn't contain an image. Commented Feb 27, 2020 at 10:31
  • @MaxiMouse but how come how sometimes its returning image and sometimes not. Commented Feb 27, 2020 at 12:08
  • IS your test file always the same? Commented Feb 27, 2020 at 13:53
  • @tst Yes its the same. Commented Feb 28, 2020 at 5:41
  • @MaxiMouse @tst below is the other error which throws sometimes for the same input data.com_error: (-2147352567, 'Exception occurred.', (0, 'Microsoft Excel', 'CopyPicture method of Range class failed', 'xlmain11.chm', 0, -2146827284), None) Commented Feb 28, 2020 at 5:49

1 Answer 1

3

HAHAHA.....,I used to meet this same problem when I use PIL module.

AttributeError: 'NoneType' object has no attribute 'save'

I guess that if you debug this code it could run this code normally,right?

There are two way to handle this:

import time

    time.sleep(1) # sleep for a while 
    img.save(os.path.join(path,Temp,images,'TextBox0'+ f"{num:02}"+'.png'))

Or (I recommend this):

while True:
    try:
        img.save(os.path.join(path,Temp,images,'TextBox0'+ f"{num:02}"+'.png'))
        break
    except AttributeError:
        pass
    except Exception as e:
        print(e.args)
Sign up to request clarification or add additional context in comments.

5 Comments

sleep worked for me. While loop is halting the execution and not proceeding nor stopping the execution.
@PythonBang Have you used break to exit this loop?
No not for loop . as you have suggested used break for try. for i in range(len(arry)): ws.Range(arry[i]).CopyPicture(Format=win32c.xlBitmap) img = ImageGrab.grabclipboard() while True: try: img.save(os.path.join(path,Temp,images,'TextBox0'+ f"{num:02}"+'.png')) break except AttributeError: pass except Exception as e: print(e.args) n=n+1
@PythonBang You have two places that img = ImageGrab.grabclipboard().Do two places use while loop and break?
@jizihihaoSAMA yes it does

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.