Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/xlsxwriter/format.py: 49%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

359 statements  

1############################################################################### 

2# 

3# Format - A class for writing the Excel XLSX Worksheet file. 

4# 

5# SPDX-License-Identifier: BSD-2-Clause 

6# 

7# Copyright (c) 2013-2026, John McNamara, jmcnamara@cpan.org 

8# 

9 

10# Package imports. 

11from typing import Literal, Union 

12from warnings import warn 

13 

14from xlsxwriter import xmlwriter 

15from xlsxwriter.color import Color 

16 

17 

18class Format(xmlwriter.XMLwriter): 

19 """ 

20 A class for writing the Excel XLSX Format file. 

21 

22 

23 """ 

24 

25 ########################################################################### 

26 # 

27 # Public API. 

28 # 

29 ########################################################################### 

30 

31 def __init__(self, properties=None, xf_indices=None, dxf_indices=None) -> None: 

32 """ 

33 Constructor. 

34 

35 """ 

36 if properties is None: 

37 properties = {} 

38 

39 super().__init__() 

40 

41 self.xf_format_indices = xf_indices 

42 self.dxf_format_indices = dxf_indices 

43 self.xf_index = None 

44 self.dxf_index = None 

45 

46 self.num_format = "General" 

47 self.num_format_index = 0 

48 self.font_index = 0 

49 self.has_font = False 

50 self.has_dxf_font = False 

51 

52 self.bold = 0 

53 self.underline = 0 

54 self.italic = 0 

55 self.font_name = "Calibri" 

56 self.theme_font_name = "Calibri" 

57 self.font_size = 11 

58 self.font_color = None 

59 self.font_strikeout = 0 

60 self.font_outline = 0 

61 self.font_shadow = 0 

62 self.font_script = 0 

63 self.font_family = 2 

64 self.font_charset = 0 

65 self.font_scheme = "minor" 

66 self.font_condense = 0 

67 self.font_extend = 0 

68 self.theme = 0 

69 self.hyperlink = False 

70 self.xf_id = 0 

71 

72 self.hidden = 0 

73 self.locked = 1 

74 

75 self.text_h_align = 0 

76 self.text_wrap = 0 

77 self.text_v_align = 0 

78 self.text_justlast = 0 

79 self.rotation = 0 

80 

81 self.fg_color = None 

82 self.bg_color = None 

83 self.pattern = 0 

84 self.has_fill = False 

85 self.has_dxf_fill = False 

86 self.fill_index = 0 

87 self.fill_count = 0 

88 

89 self.border_index = 0 

90 self.has_border = False 

91 self.has_dxf_border = False 

92 self.border_count = 0 

93 

94 self.bottom = 0 

95 self.bottom_color = None 

96 self.diag_border = 0 

97 self.diag_color = None 

98 self.diag_type = 0 

99 self.left = 0 

100 self.left_color = None 

101 self.right = 0 

102 self.right_color = None 

103 self.top = 0 

104 self.top_color = None 

105 

106 self.indent = 0 

107 self.shrink = 0 

108 self.reading_order = 0 

109 self.just_distrib = 0 

110 self.color_indexed = 0 

111 self.font_only = 0 

112 

113 self.quote_prefix = False 

114 self.checkbox = False 

115 

116 # Set the property first. 

117 if properties.get("theme_font_name"): 

118 self.theme_font_name = properties["theme_font_name"] 

119 

120 # Convert properties in the constructor to method calls. 

121 for key, value in properties.items(): 

122 getattr(self, "set_" + key)(value) 

123 

124 self._format_key = None 

125 

126 def __repr__(self) -> str: 

127 """ 

128 Return a string representation of the Format instance. 

129 """ 

130 return ( 

131 f"Format(" 

132 f"font_name={self.font_name!r}, " 

133 f"font_size={self.font_size}, " 

134 f"bold={self.bold}, " 

135 f"italic={self.italic}, " 

136 f"underline={self.underline}, " 

137 f"font_color={self.font_color}, " 

138 f"num_format={self.num_format!r}, " 

139 f"text_h_align={self.text_h_align}, " 

140 f"text_v_align={self.text_v_align}, " 

141 f"fg_color={self.fg_color}, " 

142 f"bg_color={self.bg_color}, " 

143 f"pattern={self.pattern}, " 

144 f"locked={self.locked}, " 

145 f"hidden={self.hidden})" 

146 ) 

147 

148 ########################################################################### 

149 # 

150 # Format properties. 

151 # 

152 ########################################################################### 

