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

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

351 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-2025, John McNamara, jmcnamara@cpan.org 

8# 

9 

10# Package imports. 

11from warnings import warn 

12 

13from xlsxwriter.color import Color 

14 

15from . import xmlwriter 

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): 

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.font_size = 11 

57 self.font_color = None 

58 self.font_strikeout = 0 

59 self.font_outline = 0 

60 self.font_shadow = 0 

61 self.font_script = 0 

62 self.font_family = 2 

63 self.font_charset = 0 

64 self.font_scheme = "minor" 

65 self.font_condense = 0 

66 self.font_extend = 0 

67 self.theme = 0 

68 self.hyperlink = False 

69 self.xf_id = 0 

70 

71 self.hidden = 0 

72 self.locked = 1 

73 

74 self.text_h_align = 0 

75 self.text_wrap = 0 

76 self.text_v_align = 0 

77 self.text_justlast = 0 

78 self.rotation = 0 

79 

80 self.fg_color = None 

81 self.bg_color = None 

82 self.pattern = 0 

83 self.has_fill = False 

84 self.has_dxf_fill = False 

85 self.fill_index = 0 

86 self.fill_count = 0 

87 

88 self.border_index = 0 

89 self.has_border = False 

90 self.has_dxf_border = False 

91 self.border_count = 0 

92 

93 self.bottom = 0 

94 self.bottom_color = None 

95 self.diag_border = 0 

96 self.diag_color = None 

97 self.diag_type = 0 

98 self.left = 0 

99 self.left_color = None 

100 self.right = 0 

101 self.right_color = None 

102 self.top = 0 

103 self.top_color = None 

104 

105 self.indent = 0 

106 self.shrink = 0 

107 self.merge_range = 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 # Convert properties in the constructor to method calls. 

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

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

119 

120 self._format_key = None 

121 

122 def __repr__(self): 

123 """ 

124 Return a string representation of the Format instance. 

125 """ 

126 return ( 

127 f"Format(" 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

142 ) 

143 

144 ########################################################################### 

145 # 

146 # Format properties. 

147 # 

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

149 

150 def set_font_name(self, font_name): 

151 """ 

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

153 default Excel font is 'Calibri'. 

154 

155 Args: 

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

157 

158 Returns: 

159 Nothing. 

160 

161 """ 

162 self.font_name = font_name 

163 

164 def set_font_size(self, font_size=11): 

165 """ 

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

167 

168 Args: 

169 font_size: Int with font size. No default. 

170 

171 Returns: 

172 Nothing. 

173 

174 """ 

175 self.font_size = font_size 

176 

177 def set_font_color(self, font_color): 

178 """ 

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

180 

181 Args: 

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

183 

184 Returns: 

185 Nothing. 

186 

187 """ 

188 self.font_color = Color._from_value(font_color) 

189 

190 def set_bold(self, bold=True): 

191 """ 

192 Set the Format bold property. 

193 

194 Args: 

195 bold: Default is True, turns property on. 

196 

197 Returns: 

198 Nothing. 

199 

200 """ 

201 self.bold = bold 

202 

203 def set_italic(self, italic=True): 

204 """ 

205 Set the Format italic property. 

206 

207 Args: 

208 italic: Default is True, turns property on. 

209 

210 Returns: 

211 Nothing. 

212 

213 """ 

214 self.italic = italic 

215 

216 def set_underline(self, underline=1): 

217 """ 

218 Set the Format underline property. 

219 

220 Args: 

221 underline: Default is 1, single underline. 

222 

223 Returns: 

224 Nothing. 

225 

226 """ 

227 self.underline = underline 

228 

229 def set_font_strikeout(self, font_strikeout=True): 

230 """ 

231 Set the Format font_strikeout property. 

232 

233 Args: 

234 font_strikeout: Default is True, turns property on. 

235 

236 Returns: 

237 Nothing. 

238 

239 """ 

240 self.font_strikeout = font_strikeout 

241 

242 def set_font_script(self, font_script=1): 

243 """ 

244 Set the Format font_script property. 

245 

246 Args: 

247 font_script: Default is 1, superscript. 

248 

249 Returns: 

250 Nothing. 

251 

252 """ 

253 self.font_script = font_script 

254 

255 def set_font_outline(self, font_outline=True): 

256 """ 

257 Set the Format font_outline property. 

258 

259 Args: 

260 font_outline: Default is True, turns property on. 

261 

262 Returns: 

263 Nothing. 

264 

265 """ 

