暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

python批量导出excel区域图片

染卷 2020-04-13
1872

在python3.7下使用win32com库操作excel文件(需要本地安装有office阅读办公软件),将指定区域复制为图片,并批量保存下来。如果只是需要纯粹导出excel里面的图片建议使用本站另一篇文章介绍的方法:python导出excel中所有图片(写入excel数据) 另外,本片也是在该文的基础上改进而来。

在调试过程中也遇到很多的报错,建议在使用时关闭不必要的程序,如果报excel程序错误可能是excel文件被占用,建议在任务管理器里面关闭所有excel进程!如果出现图片为空建议加上sleep延时,防止剪切板操作过快取不到数据,期间遇到的报错信息已附于代码正文及文章末尾。下面上python源码(源码中夹杂了python使用pypiwin32库操作的代码,已经注释了,有需要的也可以看看):

  1. import win32com.client as win32 # 打开excel文件

  2. #pip install pypiwin32

  3. ##########import openpyxl #另一种操作excel的包

  4. import time

  5. import pythoncom,os

  6. from PIL import ImageGrab   #用于获取复制的图片



  7. file='312(带图片).xlsx'

  8. file_name = os.path.abspath(file)  # 把相对路径转成绝对路径


  9. #pythoncom.CoInitialize()  # 开启多线程


  10. excel = win32.Dispatch('Excel.Application') #获取Excel

  11. #excel = DispatchEx("Excel.Application")  #启动excel

  12. excel.Visible = True #可视化

  13. #excel.DisplayAlerts = False  #是否显示警告 (保存时不会弹出窗口)

  14. #excel.ScreenUpdating = 1    # 关闭屏幕刷新

  15. wb2 = excel.Workbooks.Open(file_name)

  16. ws2 = wb2.Worksheets('Sheet1')        # 获取Sheet1

  17. info = ws2.UsedRange#获取有效数据区域

  18. nrows = info.Rows.Count #总行数

  19. #ncols = info.Columns.Count #总列数

  20. max_excel_row = nrows+1



  21. #pic_shape_name = range(1000)#初始化1000个数组,后面用于copy图片Shapename用

  22. pic_shape_name = []

  23. for n in range(1000):

  24.    pic_shape_name.append('mypic_'+str(n))




  25. ##########wb = openpyxl.load_workbook(file_name)

  26. ##########ws = wb.active

  27. #get_highest_row()和get_highest_column()在最新版的openpyxl模块中已经被删除了

  28. #取而代之的是max_row和max_column两个方法

  29. #max_excel_row = int(format(ws.max_row))+1




  30. i =1

  31. j = 0

  32. for i in range(1,max_excel_row):#excel行循环

  33.    #name = str(ws.cell(i,3).value)#openpyxl模块读取excel的方式,第三列

  34.    name = ws2.Range('C'+str(i)).Value

  35.    #注意openpyxl与win32com读取excel,如果遇到空值可以用 if is not None 来判断

  36.    #或者将读取到的值强制转换为str字符,会变成字符串'None'



  37.    #price_p = str(ws.cell(i,4).value)#第四列

  38.    price_p = ws2.Range('D'+str(i)).Value


  39.    #sku_class = str(ws.cell(i,1).value)#第一列 7寸

  40.    sku_class = ws2.Range('A'+str(i)).Value


  41.    if name is not None and name != 'None' and  price_p !='' and price_p !='单价' and price_p !='None':

  42.        j = j+1

  43.        #ws.Range('B2:B2').CopyPicture()    # 复制D1:I17图片区域

  44.        #time.sleep(5)

  45.        #ws2.Range('B33:B33').CopyPicture()

  46.        ws2.Range('B'+str(i)+':B'+str(i)).CopyPicture()


  47.        ws2.Paste()  #直接粘贴可以

  48.        #ws2.Paste(ws2.Range('K'+str(i)))    # 将图片移动到K列,如果移动图片后面会导致所有复制出的图片都一模一样!

  49.        pic_name0 =  str(j) + '.png'

  50.        print('正在写入第('+str(i)+'/'+str(max_excel_row-1)+')个商品:'+ name +' 的图片文件:'+ pic_name0)

  51.        #TypeError: can only concatenate str (not "NoneType") to str


  52.        excel.Selection.ShapeRange.Name = pic_shape_name[j] # 选择区域重命名

  53.        #time.sleep(2)

  54.        ws2.Shapes(pic_shape_name[j]).Copy()    # 复制移动的图片Picture 1


  55.        img = ImageGrab.grabclipboard()  # 获取图片数据

  56.        print('正在保存图片单元格为:'+ 'B'+str(i)+':B'+str(i))


  57.        try:

  58.            #img.save(image, "JPEG")

  59.            img.save(pic_name0) # 图片另存为

  60.        except AttributeError:

  61.            print("Couldn't save image {}".format(pic_name0))


  62.        #img.save(root_path + pic_name0) # 图片另存为

  63.        #报错123 180个图片 AttributeError: 'NoneType' object has no attribute 'save'

  64.        #    ws2.Shapes(pic_shape_name[j]).Copy()    # 复制移动的图片Picture 1

  65.        #  File "C:\Users\joolan\AppData\Local\Temp\gen_py\3.7\00020813-0000-0000-C000-000000000046x0x1x9\Shape.py", line 52, in Copy

  66.        #return self._oleobj_.InvokeTypes(551, LCID, 1, (24, 0), (),)

  67.        #pywintypes.com_error: (-2147352567, '发生意外。', (0, None, None, None, 0, -2147221040), None)

  68.        #

  69.        #pywintypes.com_error: (-2147352567, '发生意外。', (0, 'Microsoft Excel', '类 Worksheet 的 Paste 方法无效', 'xlmain11.chm', 0, -2146827284), None)


  70.        #File "C:\Python37\lib\site-packages\win32com\client\__init__.py", line 467, in _ApplyTypes_

  71.        #self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, *args),

  72.        #pywintypes.com_error: (-2147352567, '发生意外。', (0, 'Microsoft Excel', '类 Range 的 CopyPicture 方法无效', 'xlmain11.chm', 0, -2146827284), None)

  73.        #pywintypes.com_error: (-2147352567, '发生意外。', (0, 'Microsoft Excel', '类 Workbook 的 SaveAs 方法无效', 'xlmain11.chm', 0, -2146827284), None)




  74.        #time.sleep(1)

  75.        #if j > 5:

  76.        #    exit()



  77. print('写入有效商品图片个数:'+str(j))



  78. wb2.SaveAs('copy.xlsx') # excel文件另存为copy.xlsx

  79. wb2.Close() #关闭工作薄,不保存

  80. excel.Quit()  #退出excel


  81. #pythoncom.CoUninitialize()  # 关闭多线程