153 

154 def set_font_name(self, font_name) -> None: 

155 """ 

156 Set the Format font_name property such as 'Time New Roman'. The 

157 default Excel font is 'Calibri'. 

158 

159 Args: 

160 font_name: String with the font name. No default. 

161 

162 Returns: 

163 Nothing. 

164 

165 """ 

166 self.font_name = font_name 

167 

168 if font_name != self.theme_font_name: 

169 self.font_scheme = "none" 

170 

171 def set_font_size(self, font_size: int = 11) -> None: 

172 """ 

173 Set the Format font_size property. The default Excel font size is 11. 

174 

175 Args: 

176 font_size: Int with font size. No default. 

177 

178 Returns: 

179 Nothing. 

180 

181 """ 

182 self.font_size = font_size 

183 

184 def set_font_color(self, font_color: Union[str, Color]) -> None: 

185 """ 

186 Set the Format font_color property. The Excel default is black. 

187 

188 Args: 

189 font_color: String with the font color. No default. 

190 

191 Returns: 

192 Nothing. 

193 

194 """ 

195 self.font_color = Color._from_value(font_color) 

196 

197 def set_bold(self, bold: bool = True) -> None: 

198 """ 

199 Set the Format bold property. 

200 

201 Args: 

202 bold: Default is True, turns property on. 

203 

204 Returns: 

205 Nothing. 

206 

207 """ 

208 self.bold = bold 

209 

210 def set_italic(self, italic: bool = True) -> None: 

211 """ 

212 Set the Format italic property. 

213 

214 Args: 

215 italic: Default is True, turns property on. 

216 

217 Returns: 

218 Nothing. 

219 

220 """ 

221 self.italic = italic 

222 

223 def set_underline(self, underline: Literal[1, 2, 33, 34] = 1) -> None: 

224 """ 

225 Set the Format underline property. 

226 

227 Args: 

228 underline: Default is 1, single underline. 

229 

230 Returns: 

231 Nothing. 

232 

233 """ 

234 self.underline = underline 

235 

236 def set_font_strikeout(self, font_strikeout: bool = True) -> None: 

237 """ 

238 Set the Format font_strikeout property. 

239 

240 Args: 

241 font_strikeout: Default is True, turns property on. 

242 

243 Returns: 

244 Nothing. 

245 

246 """ 

247 self.font_strikeout = font_strikeout 

248 

249 def set_font_script(self, font_script: Literal[1, 2] = 1) -> None: 

250 """ 

251 Set the Format font_script property. 

252 

253 Args: 

254 font_script: Default is 1, superscript. 

255 

256 Returns: 

257 Nothing. 

258 

259 """ 

260 self.font_script = font_script 

261 

262 def set_font_outline(self, font_outline: bool = True) -> None: 

263 """ 

264 Set the Format font_outline property. 

265 

266 Args: 

267 font_outline: Default is True, turns property on. 

268 

269 Returns: 

270 Nothing. 

271 

272 """ 

273 self.font_outline = font_outline 

274 

275 def set_font_shadow(self, font_shadow: bool = True) -> None: 

276 """ 

277 Set the Format font_shadow property. 

278 

279 Args: 

280 font_shadow: Default is True, turns property on. 

281 

282 Returns: 

283 Nothing. 

284 

285 """ 

286 self.font_shadow = font_shadow 

287 

288 def set_num_format(self, num_format: str) -> None: 

289 """ 

290 Set the Format num_format property such as '#,##0'. 

291 

292 Args: 

293 num_format: String representing the number format. No default. 

294 

295 Returns: 

296 Nothing. 

297 

298 """ 

299 self.num_format = num_format 

300 

301 def set_locked(self, locked: bool = True) -> None: 

302 """ 

303 Set the Format locked property. 

304 

305 Args: 

306 locked: Default is True, turns property on. 

307 

308 Returns: 

309 Nothing. 

310 

311 """ 

312 self.locked = locked 

313 

314 def set_hidden(self, hidden: bool = True) -> None: 

315 """ 

316 Set the Format hidden property. 

317 

318 Args: 

319 hidden: Default is True, turns property on. 

320 

321 Returns: 

322 Nothing. 

323 

324 """ 

325 self.hidden = hidden 

326 

327 def set_align( 

328 self, 

329 alignment: Literal[ 

330 "left", 

331 "centre", 

332 "center", 

333 "right", 

334 "fill", 

335 "justify", 

336 "center_across", 

337 "centre_across", 

338 "distributed", 

339 "justify_distributed", 

340 "top", 

341 "vcentre", 

342 "vcenter", 

343 "bottom", 

344 "vjustify", 

345 "vdistributed", 

346 ], 

347 ) -> None: 