266 self.font_outline = font_outline 

267 

268 def set_font_shadow(self, font_shadow=True): 

269 """ 

270 Set the Format font_shadow property. 

271 

272 Args: 

273 font_shadow: Default is True, turns property on. 

274 

275 Returns: 

276 Nothing. 

277 

278 """ 

279 self.font_shadow = font_shadow 

280 

281 def set_num_format(self, num_format): 

282 """ 

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

284 

285 Args: 

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

287 

288 Returns: 

289 Nothing. 

290 

291 """ 

292 self.num_format = num_format 

293 

294 def set_locked(self, locked=True): 

295 """ 

296 Set the Format locked property. 

297 

298 Args: 

299 locked: Default is True, turns property on. 

300 

301 Returns: 

302 Nothing. 

303 

304 """ 

305 self.locked = locked 

306 

307 def set_hidden(self, hidden=True): 

308 """ 

309 Set the Format hidden property. 

310 

311 Args: 

312 hidden: Default is True, turns property on. 

313 

314 Returns: 

315 Nothing. 

316 

317 """ 

318 self.hidden = hidden 

319 

320 def set_align(self, alignment): 

321 """ 

322 Set the Format cell alignment. 

323 

324 Args: 

325 alignment: String representing alignment. No default. 

326 

327 Returns: 

328 Nothing. 

329 """ 

330 alignment = alignment.lower() 

331 

332 # Set horizontal alignment properties. 

333 if alignment == "left": 

334 self.set_text_h_align(1) 

335 if alignment == "centre": 

336 self.set_text_h_align(2) 

337 if alignment == "center": 

338 self.set_text_h_align(2) 

339 if alignment == "right": 

340 self.set_text_h_align(3) 

341 if alignment == "fill": 

342 self.set_text_h_align(4) 

343 if alignment == "justify": 

344 self.set_text_h_align(5) 

345 if alignment == "center_across": 

346 self.set_text_h_align(6) 

347 if alignment == "centre_across": 

348 self.set_text_h_align(6) 

349 if alignment == "distributed": 

350 self.set_text_h_align(7) 

351 if alignment == "justify_distributed": 

352 self.set_text_h_align(7) 

353 

354 if alignment == "justify_distributed": 

355 self.just_distrib = 1 

356 

357 # Set vertical alignment properties. 

358 if alignment == "top": 

359 self.set_text_v_align(1) 

360 if alignment == "vcentre": 

361 self.set_text_v_align(2) 

362 if alignment == "vcenter": 

363 self.set_text_v_align(2) 

364 if alignment == "bottom": 

365 self.set_text_v_align(3) 

366 if alignment == "vjustify": 

367 self.set_text_v_align(4) 

368 if alignment == "vdistributed": 

369 self.set_text_v_align(5) 

370 

371 def set_center_across(self, align_type=None): 

372 # pylint: disable=unused-argument 

373 """ 

374 Set the Format center_across property. 

375 

376 Returns: 

377 Nothing. 

378 

379 """ 

380 self.set_text_h_align(6) 

381 

382 def set_text_wrap(self, text_wrap=True): 

383 """ 

384 Set the Format text_wrap property. 

385 

386 Args: 

387 text_wrap: Default is True, turns property on. 

388 

389 Returns: 

390 Nothing. 

391 

392 """ 

393 self.text_wrap = text_wrap 

394 

395 def set_rotation(self, rotation): 

396 """ 

397 Set the Format rotation property. 

398 

399 Args: 

400 rotation: Rotation angle. No default. 

401 

402 Returns: 

403 Nothing. 

404 

405 """ 

406 rotation = int(rotation) 

407 

408 # Map user angle to Excel angle. 

409 if rotation == 270: 

410 rotation = 255 

411 elif -90 <= rotation <= 90: 

412 if rotation < 0: 

413 rotation = -rotation + 90 

414 else: 

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

416 return 

417 

418 self.rotation = rotation 

419 

420 def set_indent(self, indent=1): 

421 """ 

422 Set the Format indent property. 

423 

424 Args: 

425 indent: Default is 1, first indentation level. 

426 

427 Returns: 

428 Nothing. 

429 

430 """ 

431 self.indent = indent 

432 

433 def set_shrink(self, shrink=True): 

434 """ 

435 Set the Format shrink property. 

436 

437 Args: 

438 shrink: Default is True, turns property on. 

439 

440 Returns: 

441 Nothing. 

442 

443 """ 

