Ei kuvausta

test_xlsx2.py 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. from openpyxl import load_workbook, Workbook
  2. from datetime import datetime
  3. from openpyxl.drawing.image import Image
  4. import re
  5. from openpyxl.drawing.spreadsheet_drawing import AbsoluteAnchor
  6. from openpyxl.drawing.xdr import XDRPoint2D, XDRPositiveSize2D
  7. from openpyxl.utils.units import pixels_to_EMU
  8. from openpyxl.utils import get_column_letter
  9. def center_image_in_cell(ws, cell_address, img_path):
  10. """
  11. Center an image in a specific cell.
  12. Args:
  13. ws: The worksheet object.
  14. cell_address (str): The cell address (e.g., "B2") where the image will be centered.
  15. img_path (str): Path to the image file.
  16. Returns:
  17. None
  18. """
  19. # Load the image
  20. img = Image(img_path)
  21. img.width = img.height = 20
  22. # Get the cell
  23. cell = ws[cell_address]
  24. # Approximate pixel dimensions of the cell
  25. col_letter = get_column_letter(cell.column)
  26. col_width = ws.column_dimensions[col_letter].width or 10 # Default width
  27. row_height = ws.row_dimensions[cell.row].height or 15 # Default height
  28. # Convert dimensions to pixels
  29. col_width_pixels = col_width * 7 # Approximation: 1 Excel unit = ~7 pixels
  30. row_height_pixels = row_height * 0.75 # Approximation: 1 Excel unit = ~0.75 pixels
  31. # Calculate the center position
  32. cell_left = pixels_to_EMU(cell.column - 1) # Column start position in EMU
  33. cell_top = pixels_to_EMU((cell.row - 1) * row_height_pixels) # Row start position in EMU
  34. x_center = cell_left + pixels_to_EMU((col_width_pixels - img.width) / 2)
  35. y_center = cell_top + pixels_to_EMU((row_height_pixels - img.height) / 2)
  36. # Set the image position and size
  37. position = XDRPoint2D(x_center, y_center)
  38. size = XDRPositiveSize2D(pixels_to_EMU(img.width), pixels_to_EMU(img.height))
  39. img.anchor = AbsoluteAnchor(pos=position, ext=size)
  40. # Add the image to the worksheet
  41. ws.add_image(img)
  42. def gen_xlsx4(template_file, selected_sheets, prefix_filename, data):
  43. """
  44. Generate an Excel file from a template, fill placeholders, and include only selected sheets.
  45. Args:
  46. template_file (str): Path to the Excel template file.
  47. selected_sheets (list): List of sheet names to include in the output file.
  48. prefix_filename (str): Prefix for the output filename.
  49. data (dict): Data dictionary with sheet-specific keys and fallback keys.
  50. Returns:
  51. str: Path of the generated Excel file.
  52. """
  53. checked_image_path = "./checkbox_checked.jpg" # Path to the checked checkbox image
  54. unchecked_image_path = "./checkbox_unchecked.jpg" # Path to the unchecked checkbox image
  55. # Load the template workbook
  56. workbook = load_workbook(template_file)
  57. # Remove sheets not in selected_sheets
  58. for sheet_name in workbook.sheetnames:
  59. if sheet_name not in selected_sheets:
  60. del workbook[sheet_name]
  61. # Process the selected sheets
  62. for sheet_name in selected_sheets:
  63. if sheet_name not in workbook.sheetnames:
  64. raise ValueError(f"Sheet '{sheet_name}' not found in the template.")
  65. sheet = workbook[sheet_name]
  66. # Replace placeholders with actual values
  67. # Handle hiding rows based on patterns in data
  68. for row in sheet.iter_rows():
  69. for cell in row:
  70. if cell.value and isinstance(cell.value, str) and cell.value.startswith("<") and cell.value.endswith(">"):
  71. placeholder = cell.value.strip("<>")
  72. # Determine value priority: `sheet_name.key` > `key`
  73. value = None
  74. sheet_specific_key = f"{sheet_name}.{placeholder}"
  75. if sheet_specific_key in data:
  76. value = data[sheet_specific_key]
  77. elif placeholder in data:
  78. value = data[placeholder]
  79. if value is not None:
  80. if value is True:
  81. img = Image(checked_image_path)
  82. img.width = img.height = 20
  83. print(f"{cell.coordinate}")
  84. sheet.add_image(img, cell.coordinate)
  85. cell.value = None # Remove the placeholder text
  86. elif value is False:
  87. img = Image(unchecked_image_path)
  88. img.width = img.height = 20
  89. sheet.add_image(img, cell.coordinate)
  90. # center_image_in_cell(sheet, cell.coordinate, unchecked_image_path)
  91. cell.value = None # Remove the placeholder text
  92. else:
  93. # Insert the text value directly
  94. cell.value = value
  95. for key, value in data.items():
  96. if isinstance(value, str) and re.match(r"^\d+\[\d+:\d+\]$", value):
  97. # Parse the prefix and row range
  98. prefix, row_range = value.split("[")
  99. row_start, row_end = map(int, row_range[:-1].split(":"))
  100. # Hide rows if the prefix matches the condition
  101. if prefix == "0": # Adjust the condition as needed
  102. sheet.row_dimensions.group(row_start, row_end, hidden=True)
  103. # Generate the output filename with a timestamp
  104. timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
  105. output_path = f"{prefix_filename}_{timestamp}.xlsx"
  106. workbook.save(output_path)
  107. return output_path
  108. if __name__ == "__main__":
  109. # Example usage
  110. data = {
  111. "customer": "Tum Coder",
  112. "inspect_date": "2025-01-15",
  113. "lot_no": "12345",
  114. "size": "Large",
  115. "pcs": "10 pcs",
  116. "spec": "Spec-A",
  117. "hardness.d1_act": "10",
  118. "hardness.d2_act": "0[24:28]", # Hide rows 24 to 28 if the prefix is "0"
  119. "hardness.acc": True, # Hide rows 24 to 28 if the prefix is "0"
  120. "hardness.spe_acc": False, # Hide rows 24 to 28 if the prefix is "0"
  121. "dimension_app.d1_act": "33",
  122. "dimension_app.d2_act": "0[26:32]", # Hide rows 24 to 28 if the prefix is "0"
  123. "dimension_app.acc": True, # Hide rows 24 to 28 if the prefix is "0"
  124. "dimension_app.spe_acc": False, # Hide rows 24 to 28 if the prefix is "0"
  125. }
  126. output_file = gen_xlsx4(
  127. template_file="./hardness.xlsx",
  128. selected_sheets=["hardness", "dimension_app"], # Replace with your actual sheet names
  129. prefix_filename="./output/output",
  130. data=data
  131. )
  132. print(f"Generated file: {output_file}")