在使用影刀的指令【单元格填充图片】时,会有两种问题:
1. 悬浮状态无法嵌入单元格,不方便灵活地调整表格的列宽行高;
2. 会有偏移,且数量多时,偏移堆积也越来越多,不便于直观地查看;
在社区搜一下相关的问题,其实大家都苦于此些问题,也先后有了许多小伙伴分享了自己的经验,实现了图片的嵌入、半嵌入、解决偏移等效果。这些文章都很棒,但当我去尝试这些解决方案的时候,发现使用起来还是不够方便。于是对大家的经验进行了整合,希望可以给出一个更方便大家使用的方式。
结合了咱们社区的两篇优质分享文章:
1. https://www.yingdao.com/community/detaildiscuss?id=74ea5df1-c9e0-4670-ba6f-066c84e19e04 ,对其中插入图片的代码进行了改进,实现了单元格列宽行高的自适应;
2. https://www.yingdao.com/community/detaildiscuss?id=b711966c-f121-4bae-943b-1264cd75733a 结合其中的第三点,使用键盘输入的方式,但通过代码来实现;
整合版的结果如下:
import xbot
from xbot import print, sleep
from .import package
from .package import variables as glv
import win32clipboard as w
import win32con
from PIL import Image
import pyautogui
import time
class Clipboard:
@staticmethod
def getText():
w.OpenClipboard()
d = w.GetClipboardData(win32con.CF_UNICODETEXT)
w.CloseClipboard()
return d
@staticmethod
def setText(aString):
w.OpenClipboard()
w.EmptyClipboard()
w.SetClipboardData(win32con.CF_UNICODETEXT, aString)
w.CloseClipboard()
def add_picture(excel_instance, row_num, column_name, image_path, height=None, width=None):
"""
Excel通过公式插入图片
:param excel_instance: excel_instance, excel对象
:param row_num: int, 行号
:param column_name: str, 列名
:param image_path: str, 图片的路径
:param height: int 行高(非必填)
:param width: int 列宽(非必填)
"""
sht = excel_instance.workbook.ActiveSheet
# 获取图片的实际尺寸
with Image.open(image_path) as img:
original_width, original_height = img.size
# 使用列宽来计算图片的宽度和高度
if width is not None:
img_width = int(width) * 7.5 # 将列宽转换为点
img_height = int(img_width) / (original_width / original_height)
else:
img_width = original_width
img_height = original_height
# 如果没有提供行高,则使用计算出的图片高度
if height is None:
height = img_height
content = f'<table style="border-collapse: collapse;"><td style="padding: 5px;"><img src="{image_path}" width="{int(img_width)}" height="{int(img_height)}"></td></table>'
sht.Range(f"{column_name}{row_num}").Activate()
sht.Range(f"{column_name}{row_num}").Select()
Clipboard.setText(content)
# 直接调用 PasteSpecial 而不赋值给变量
sht.PasteSpecial(Format="Unicode 文本")
range_selection = sht.Range(f"{column_name}{row_num}")
# 设置行高和列宽
range_selection.RowHeight = height
if width is not None:
range_selection.ColumnWidth = width
range_selection.Borders.LineStyle = 1
time.sleep(0.5)
# 按下 Ctrl+G
pyautogui.hotkey('ctrl', 'g')
# 按 B
pyautogui.press('b')
# 按 T
pyautogui.press('t')
time.sleep(0.5)
# 按下 Alt+7
pyautogui.hotkey('alt', '7')
'''
也可以用影刀键盘
win32.send_keys(keys='^{g}',send_key_delay=50,delay_after=0)
win32.send_keys(keys='b',send_key_delay=50,delay_after=0)
win32.send_keys(keys='t',send_key_delay=50,delay_after=0.5)
win32.send_keys(keys='!{7}',send_key_delay=50,delay_after=1)
'''

1. 仅适用于 WPS,需要在 WPS 的 【文件】-【选项】-【快速访问工具栏】-【查找命令“嵌入”】-【添加】,打开热键。

2. 将上述的代码拷贝,在影刀中新建一个 Python 文件,粘贴进去。这里面涉及到一些需要手动安装的第三方库,如 Pillow、PyAutoGUI 等,需要在 Python 包管理中手动安装。
3. 回到指令中,调用你新建的 Python 模块,选择 add_pictyure 这个行数。调用模块时,height 和 width 两个参数分别是 行高 和 列宽,非必填项。如果想要自适应,保持默认的 None 即可。

4. 建议在 WPS 表格关闭的状态下,再运行影刀应用。