444 self.shrink = shrink 

445 

446 def set_text_justlast(self, text_justlast=True): 

447 """ 

448 Set the Format text_justlast property. 

449 

450 Args: 

451 text_justlast: Default is True, turns property on. 

452 

453 Returns: 

454 Nothing. 

455 

456 """ 

457 self.text_justlast = text_justlast 

458 

459 def set_pattern(self, pattern=1): 

460 """ 

461 Set the Format pattern property. 

462 

463 Args: 

464 pattern: Default is 1, solid fill. 

465 

466 Returns: 

467 Nothing. 

468 

469 """ 

470 self.pattern = pattern 

471 

472 def set_bg_color(self, bg_color): 

473 """ 

474 Set the Format bg_color property. 

475 

476 Args: 

477 bg_color: Background color. No default. 

478 

479 Returns: 

480 Nothing. 

481 

482 """ 

483 self.bg_color = Color._from_value(bg_color) 

484 

485 def set_fg_color(self, fg_color): 

486 """ 

487 Set the Format fg_color property. 

488 

489 Args: 

490 fg_color: Foreground color. No default. 

491 

492 Returns: 

493 Nothing. 

494 

495 """ 

496 self.fg_color = Color._from_value(fg_color) 

497 

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

499 def set_border(self, style=1): 

500 """ 

501 Set the Format bottom property. 

502 

503 Args: 

504 bottom: Default is 1, border type 1. 

505 

506 Returns: 

507 Nothing. 

508 

509 """ 

510 self.set_bottom(style) 

511 self.set_top(style) 

512 self.set_left(style) 

513 self.set_right(style) 

514 

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

516 def set_border_color(self, color): 

517 """ 

518 Set the Format bottom property. 

519 

520 Args: 

521 color: Color string. No default. 

522 

523 Returns: 

524 Nothing. 

525 

526 """ 

527 self.set_bottom_color(color) 

528 self.set_top_color(color) 

529 self.set_left_color(color) 

530 self.set_right_color(color) 

531 

532 def set_bottom(self, bottom=1): 

533 """ 

534 Set the Format bottom property. 

535 

536 Args: 

537 bottom: Default is 1, border type 1. 

538 

539 Returns: 

540 Nothing. 

541 

542 """ 

543 self.bottom = bottom 

544 

545 def set_bottom_color(self, bottom_color): 

546 """ 

547 Set the Format bottom_color property. 

548 

549 Args: 

550 bottom_color: Color string. No default. 

551 

552 Returns: 

553 Nothing. 

554 

555 """ 

556 self.bottom_color = Color._from_value(bottom_color) 

557 

558 def set_diag_type(self, diag_type=1): 

559 """ 

560 Set the Format diag_type property. 

561 

562 Args: 

563 diag_type: Default is 1, border type 1. 

564 

565 Returns: 

566 Nothing. 

567 

568 """ 

569 self.diag_type = diag_type 

570 

571 def set_left(self, left=1): 

572 """ 

573 Set the Format left property. 

574 

575 Args: 

576 left: Default is 1, border type 1. 

577 

578 Returns: 

579 Nothing. 

580 

581 """ 

582 self.left = left 

583 

584 def set_left_color(self, left_color): 

585 """ 

586 Set the Format left_color property. 

587 

588 Args: 

589 left_color: Color string. No default. 

590 

591 Returns: 

592 Nothing. 

593 

594 """ 

595 self.left_color = Color._from_value(left_color) 

596 

597 def set_right(self, right=1): 

598 """ 

599 Set the Format right property. 

600 

601 Args: 

602 right: Default is 1, border type 1. 

603 

604 Returns: 

605 Nothing. 

606 

607 """ 

608 self.right = right 

609 

610 def set_right_color(self, right_color): 

611 """ 

612 Set the Format right_color property. 

613 

614 Args: 

615 right_color: Color string. No default. 

616 

617 Returns: 

618 Nothing. 

619 

620 """ 

621 self.right_color = Color._from_value(right_color) 

622 

623 def set_top(self, top=1): 

624 """ 

625 Set the Format top property. 

626 

627 Args: 

628 top: Default is 1, border type 1. 

629 

630 Returns: 

631 Nothing. 

632 

633 """ 

634 self.top = top 

635 

636 def set_top_color(self, top_color): 

637 """ 

638 Set the Format top_color property. 

639 

640 Args: 

641 top_color: Color string. No default. 

642 

643 Returns: 

644 Nothing. 

645 

646 """ 

