(Изменить: это было с Python 3.7 и openpyxl 2.6.1)
Итак, я открыл переименованный выходной файл Excel в zip-файл и обнаружил там «Drawing1.xml», где я мог видеть, что он использует OneCellAnchor. Поэтому, следуя совету Чарли, я углубился в код openpyxl и обнаружил, что есть класс AbsoluteAnchor, который я могу использовать. Чтобы установить позиции, мне нужно было импортировать координаты XDR, а затем из utils.units некоторые функции преобразования из пикселя / см в EMU (единицы измерения Excel?). Затем я просто установил привязку изображения к абсолюту и дал положение и «ext» (размеры).
from openpyxl import Workbook
from openpyxl.drawing.image import Image
from openpyxl.drawing.spreadsheet_drawing import AbsoluteAnchor
from openpyxl.drawing.xdr import XDRPoint2D, XDRPositiveSize2D
from openpyxl.utils.units import pixels_to_EMU, cm_to_EMU
wb = Workbook()
ws = wb.active
img = Image('image.png')
p2e = pixels_to_EMU
h, w = img.height, img.width
positie = XDRPoint2D(p2e(500), p2e(500))
size = XDRPositiveSize2D(p2e(h), p2e(w))
img.anchor = AbsoluteAnchor(pos=position, ext=size)
ws.add_image(img)
wb.save('test.xlsx')
Но это все равно будет проблематично, так как мне нужно будет знать абсолютные координаты для КАЖДОГО изображения, которое я хочу разместить ... в идеале, я все еще хочу привязать его к ячейке, но затем иметь возможность более точно перемещать его внутри клетка. Именно тогда я заметил, что OneCellAnchor имеет аргумент смещения. Это было прекрасно, тогда я сделал лямбда-функции с измеренной сантиметровой высотой и шириной стандартных ячеек Excel.
from openpyxl.drawing.spreadsheet_drawing import OneCellAnchor, AnchorMarker
c2e = cm_to_EMU
# Calculated number of cells width or height from cm into EMUs
cellh = lambda x: c2e((x * 49.77)/99)
cellw = lambda x: c2e((x * (18.65-1.71))/10)
# Want to place image in row 5 (6 in excel), column 2 (C in excel)
# Also offset by half a column.
column = 2
coloffset = cellw(0.5)
row = 5
rowoffset = cellh(0.5)
marker = AnchorMarker(col=column, colOff=coloffset, row=row, rowOff=rowoffset)
img.anchor = OneCellAnchor(_from=marker, ext=size)
ws.add_image(img)
wb.save('test.xlsx')
Который производит:
Отлично! Именно точность, которую я искал:)