[Python] pixel to excel cell conversion by xlwings

Discussão em 'Python' iniciado por Stack, Março 4, 2025.

  1. Stack

    Stack Membro Participativo

    I am trying to convert pixel value to spreadsheet cell_id, but the conversion is not exact, meaning it's not so close, any idea what is wrong with my code ?

    import xlwings as xw
    from openpyxl.utils import get_column_letter

    def column_width_to_pixels(column_width):
    """Convert Excel column width to pixels (including extra padding)."""
    return int((column_width + 0.71) * 7) + 2 # Add 2 pixels for Excel padding

    def row_height_to_pixels(row_height):
    """Convert Excel row height (points) to pixels (including padding)."""
    return int(row_height * (96 / 72)) + 2 # Add 2 pixels for Excel rendering offset


    def find_exact_excel_cell(file_path, sheet_name, left_px, top_px):
    """
    Converts image pixel position (left_px, top_px) into the closest Excel cell.
    Uses accurate width and height calculations.
    """
    app = xw.App(visible=False) # Prevent Excel UI from opening
    wb = xw.Book(file_path)
    ws = wb.sheets[sheet_name]

    x_offset = 0 # Tracks total width in pixels
    y_offset = 0 # Tracks total height in pixels

    target_col = None
    target_row = None

    # Retrieve total columns and rows
    total_cols = ws.used_range.columns.count
    total_rows = ws.used_range.rows.count

    # Find the closest column (X position)
    for col in range(1, total_cols + 1): # xlwings uses 1-based index
    col_letter = get_column_letter(col) # Convert to 'A', 'B', etc.
    col_width = ws.range(f"{col_letter}1").column_width
    col_pixel_width = column_width_to_pixels(col_width) # Convert width to pixels

    if x_offset <= left_px < (x_offset + col_pixel_width): # If image falls in this range
    target_col = col_letter
    break
    x_offset += col_pixel_width # Move to next column boundary

    # Find the closest row (Y position)
    for row in range(1, total_rows + 1):
    row_height = ws.range(f"A{row}").row_height
    row_pixel_height = row_height_to_pixels(row_height) # Convert height to pixels

    if y_offset <= top_px < (y_offset + row_pixel_height): # If image falls in this range
    target_row = row
    break
    y_offset += row_pixel_height # Move to next row boundary

    wb.close()
    app.quit()

    if target_col and target_row:
    return f"{target_col}{target_row}"
    else:
    return None # Image is outside valid cell range


    I have exported to image by following code:

    app = xw.App(visible=False)
    # Open the Excel workbook
    wb = app.books.open(file_name)

    sheet = wb.sheets[0]
    sheet.page_setup.zoom = 100 # Ensure no zooming
    sheet.page_setup.print_quality = 300
    img_file = os.path.join(output_path, f"{name_no_extention}.png")
    end_range = spreadsheet_max_dimensions(file_name, sheet.name)
    custom_range = f"A1:{end_range}" # Change this to your desired range
    sheet.range(custom_range).to_png(img_file)

    Continue reading...

Compartilhe esta Página