647 self.top_color = Color._from_value(top_color) 

648 

649 def set_diag_color(self, diag_color): 

650 """ 

651 Set the Format diag_color property. 

652 

653 Args: 

654 diag_color: Color string. No default. 

655 

656 Returns: 

657 Nothing. 

658 

659 """ 

660 self.diag_color = Color._from_value(diag_color) 

661 

662 def set_diag_border(self, diag_border=1): 

663 """ 

664 Set the Format diag_border property. 

665 

666 Args: 

667 diag_border: Default is 1, border type 1. 

668 

669 Returns: 

670 Nothing. 

671 

672 """ 

673 self.diag_border = diag_border 

674 

675 def set_quote_prefix(self, quote_prefix=True): 

676 """ 

677 Set the Format quote prefix property. 

678 

679 Args: 

680 quote_prefix: Default is True, turns property on. 

681 

682 Returns: 

683 Nothing. 

684 

685 """ 

686 self.quote_prefix = quote_prefix 

687 

688 def set_checkbox(self, checkbox=True): 

689 """ 

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

691 

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

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

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

695 ``worksheet.insert_checkbox()`` method. 

696 

697 Args: 

698 checkbox: Default is True, turns property on. 

699 

700 Returns: 

701 Nothing. 

702 

703 """ 

704 self.checkbox = checkbox 

705 

706 ########################################################################### 

707 # 

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

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

710 # 

711 ########################################################################### 

712 

713 def set_has_font(self, has_font=True): 

714 """ 

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

716 

717 Args: 

718 has_font: Default is True, turns property on. 

719 

720 Returns: 

721 Nothing. 

722 

723 """ 

724 self.has_font = has_font 

725 

726 def set_has_fill(self, has_fill=True): 

727 """ 

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

729 

730 Args: 

731 has_fill: Default is True, turns property on. 

732 

733 Returns: 

734 Nothing. 

735 

736 """ 

737 self.has_fill = has_fill 

738 

739 def set_font_index(self, font_index): 

740 """ 

741 Set the unique font index property. 

742 

743 Args: 

744 font_index: The unique font index. 

745 

746 Returns: 

747 Nothing. 

748 

749 """ 

750 self.font_index = font_index 

751 

752 def set_xf_index(self, xf_index): 

753 """ 

754 Set the unique format index property. 

755 

756 Args: 

757 xf_index: The unique Excel format index. 

758 

759 Returns: 

760 Nothing. 

761 

762 """ 

763 self.xf_index = xf_index 

764 

765 def set_dxf_index(self, dxf_index): 

766 """ 

767 Set the unique conditional format index property. 

768 

769 Args: 

770 dxf_index: The unique Excel conditional format index. 

771 

772 Returns: 

773 Nothing. 

774 

775 """ 

776 self.dxf_index = dxf_index 

777 

778 def set_num_format_index(self, num_format_index): 

779 """ 

780 Set the number format_index property. 

781 

782 Args: 

783 num_format_index: The unique number format index. 

784 

785 Returns: 

786 Nothing. 

787 

788 """ 

789 self.num_format_index = num_format_index 

790 

791 def set_text_h_align(self, text_h_align): 

792 """ 

793 Set the horizontal text alignment property. 

794 

795 Args: 

796 text_h_align: Horizontal text alignment. 

797 

798 Returns: 

799 Nothing. 

800 

801 """ 

802 self.text_h_align = text_h_align 

803 

804 def set_text_v_align(self, text_v_align): 

805 """ 

806 Set the vertical text alignment property. 

807 

808 Args: 

809 text_h_align: Vertical text alignment. 

810 

811 Returns: 

812 Nothing. 

813 

814 """ 

815 self.text_v_align = text_v_align 

816 

817 def set_reading_order(self, direction=0): 

818 # Set the reading_order property. 

819 """ 

820 Set the reading order property. 

821 

822 Args: 

823 direction: Default is 0, left to right. 

824 

825 Returns: 

826 Nothing. 

827 

828 """ 

829 self.reading_order = direction 

830 

831 def set_valign(self, align): 

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

833 # properties dict to differentiate between the vertical and horizontal 

834 # properties. 

835 """ 

836 Set vertical cell alignment property. 

837 

838 This is required by the constructor properties dict to differentiate 

839 between the vertical and horizontal properties. 

840 

841 Args: 

842 align: Alignment property. 

843 

844 Returns: 

845 Nothing. 

846 

847 """ 

