XLWINGS将EXCEL中USED_RANGE转成图片

写了一个函数,基本的需求是把一个表格中的有用的部分转换成图片。自然想到了USED_RANGE,这个在VBA中很常见,但是有个问题,表格中不单纯的只是有文字就叫USED_RANGE,单元格的大小、字体、格式等等修过都都叫USED_RANGE,这样一来,用传统的方法直接COPY到剪切板,再把图片导出来的方法,很容易导致图片有大量的空白边框,很恶心。如果放到网页中直接使用就很难看。因此经历了一下午的研究,借助GPT的智慧写下了以下代码:

def xlsx_to_png(xlsx_name):
    pythoncom.CoInitialize()
    app = xw.App(visible=True, add_book=False)
    try:
        file_path = os.path.abspath(xlsx_name)
        wb = app.books.open(file_path)
        sheet = wb.sheets[0]

        used_range = sheet.used_range
    
        # 遍历列,检查一整列是否都是空单元格
        empty_columns = []
        for column in range(1, used_range.columns.count + 1):
            is_empty_column = True
            for row in range(used_range.row, used_range.last_cell.row + 1):
                cell_value = sheet.cells(row, column).value
                if cell_value is not None and str(cell_value).strip():
                    is_empty_column = False
                    break
            if is_empty_column:
                empty_columns.append(column)

        # 遍历行,检查一整行是否都是空单元格
        empty_rows = []
        for row in range(used_range.row, used_range.last_cell.row + 1):
            is_empty_row = True
            for column in range(used_range.column, used_range.last_cell.column + 1):
                cell_value = sheet.cells(row, column).value
                if cell_value is not None and str(cell_value).strip():
                    is_empty_row = False
                    break
            if is_empty_row:
                empty_rows.append(row)

        # 剔除空列和空行
        first_row = used_range.row
        last_row = used_range.last_cell.row
        first_column = used_range.column
        last_column = used_range.last_cell.column

        for row in empty_rows:
            if row <= last_row:
                first_row += 1
            else:
                last_row -= 1

        for column in empty_columns:
            if column <= last_column:
                first_column += 1
            else:
                last_column -= 1

        used_range = sheet.range((first_row, first_column),
                                 (last_row, last_column))

        used_range.api.CopyPicture()  # 复制图片区域
        sheet.api.Paste()  # 粘贴
        pic = sheet.pictures[-1]  # 当前图片
        pic.api.Copy()  # 复制图片
        time.sleep(3)  # 延迟一下操作,不然获取不到图片
        img = ImageGrab.grabclipboard()
        new_img = Image.new('RGB', img.size, (255, 255, 255))  # 创建新的 RGB 模式图像,并填充为白色
        new_img.paste(img, mask=img.split()[3])  # 将剪贴板中的图像粘贴到新图像上,保留原始图像的透明度通道
        test_pn= '../filestorage/test.png'
        new_img.save(test_pn)  # 保存图片
        pic.delete()  # 删除sheet上的图片
        wb.close()  # 不保存,直接关闭
        app.quit()  # 退出xlwings的app启动
        pythoncom.CoUninitialize()  # 关闭多线程
        return 'success'
    except Exception as e:
        app.quit()
        pythoncom.CoUninitialize()  # 关闭多线程
        return str(e)

GPT在总结算出empty_rows和empty_columns以后就开始各种犯混,又是清除格式又是删除行列,总之都不对,最后给了我这么一段代码
 

for row in empty_rows:
  if row <= last_row:
     last_row -= 1

for column in empty_columns:
  if column <= last_column:
     last_column -= 1

used_range = sheet.range((first_row, first_column), (last_row, last_column))

这段代码让我突然有了灵感,就写出了正确结果。

        for row in empty_rows:
            if row <= last_row:
                first_row += 1
            else:
                last_row -= 1

        for column in empty_columns:
            if column <= last_column:
                first_column += 1
            else:
                last_column -= 1

当空的那行比整个used_range小,说明空的在used_range上方,新used_range的第一行就要加1个;当空的那行比整个used_range大,说明空的在used_range下方,新的used_range的最后一行就要减1个。列也是同理。

由此解决了这个问题。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值