348 """ 

349 Set the Format cell alignment. 

350 

351 Args: 

352 alignment: String representing alignment. No default. 

353 

354 Returns: 

355 Nothing. 

356 """ 

357 alignment = alignment.lower() 

358 

359 # Set horizontal alignment properties. 

360 if alignment == "left": 

361 self.set_text_h_align(1) 

362 if alignment == "centre": 

363 self.set_text_h_align(2) 

364 if alignment == "center": 

365 self.set_text_h_align(2) 

366 if alignment == "right": 

367 self.set_text_h_align(3) 

368 if alignment == "fill": 

369 self.set_text_h_align(4) 

370 if alignment == "justify": 

371 self.set_text_h_align(5) 

372 if alignment == "center_across": 

373 self.set_text_h_align(6) 

374 if alignment == "centre_across": 

375 self.set_text_h_align(6) 

376 if alignment == "distributed": 

377 self.set_text_h_align(7) 

378 if alignment == "justify_distributed": 

379 self.set_text_h_align(7) 

380 

381 if alignment == "justify_distributed": 

382 self.just_distrib = 1 

383 

384 # Set vertical alignment properties. 

385 if alignment == "top": 

386 self.set_text_v_align(1) 

387 if alignment == "vcentre": 

388 self.set_text_v_align(2) 

389 if alignment == "vcenter": 

390 self.set_text_v_align(2) 

391 if alignment == "bottom": 

392 self.set_text_v_align(3) 

393 if alignment == "vjustify": 

394 self.set_text_v_align(4) 

395 if alignment == "vdistributed": 

396 self.set_text_v_align(5) 

397 

398 def set_center_across(self, align_type: None = None) -> None: 

399 # pylint: disable=unused-argument 

400 """ 

401 Set the Format center_across property. 

402 

403 Returns: 

404 Nothing. 

405 

406 """ 

407 self.set_text_h_align(6) 

408 

409 def set_text_wrap(self, text_wrap: bool = True) -> None: 

410 """ 

411 Set the Format text_wrap property. 

412 

413 Args: 

414 text_wrap: Default is True, turns property on. 

415 

416 Returns: 

417 Nothing. 

418 

419 """ 

420 self.text_wrap = text_wrap 

421 

422 def set_rotation(self, rotation: int) -> None: 

423 """ 

424 Set the Format rotation property. 

425 

426 Args: 

427 rotation: Rotation angle. No default. 

428 

429 Returns: 

430 Nothing. 

431 

432 """ 

433 rotation = int(rotation) 

434 

435 # Map user angle to Excel angle. 

436 if rotation == 270: 

437 rotation = 255 

438 elif -90 <= rotation <= 90: 

439 if rotation < 0: 

440 rotation = -rotation + 90 

441 else: 

442 warn("Rotation rotation outside range: -90 <= angle <= 90") 

443 return 

444 

445 self.rotation = rotation 

446 

447 def set_indent(self, indent: int = 1) -> None: 

448 """ 

449 Set the Format indent property. 

450 

451 Args: 

452 indent: Default is 1, first indentation level. 

453 

454 Returns: 

455 Nothing. 

456 

457 """ 

458 self.indent = indent 

459 

460 def set_shrink(self, shrink: bool = True) -> None: 

461 """ 

462 Set the Format shrink property. 

463 

464 Args: 

465 shrink: Default is True, turns property on. 

466 

467 Returns: 

468 Nothing. 

469 

470 """ 

471 self.shrink = shrink 

472 

473 def set_text_justlast(self, text_justlast: bool = True) -> None: 

474 """ 

475 Set the Format text_justlast property. 

476 

477 Args: 

478 text_justlast: Default is True, turns property on. 

479 

480 Returns: 

481 Nothing. 

482 

483 """ 

484 self.text_justlast = text_justlast 

485 

486 def set_pattern(self, pattern: int = 1) -> None: 

487 """ 

488 Set the Format pattern property. 

489 

490 Args: 

491 pattern: Default is 1, solid fill. 

492 

493 Returns: 

494 Nothing. 

495 

496 """ 

497 self.pattern = pattern 

498 

499 def set_bg_color(self, bg_color: Union[str, Color]) -> None: 