本例excel文件结构内容如下(python操作方法为将单元格区域复制为图片的方式,所以保存图片的质量取决于你excel中直观看到的图片大小,如果只想导出图片建议使用文章开篇推荐的方法!):


下面是使用python保存excel图片中遇到的一些错误提示,如果严格按照我上面的代码运行,一般是不会有问题的,已经连续测试3次,导出200+图片没问题。

  1. TypeError: can only concatenate str (not "NoneType") to str 执行操作过程中取到了空单元格,但是没有对值进行is not None 或 != 'None'判断


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

  3. 如果你想将图片保存出来(且图片超过一张)建议直接使用ws.Paste() ,而不要使用类似ws.Paste(ws.Range('K'+str(i)))这种在excel内黏贴到指定单元格的操作!否则会导致后面的excel.Selection.ShapeRange.Name选择区重命名失效,结果就是使用python复制出的excel图片除了名字,内容完全是一模一样的图片


  4. pywintypes.com_error: (-2147352567, '发生意外。', (0, None, None, None, 0, -2147221040), None)

  5. pywintypes.com_error: (-2147352567, '发生意外。', (0, 'Microsoft Excel', '类 Worksheet 的 Paste 方法无效', 'xlmain11.chm', 0, -2146827284), None)


  6. pywintypes.com_error: (-2147352567, '发生意外。', (0, 'Microsoft Excel', '类 Range 的 CopyPicture 方法无效', 'xlmain11.chm', 0, -2146827284), None) 在使用ws.Range('xx:xx').CopyPicture()时被复制的单元格内容为空,或目标单元格颜色是纯色。遇到这种情况最好每次复制时打印出excel行,然后打开excel文件定位看一下该单元格是否存在异常。


  7. pywintypes.com_error: (-2147352567, '发生意外。', (0, 'Microsoft Excel', '类 Workbook 的 SaveAs 方法无效', 'xlmain11.chm', 0, -2146827284), None) 目标excel文件已存在,无法保存文件


基于互联网精神,在注明出处的前提下本站文章可自由转载!

本文链接:https://ranjuan.cn/python-save-excelarea-pic/


文章转载自染卷,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论