848 self.set_align(align) 

849 

850 def set_font_family(self, font_family): 

851 """ 

852 Set the font family property. 

853 

854 Args: 

855 font_family: Font family number. 

856 

857 Returns: 

858 Nothing. 

859 

860 """ 

861 self.font_family = font_family 

862 

863 def set_font_charset(self, font_charset): 

864 """ 

865 Set the font character set property. 

866 

867 Args: 

868 font_charset: The font character set number. 

869 

870 Returns: 

871 Nothing. 

872 

873 """ 

874 self.font_charset = font_charset 

875 

876 def set_font_scheme(self, font_scheme): 

877 """ 

878 Set the font scheme property. 

879 

880 Args: 

881 font_scheme: The font scheme. 

882 

883 Returns: 

884 Nothing. 

885 

886 """ 

887 self.font_scheme = font_scheme 

888 

889 def set_font_condense(self, font_condense): 

890 """ 

891 Set the font condense property. 

892 

893 Args: 

894 font_condense: The font condense property. 

895 

896 Returns: 

897 Nothing. 

898 

899 """ 

900 self.font_condense = font_condense 

901 

902 def set_font_extend(self, font_extend): 

903 """ 

904 Set the font extend property. 

905 

906 Args: 

907 font_extend: The font extend property. 

908 

909 Returns: 

910 Nothing. 

911 

912 """ 

913 self.font_extend = font_extend 

914 

915 def set_theme(self, theme): 

916 """ 

917 Set the theme property. 

918 

919 Args: 

920 theme: Format theme. 

921 

922 Returns: 

923 Nothing. 

924 

925 """ 

926 self.theme = theme 

927 

928 def set_hyperlink(self, hyperlink=True): 

929 """ 

930 Set the properties for the hyperlink style. 

931 

932 Args: 

933 hyperlink: Default is True, turns property on. 

934 

935 Returns: 

936 Nothing. 

937 

938 """ 

939 self.xf_id = 1 

940 self.set_underline(1) 

941 self.set_theme(10) 

942 self.hyperlink = hyperlink 

943 

944 def set_color_indexed(self, color_index): 

945 """ 

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

947 indexed color instead of a rbg or theme color. 

948 

949 Args: 

950 color_index: Generally 0 or 1. 

951 

952 Returns: 

953 Nothing. 

954 

955 """ 

956 self.color_indexed = color_index 

957 

958 def set_font_only(self, font_only=True): 

959 """ 

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

961 

962 Args: 

963 font_only: Default is True, turns property on. 

964 

965 Returns: 

966 Nothing. 

967 

968 """ 

969 self.font_only = font_only 

970 

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

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

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

974 # in a future after a suitable deprecation period. 

975 def set_font(self, font_name): 

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

977 self.font_name = font_name 

978 

979 def set_size(self, font_size): 

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

981 self.font_size = font_size 

982 

983 def set_color(self, font_color): 

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

985 self.font_color = Color._from_value(font_color) 

986 

987 ########################################################################### 

988 # 

989 # Private API. 

990 # 

991 ########################################################################### 

992 

993 def _get_align_properties(self): 

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

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

996 changed = 0 

997 align = [] 

998 

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

1000 if ( 

1001 self.text_h_align 

1002 or self.text_v_align 

1003 or self.indent 

1004 or self.rotation 

1005 or self.text_wrap 

1006 or self.shrink 

1007 or self.reading_order 

1008 ): 

1009 changed = 1 

1010 else: 

1011 return changed, align 

1012 

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

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

1015 # default to left alignment. 

1016 if ( 

1017 self.indent 

1018 and self.text_h_align != 1 

1019 and self.text_h_align != 3 

1020 and self.text_h_align != 7 

1021 and self.text_v_align != 1 

1022 and self.text_v_align != 3 

1023 and self.text_v_align != 5 

1024 ): 

1025 self.text_h_align = 1 

1026 

1027 # Check for properties that are mutually exclusive. 

1028 if self.text_wrap: 

1029 self.shrink = 0 

1030 if self.text_h_align == 4: 

1031 self.shrink = 0 

1032 if self.text_h_align == 5: 

1033 self.shrink = 0 

1034 if self.text_h_align == 7: 

1035 self.shrink = 0 

1036 if self.text_h_align != 7: 

1037 self.just_distrib = 0 

1038 if self.indent: 

1039 self.just_distrib = 0 

1040 

1041 continuous = "centerContinuous" 

1042 