500 """ 

501 Set the Format bg_color property. 

502 

503 Args: 

504 bg_color: Background color. No default. 

505 

506 Returns: 

507 Nothing. 

508 

509 """ 

510 self.bg_color = Color._from_value(bg_color) 

511 

512 def set_fg_color(self, fg_color: Union[str, Color]) -> None: 

513 """ 

514 Set the Format fg_color property. 

515 

516 Args: 

517 fg_color: Foreground color. No default. 

518 

519 Returns: 

520 Nothing. 

521 

522 """ 

523 self.fg_color = Color._from_value(fg_color) 

524 

525 # set_border(style) Set cells borders to the same style 

526 def set_border(self, style: int = 1) -> None: 

527 """ 

528 Set the Format bottom property. 

529 

530 Args: 

531 bottom: Default is 1, border type 1. 

532 

533 Returns: 

534 Nothing. 

535 

536 """ 

537 self.set_bottom(style) 

538 self.set_top(style) 

539 self.set_left(style) 

540 self.set_right(style) 

541 

542 # set_border_color(color) Set cells border to the same color 

543 def set_border_color(self, color: Union[str, Color]) -> None: 

544 """ 

545 Set the Format bottom property. 

546 

547 Args: 

548 color: Color string. No default. 

549 

550 Returns: 

551 Nothing. 

552 

553 """ 

554 self.set_bottom_color(color) 

555 self.set_top_color(color) 

556 self.set_left_color(color) 

557 self.set_right_color(color) 

558 

559 def set_bottom(self, bottom: int = 1) -> None: 

560 """ 

561 Set the Format bottom property. 

562 

563 Args: 

564 bottom: Default is 1, border type 1. 

565 

566 Returns: 

567 Nothing. 

568 

569 """ 

570 self.bottom = bottom 

571 

572 def set_bottom_color(self, bottom_color: Union[str, Color]) -> None: 

573 """ 

574 Set the Format bottom_color property. 

575 

576 Args: 

577 bottom_color: Color string. No default. 

578 

579 Returns: 

580 Nothing. 

581 

582 """ 

583 self.bottom_color = Color._from_value(bottom_color) 

584 

585 def set_diag_type(self, diag_type: Literal[1, 2, 3] = 1) -> None: 

586 """ 

587 Set the Format diag_type property. 

588 

589 Args: 

590 diag_type: Default is 1, border type 1. 

591 

592 Returns: 

593 Nothing. 

594 

595 """ 

596 self.diag_type = diag_type 

597 

598 def set_left(self, left: int = 1) -> None: 

599 """ 

600 Set the Format left property. 

601 

602 Args: 

603 left: Default is 1, border type 1. 

604 

605 Returns: 

606 Nothing. 

607 

608 """ 

609 self.left = left 

610 

611 def set_left_color(self, left_color: Union[str, Color]) -> None: 

612 """ 

613 Set the Format left_color property. 

614 

615 Args: 

616 left_color: Color string. No default. 

617 

618 Returns: 

619 Nothing. 

620 

621 """ 

622 self.left_color = Color._from_value(left_color) 

623 

624 def set_right(self, right: int = 1) -> None: 

625 """ 

626 Set the Format right property. 

627 

628 Args: 

629 right: Default is 1, border type 1. 

630 

631 Returns: 

632 Nothing. 

633 

634 """ 

635 self.right = right 

636 

637 def set_right_color(self, right_color: Union[str, Color]) -> None: 

638 """ 

639 Set the Format right_color property. 

640 

641 Args: 

642 right_color: Color string. No default. 

643 

644 Returns: 

645 Nothing. 

646 

647 """ 

648 self.right_color = Color._from_value(right_color) 

649 

650 def set_top(self, top: int = 1) -> None: 

651 """ 

652 Set the Format top property. 

653 

654 Args: 

655 top: Default is 1, border type 1. 

656 

657 Returns: 

658 Nothing. 

659 

660 """ 

661 self.top = top 

662 

663 def set_top_color(self, top_color: Union[str, Color]) -> None: 

664 """ 

665 Set the Format top_color property. 

666 

667 Args: 

668 top_color: Color string. No default. 

669 

670 Returns: 

671 Nothing. 

672 

673 """ 

674 self.top_color = Color._from_value(top_color) 

675 

676 def set_diag_color(self, diag_color: Union[str, Color]) -> None: 

677 """ 

678 Set the Format diag_color property. 

679 

680 Args: 

681 diag_color: Color string. No default. 

682 

683 Returns: 

684 Nothing. 

685 

686 """ 

687 self.diag_color = Color._from_value(diag_color) 

