excel_list_validation.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. from __future__ import annotations
  2. from typing import Sequence
  3. from openpyxl.utils import get_column_letter
  4. from openpyxl.workbook.workbook import Workbook
  5. from openpyxl.worksheet.datavalidation import DataValidation
  6. from openpyxl.worksheet.worksheet import Worksheet
  7. def write_option_sheet(
  8. wb: Workbook,
  9. sheet_title: str,
  10. labels: Sequence[str],
  11. ids: Sequence[str] | None = None,
  12. *,
  13. hidden: bool = True,
  14. ) -> str:
  15. """写入选项表:A=label,可选 B=id。返回 sheet_title。"""
  16. if sheet_title in wb.sheetnames:
  17. ws = wb[sheet_title]
  18. wb.remove(ws)
  19. ws = wb.create_sheet(sheet_title)
  20. ws.append(["label", "id"] if ids is not None else ["label"])
  21. for i, lab in enumerate(labels):
  22. if ids is not None:
  23. ws.append([lab, ids[i] if i < len(ids) else ""])
  24. else:
  25. ws.append([lab])
  26. if hidden:
  27. ws.sheet_state = "hidden"
  28. return sheet_title
  29. def add_list_validation(
  30. ws: Worksheet,
  31. *,
  32. option_sheet: str,
  33. option_rows: int,
  34. target_col: int,
  35. start_row: int,
  36. end_row: int,
  37. allow_blank: bool = True,
  38. ) -> None:
  39. """option_rows 为选项数据行数(不含表头)。option 在 A2:A{1+option_rows}。"""
  40. if option_rows <= 0:
  41. return
  42. last = 1 + option_rows
  43. formula = f"='{option_sheet}'!$A$2:$A${last}"
  44. col = get_column_letter(target_col)
  45. dv = DataValidation(
  46. type="list",
  47. formula1=formula,
  48. allow_blank=allow_blank,
  49. showErrorMessage=True,
  50. showInputMessage=True,
  51. )
  52. dv.error = "请从下拉列表选择"
  53. dv.errorTitle = "无效值"
  54. dv.add(f"{col}{start_row}:{col}{end_row}")
  55. ws.add_data_validation(dv)