1043 if self.text_h_align == 1: 

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

1045 if self.text_h_align == 2: 

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

1047 if self.text_h_align == 3: 

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

1049 if self.text_h_align == 4: 

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

1051 if self.text_h_align == 5: 

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

1053 if self.text_h_align == 6: 

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

1055 if self.text_h_align == 7: 

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

1057 

1058 if self.just_distrib: 

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

1060 

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

1062 # without an alignment sub-element. 

1063 if self.text_v_align == 1: 

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

1065 if self.text_v_align == 2: 

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

1067 if self.text_v_align == 4: 

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

1069 if self.text_v_align == 5: 

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

1071 

1072 if self.rotation: 

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

1074 if self.indent: 

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

1076 

1077 if self.text_wrap: 

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

1079 if self.shrink: 

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

1081 

1082 if self.reading_order == 1: 

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

1084 if self.reading_order == 2: 

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

1086 

1087 return changed, align 

1088 

1089 def _get_protection_properties(self): 

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

1091 attributes = [] 

1092 

1093 if not self.locked: 

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

1095 if self.hidden: 

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

1097 

1098 return attributes 

1099 

1100 def _get_format_key(self): 

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

1102 if self._format_key is None: 

1103 self._format_key = ":".join( 

1104 str(x) 

1105 for x in ( 

1106 self._get_font_key(), 

1107 self._get_border_key(), 

1108 self._get_fill_key(), 

1109 self._get_alignment_key(), 

1110 self.num_format, 

1111 self.locked, 

1112 self.checkbox, 

1113 self.quote_prefix, 

1114 self.hidden, 

1115 ) 

1116 ) 

1117 

1118 return self._format_key 

1119 

1120 def _get_font_key(self): 

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

1122 key = ":".join( 

1123 str(x) 

1124 for x in ( 

1125 self.bold, 

1126 self.font_color, 

1127 self.font_charset, 

1128 self.font_family, 

1129 self.font_outline, 

1130 self.font_script, 

1131 self.font_shadow, 

1132 self.font_strikeout, 

1133 self.font_name, 

1134 self.italic, 

1135 self.font_size, 

1136 self.underline, 

1137 self.theme, 

1138 ) 

1139 ) 

1140 

1141 return key 

1142 

1143 def _get_border_key(self): 

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

1145 key = ":".join( 

1146 str(x) 

1147 for x in ( 

1148 self.bottom, 

1149 self.bottom_color, 

1150 self.diag_border, 

1151 self.diag_color, 

1152 self.diag_type, 

1153 self.left, 

1154 self.left_color, 

1155 self.right, 

1156 self.right_color, 

1157 self.top, 

1158 self.top_color, 

1159 ) 

1160 ) 

1161 

1162 return key 

1163 

1164 def _get_fill_key(self): 

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

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

1167 

1168 return key 

1169 

1170 def _get_alignment_key(self): 

1171 # Returns a unique hash key for alignment formats. 

1172 

1173 key = ":".join( 

1174 str(x) 

1175 for x in ( 

1176 self.text_h_align, 

1177 self.text_v_align, 

1178 self.indent, 

1179 self.rotation, 

1180 self.text_wrap, 

1181 self.shrink, 

1182 self.reading_order, 

1183 ) 

1184 ) 

1185 

1186 return key 

1187 

1188 def _get_xf_index(self): 

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

1190 if self.xf_index is not None: 

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

1192 return self.xf_index 

1193 

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

1195 key = self._get_format_key() 

1196 

1197 if key in self.xf_format_indices: 

1198 # Format matches existing format with an index. 

1199 return self.xf_format_indices[key] 

1200 

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

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

1203 index = 1 + len(self.xf_format_indices) 

1204 self.xf_format_indices[key] = index 

1205 self.xf_index = index 

1206 return index 

1207 

1208 def _get_dxf_index(self): 

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

1210 if self.dxf_index is not None: 

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

1212 return self.dxf_index 

1213 

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

1215 key = self._get_format_key() 

1216 

1217 if key in self.dxf_format_indices: 

1218 # Format matches existing format with an index. 

1219 return self.dxf_format_indices[key] 

1220 

1221 # New format requiring an index. 

1222 index = len(self.dxf_format_indices) 

1223 self.dxf_format_indices[key] = index 

1224 self.dxf_index = index 

1225 return index 

1226 

1227 ########################################################################### 

1228 # 

1229 # XML methods. 

1230 # 

1231 ###########################################################################