688 

689 def set_diag_border(self, diag_border: int = 1) -> None: 

690 """ 

691 Set the Format diag_border property. 

692 

693 Args: 

694 diag_border: Default is 1, border type 1. 

695 

696 Returns: 

697 Nothing. 

698 

699 """ 

700 self.diag_border = diag_border 

701 

702 def set_quote_prefix(self, quote_prefix: bool = True) -> None: 

703 """ 

704 Set the Format quote prefix property. 

705 

706 Args: 

707 quote_prefix: Default is True, turns property on. 

708 

709 Returns: 

710 Nothing. 

711 

712 """ 

713 self.quote_prefix = quote_prefix 

714 

715 def set_checkbox(self, checkbox: bool = True) -> None: 

716 """ 

717 Set the Format property to show a checkbox in a cell. 

718 

719 This format property can be used with a cell that contains a boolean 

720 value to display it as a checkbox. This property isn't required very 

721 often and it is generally easier to create a checkbox using the 

722 ``worksheet.insert_checkbox()`` method. 

723 

724 Args: 

725 checkbox: Default is True, turns property on. 

726 

727 Returns: 

728 Nothing. 

729 

730 """ 

731 self.checkbox = checkbox 

732 

733 ########################################################################### 

734 # 

735 # Internal Format properties. These aren't documented since they are 

736 # either only used internally or else are unlikely to be set by the user. 

737 # 

738 ########################################################################### 

739 

740 def set_has_font(self, has_font: bool = True) -> None: 

741 """ 

742 Set the property to indicate the format has a font. 

743 

744 Args: 

745 has_font: Default is True, turns property on. 

746 

747 Returns: 

748 Nothing. 

749 

750 """ 

751 self.has_font = has_font 

752 

753 def set_has_fill(self, has_fill: bool = True) -> None: 

754 """ 

755 Set the property to indicate the format has a fill. 

756 

757 Args: 

758 has_fill: Default is True, turns property on. 

759 

760 Returns: 

761 Nothing. 

762 

763 """ 

764 self.has_fill = has_fill 

765 

766 def set_font_index(self, font_index: int) -> None: 

767 """ 

768 Set the unique font index property. 

769 

770 Args: 

771 font_index: The unique font index. 

772 

773 Returns: 

774 Nothing. 

775 

776 """ 

777 self.font_index = font_index 

778 

779 def set_xf_index(self, xf_index: int) -> None: 

780 """ 

781 Set the unique format index property. 

782 

783 Args: 

784 xf_index: The unique Excel format index. 

785 

786 Returns: 

787 Nothing. 

788 

789 """ 

790 self.xf_index = xf_index 

791 

792 def set_dxf_index(self, dxf_index: int) -> None: 

793 """ 

794 Set the unique conditional format index property. 

795 

796 Args: 

797 dxf_index: The unique Excel conditional format index. 

798 

799 Returns: 

800 Nothing. 

801 

802 """ 

803 self.dxf_index = dxf_index 

804 

805 def set_num_format_index(self, num_format_index: int) -> None: 

806 """ 

807 Set the number format_index property. 

808 

809 Args: 

810 num_format_index: The unique number format index. 

811 

812 Returns: 

813 Nothing. 

814 

815 """ 

816 self.num_format_index = num_format_index 

817 

818 def set_text_h_align(self, text_h_align: int) -> None: 

819 """ 

820 Set the horizontal text alignment property. 

821 

822 Args: 

823 text_h_align: Horizontal text alignment. 

824 

825 Returns: 

826 Nothing. 

827 

828 """ 

829 self.text_h_align = text_h_align 

830 

831 def set_text_v_align(self, text_v_align: int) -> None: 

832 """ 

833 Set the vertical text alignment property. 

834 

835 Args: 

836 text_h_align: Vertical text alignment. 

837 

838 Returns: 

839 Nothing. 

840 

841 """ 

842 self.text_v_align = text_v_align 

843 

844 def set_reading_order(self, direction: int = 0) -> None: 

845 # Set the reading_order property. 

846 """ 

847 Set the reading order property. 

848 

849 Args: 

850 direction: Default is 0, left to right. 

851 

852 Returns: 

853 Nothing. 

854 

855 """ 

856 self.reading_order = direction 

857 

