Search code examples
pythonxlsxwriter

xlsxwriter: how to center image in cell


Im setting the size of my column and rows using set_column and set_row respectively, like so:

my_worksheet.set_column('A:KK', 17)
my_worksheet.set_row(0, 99.6)

I have this code to print an image of arbitrary size to the cell:

width, height = im.size
# Calculate scale: Problematic
x_scale = IMAGE_CELL_SIZE_PX[0]/float(width) 
y_scale = (IMAGE_CELL_SIZE_PX[1] - 5.0)/float(height)
# Calculate offset: Problematic
x_offset = ((IMAGE_CELL_SIZE_PX[0] - width) / 2.0) / x_scale
y_offset = ((IMAGE_CELL_SIZE_PX[1] - 5 - height) / 2.0) / y_scale
worksheet.insert_image(row, col, image_path, {'x_offset': x_offset, 'y_offset': y_offset, 'x_scale': x_scale, 'y_scale': y_scale})

problem is it doesnt work. The image size is wrong and the pictures are most of the time far from centered. It's like Im missing a term. The main issue is that I cannot find a way to convert from pixels to Excel's and xlsxwriter length unit robustly in a machine independent way.

I can only set the width of the cells through set_column which takes excel units and I know the image dimensions in pixels (from Pillow Image.size). Apparently the transformation between the two is machine dependent. Any ideas?


Solution

  • You can use the worksheet._size_col() and worksheet._size_row() (see here in the code) which converts a column or row zero-based index to a pixel size.

    The other thing to look out for is that Excel scales images based on a DPI of 96. If the image has another DPI you should account for the scaling. This is what happens internally in XlsxWriter to account for Excel's scaling:

        # Scale by non 96dpi resolutions.
        width *= 96.0 / x_dpi
        height *= 96.0 / y_dpi