858 def set_valign( 

859 self, 

860 align: Literal[ 

861 "left", 

862 "centre", 

863 "center", 

864 "right", 

865 "fill", 

866 "justify", 

867 "center_across", 

868 "centre_across", 

869 "distributed", 

870 "justify_distributed", 

871 "top", 

872 "vcentre", 

873 "vcenter", 

874 "bottom", 

875 "vjustify", 

876 "vdistributed", 

877 ], 

878 ) -> None: 

879 # Set vertical cell alignment. This is required by the constructor 

880 # properties dict to differentiate between the vertical and horizontal 

881 # properties. 

882 """ 

883 Set vertical cell alignment property. 

884 

885 This is required by the constructor properties dict to differentiate 

886 between the vertical and horizontal properties. 

887 

888 Args: 

889 align: Alignment property. 

890 

891 Returns: 

892 Nothing. 

893 

894 """ 

895 self.set_align(align) 

896 

897 def set_font_family(self, font_family: int) -> None: 

898 """ 

899 Set the font family property. 

900 

901 Args: 

902 font_family: Font family number. 

903 

904 Returns: 

905 Nothing. 

906 

907 """ 

908 self.font_family = font_family 

909 

910 def set_font_charset(self, font_charset: int) -> None: 

911 """ 

912 Set the font character set property. 

913 

914 Args: 

915 font_charset: The font character set number. 

916 

917 Returns: 

918 Nothing. 

919 

920 """ 

921 self.font_charset = font_charset 

922 

923 def set_font_scheme(self, font_scheme: str) -> None: 

924 """ 

925 Set the font scheme property to indicate if the font is tied to the 

926 workbook theme 

927 

928 This method can be used to indicate that a font is part of a theme. The 

929 theme must also contain the appropriate font for this to work. 

930 

931 This method can also be used to indicate that a font is not part of a 

932 theme, for example, if you wished to use a "Calibri" font that is not 

933 connected to the theme and which will not change if the theme is 

934 changed. 

935 

936 

937 The allowed values are: 

938 

939 - "minor": This is used to indicate a theme font that is used for body 

940 text. 

941 - "major": This is used to indicate a theme font that is used for 

942 headings. 

943 - "none": This is used to indicate a font that is not part of the theme. 

944 

945 Args: 

946 font_scheme: The font scheme. 

947 

948 Returns: 

949 Nothing. 

950 

951 """ 

952 self.font_scheme = font_scheme 

953 

954 def set_font_condense(self, font_condense: int) -> None: 

955 """ 

956 Set the font condense property. 

957 

958 Args: 

959 font_condense: The font condense property. 

960 

961 Returns: 

962 Nothing. 

963 

964 """ 

965 self.font_condense = font_condense 

966 

967 def set_font_extend(self, font_extend: int) -> None: 

968 """ 

969 Set the font extend property. 

970 

971 Args: 

972 font_extend: The font extend property. 

973 

974 Returns: 

975 Nothing. 

976 

977 """ 

978 self.font_extend = font_extend 

979 

980 def set_theme(self, theme: int) -> None: 

981 """ 

982 Set the theme property. 

983 

984 Args: 

985 theme: Format theme. 

986 

987 Returns: 

988 Nothing. 

989 

990 """ 

991 self.theme = theme 

992 

993 def set_hyperlink(self, hyperlink: bool = True) -> None: 

994 """ 

995 Set the properties for the hyperlink style. 

996 

997 Args: 

998 hyperlink: Default is True, turns property on. 

999 

1000 Returns: 

1001 Nothing. 

1002 

1003 """ 

1004 self.xf_id = 1 

1005 self.set_underline(1) 

1006 self.set_theme(10) 

1007 self.hyperlink = hyperlink 

1008 self.font_scheme = "none" 

1009 

1010 def set_color_indexed(self, color_index: Literal[0, 1]) -> None: 

1011 """ 

1012 Set the color index property. Some fundamental format properties use an 

1013 indexed color instead of a rbg or theme color. 

1014 

1015 Args: 

1016 color_index: Generally 0 or 1. 

1017 

1018 Returns: 

1019 Nothing. 

1020 

1021 """ 

1022 self.color_indexed = color_index 

1023 

1024 def set_font_only(self, font_only: bool = True) -> None: 

1025 """ 

1026 Set property to indicate that the format is used for fonts only. 

1027 

1028 Args: 

1029 font_only: Default is True, turns property on. 

1030 

1031 Returns: 

1032 Nothing. 

1033 

1034 """ 

1035 self.font_only = font_only 

1036 

1037 def set_theme_font_name(self, font_name) -> None: 

1038 """ 

1039 Set the Format font name use for the theme. 

1040 

1041 Args: 

1042 font_name: String with the font name. No default. 

1043 

1044 Returns: 

1045 Nothing. 

1046 

1047 """ 

1048 self.theme_font_name = font_name 

1049 

1050 # Compatibility methods. These versions of the method names were added in an 

1051 # initial version for compatibility testing with Excel::Writer::XLSX and 

1052 # leaked out into production code. They are deprecated and will be removed 

1053 # in a future after a suitable deprecation period. 

1054 def set_font(self, font_name: str) -> None: 

1055 """Deprecated: Use set_font_name() instead.""" 

1056 self.set_font_name(font_name) 

1057 

1058 def set_size(self, font_size: int) -> None: 

1059 """Deprecated: Use set_font_size() instead.""" 

1060 self.set_font_size(font_size) 

1061 

1062 def set_color(self, font_color: Union[Color, str]) -> None: 

1063 """Deprecated: Use set_font_color() instead.""" 

1064 self.set_font_color(font_color) 

1065 

1066 ########################################################################### 

1067 # 

1068 # Private API. 

1069 # 

1070 ########################################################################### 

1071 

1072 def _get_align_properties(self): 

1073 # pylint: disable=too-many-boolean-expressions 

1074 # Return properties for an Style xf <alignment> sub-element. 

1075 changed = 0 

1076 align = [] 

1077 

1078 # Check if any alignment options in the format have been changed. 

1079 if ( 

1080 self.text_h_align 

1081 or self.text_v_align 

1082 or self.indent 

1083 or self.rotation 

1084 or self.text_wrap 

1085 or self.shrink 

1086 or self.reading_order 

1087 ): 

1088 changed = 1 

1089 else: 

1090 return changed, align 

1091 

1092 # Indent is only allowed for some alignment properties. If it is 

1093 # defined for any other alignment or no alignment has been set then 

1094 # default to left alignment. 

1095 if ( 

1096 self.indent 

1097 and self.text_h_align != 1 

1098 and self.text_h_align != 3 

1099 and self.text_h_align != 7 

1100 and self.text_v_align != 1 

1101 and self.text_v_align != 3 

1102 and self.text_v_align != 5 

1103 ): 

1104 self.text_h_align = 1 

1105 

1106 # Check for properties that are mutually exclusive. 

1107 if self.text_wrap: 

1108 self.shrink = 0 

1109 if self.text_h_align == 4: 

1110 self.shrink = 0 

1111 if self.text_h_align == 5: 

1112 self.shrink = 0 

1113 if self.text_h_align == 7: 

1114 self.shrink = 0 

1115 if self.text_h_align != 7: 

1116 self.just_distrib = 0 

1117 if self.indent: 

1118 self.just_distrib = 0 

1119 

1120 continuous = "centerContinuous" 

1121 

1122 if self.text_h_align == 1: 

1123 align.append(("horizontal", "left")) 

1124 if self.text_h_align == 2: 

1125 align.append(("horizontal", "center")) 

1126 if self.text_h_align == 3: 

1127 align.append(("horizontal", "right")) 

1128 if self.text_h_align == 4: 

1129 align.append(("horizontal", "fill")) 

1130 if self.text_h_align == 5: 

1131 align.append(("horizontal", "justify")) 

1132 if self.text_h_align == 6: 

1133 align.append(("horizontal", continuous)) 

1134 if self.text_h_align == 7: 

1135 align.append(("horizontal", "distributed")) 

1136 

1137 if self.just_distrib: 

1138 align.append(("justifyLastLine", 1)) 

1139 

1140 # Property 'vertical' => 'bottom' is a default. It sets applyAlignment 

1141 # without an alignment sub-element. 

1142 if self.text_v_align == 1: 

1143 align.append(("vertical", "top")) 

1144 if self.text_v_align == 2: 

1145 align.append(("vertical", "center")) 

1146 if self.text_v_align == 4: 

1147 align.append(("vertical", "justify")) 

1148 if self.text_v_align == 5: 

1149 align.append(("vertical", "distributed")) 

1150 

1151 if self.rotation: 

1152 align.append(("textRotation", self.rotation)) 

1153 if self.indent: 

1154 align.append(("indent", self.indent)) 

1155 

1156 if self.text_wrap: 

1157 align.append(("wrapText", 1)) 

1158 if self.shrink: 

1159 align.append(("shrinkToFit", 1)) 

1160 

1161 if self.reading_order == 1: 

1162 align.append(("readingOrder", 1)) 

1163 if self.reading_order == 2: 

1164 align.append(("readingOrder", 2)) 

1165 

1166 return changed, align 

1167 

1168 def _get_protection_properties(self): 

1169 # Return properties for an Excel XML <Protection> element. 

1170 attributes = [] 

1171 

1172 if not self.locked: 

1173 attributes.append(("locked", 0)) 

1174 if self.hidden: 

1175 attributes.append(("hidden", 1)) 

1176 

1177 return attributes 

1178 

1179 def _get_format_key(self): 

1180 # Returns a unique hash key for a format. Used by Workbook. 

1181 if self._format_key is None: 

1182 self._format_key = ":".join( 

1183 str(x) 

1184 for x in ( 

1185 self._get_font_key(), 

1186 self._get_border_key(), 

1187 self._get_fill_key(), 

1188 self._get_alignment_key(), 

1189 self.num_format, 

1190 self.locked, 

1191 self.checkbox, 

1192 self.quote_prefix, 

1193 self.hidden, 

1194 ) 

1195 ) 

1196 

1197 return self._format_key 

1198 

1199 def _get_font_key(self): 

1200 # Returns a unique hash key for a font. Used by Workbook. 

1201 key = ":".join( 

1202 str(x) 

1203 for x in ( 

1204 self.bold, 

1205 self.font_color, 

1206 self.font_charset, 

1207 self.font_family, 

1208 self.font_outline, 

1209 self.font_script, 

1210 self.font_shadow, 

1211 self.font_strikeout, 

1212 self.font_name, 

1213 self.italic, 

1214 self.font_size, 

1215 self.underline, 

1216 self.theme, 

1217 ) 

1218 ) 

1219 

1220 return key 

1221 

1222 def _get_border_key(self): 

1223 # Returns a unique hash key for a border style. Used by Workbook. 

1224 key = ":".join( 

1225 str(x) 

1226 for x in ( 

1227 self.bottom, 

1228 self.bottom_color, 

1229 self.diag_border, 

1230 self.diag_color, 

1231 self.diag_type, 

1232 self.left, 

1233 self.left_color, 

1234 self.right, 

1235 self.right_color, 

1236 self.top, 

1237 self.top_color, 

1238 ) 

1239 ) 

1240 

1241 return key 

1242 

1243 def _get_fill_key(self): 

1244 # Returns a unique hash key for a fill style. Used by Workbook. 

1245 key = ":".join(str(x) for x in (self.pattern, self.bg_color, self.fg_color)) 

1246 

1247 return key 

1248 

1249 def _get_alignment_key(self): 

1250 # Returns a unique hash key for alignment formats. 

1251 

1252 key = ":".join( 

1253 str(x) 

1254 for x in ( 

1255 self.text_h_align, 

1256 self.text_v_align, 

1257 self.indent, 

1258 self.rotation, 

1259 self.text_wrap, 

1260 self.shrink, 

1261 self.reading_order, 

1262 ) 

1263 ) 

1264 

1265 return key 

1266 

1267 def _get_xf_index(self): 

1268 # Returns the XF index number used by Excel to identify a format. 

1269 if self.xf_index is not None: 

1270 # Format already has an index number so return it. 

1271 return self.xf_index 

1272 

1273 # Format doesn't have an index number so assign one. 

1274 key = self._get_format_key() 

1275 

1276 if key in self.xf_format_indices: 

1277 # Format matches existing format with an index. 

1278 return self.xf_format_indices[key] 

1279 

1280 # New format requiring an index. Note. +1 since Excel 

1281 # has an implicit "General" format at index 0. 

1282 index = 1 + len(self.xf_format_indices) 

1283 self.xf_format_indices[key] = index 

1284 self.xf_index = index 

1285 return index 

1286 

1287 def _get_dxf_index(self): 

1288 # Returns the DXF index number used by Excel to identify a format. 

1289 if self.dxf_index is not None: 

1290 # Format already has an index number so return it. 

1291 return self.dxf_index 

1292 

1293 # Format doesn't have an index number so assign one. 

1294 key = self._get_format_key() 

1295 

1296 if key in self.dxf_format_indices: 

1297 # Format matches existing format with an index. 

1298 return self.dxf_format_indices[key] 

1299 

1300 # New format requiring an index. 

1301 index = len(self.dxf_format_indices) 

1302 self.dxf_format_indices[key] = index 

1303 self.dxf_index = index 

1304 return index 

1305 

1306 ########################################################################### 

1307 # 

1308 # XML methods. 

1309 # 

1310 ###########################################################################