@@ -1596,6 +1596,63 @@ def write_cells(self, cells, sheet_name=None, startrow=0, startcol=0,
1596
1596
startcol + cell .col ,
1597
1597
val , style )
1598
1598
1599
+ # Map from openpyxl-oriented styles to flatter xlsxwriter representation
1600
+ STYLE_MAPPING = [
1601
+ (('font' , 'name' ), 'font_name' ),
1602
+ (('font' , 'sz' ), 'font_size' ),
1603
+ (('font' , 'size' ), 'font_size' ),
1604
+ (('font' , 'color' , 'rgb' ), 'font_color' ),
1605
+ (('font' , 'b' ), 'bold' ),
1606
+ (('font' , 'bold' ), 'bold' ),
1607
+ (('font' , 'i' ), 'italic' ),
1608
+ (('font' , 'italic' ), 'italic' ),
1609
+ (('font' , 'u' ), 'underline' ),
1610
+ (('font' , 'underline' ), 'underline' ),
1611
+ (('font' , 'strike' ), 'font_strikeout' ),
1612
+ (('font' , 'vertAlign' ), 'font_script' ),
1613
+ (('font' , 'vertalign' ), 'font_script' ),
1614
+ (('number_format' , 'format_code' ), 'num_format' ),
1615
+ (('number_format' ,), 'num_format' ),
1616
+ (('protection' , 'locked' ), 'locked' ),
1617
+ (('protection' , 'hidden' ), 'hidden' ),
1618
+ (('alignment' , 'horizontal' ), 'align' ),
1619
+ (('alignment' , 'vertical' ), 'valign' ),
1620
+ (('alignment' , 'text_rotation' ), 'rotation' ),
1621
+ (('alignment' , 'wrap_text' ), 'text_wrap' ),
1622
+ (('alignment' , 'indent' ), 'indent' ),
1623
+ (('alignment' , 'shrink_to_fit' ), 'shrink' ),
1624
+ (('fill' , 'patternType' ), 'pattern' ),
1625
+ (('fill' , 'patterntype' ), 'pattern' ),
1626
+ (('fill' , 'fill_type' ), 'pattern' ),
1627
+ (('fill' , 'start_color' , 'rgb' ), 'fg_color' ),
1628
+ (('fill' , 'fgColor' , 'rgb' ), 'fg_color' ),
1629
+ (('fill' , 'fgcolor' , 'rgb' ), 'fg_color' ),
1630
+ (('fill' , 'start_color' ), 'fg_color' ),
1631
+ (('fill' , 'fgColor' ), 'fg_color' ),
1632
+ (('fill' , 'fgcolor' ), 'fg_color' ),
1633
+ (('fill' , 'end_color' , 'rgb' ), 'bg_color' ),
1634
+ (('fill' , 'bgColor' , 'rgb' ), 'bg_color' ),
1635
+ (('fill' , 'bgcolor' , 'rgb' ), 'bg_color' ),
1636
+ (('fill' , 'end_color' ), 'bg_color' ),
1637
+ (('fill' , 'bgColor' ), 'bg_color' ),
1638
+ (('fill' , 'bgcolor' ), 'bg_color' ),
1639
+ (('border' , 'color' , 'rgb' ), 'border_color' ),
1640
+ (('border' , 'color' ), 'border_color' ),
1641
+ (('border' , 'style' ), 'border' ),
1642
+ (('border' , 'top' , 'color' , 'rgb' ), 'top_color' ),
1643
+ (('border' , 'top' , 'color' ), 'top_color' ),
1644
+ (('border' , 'top' , 'style' ), 'top' ),
1645
+ (('border' , 'right' , 'color' , 'rgb' ), 'right_color' ),
1646
+ (('border' , 'right' , 'color' ), 'right_color' ),
1647
+ (('border' , 'right' , 'style' ), 'right' ),
1648
+ (('border' , 'bottom' , 'color' , 'rgb' ), 'bottom_color' ),
1649
+ (('border' , 'bottom' , 'color' ), 'bottom_color' ),
1650
+ (('border' , 'bottom' , 'style' ), 'bottom' ),
1651
+ (('border' , 'left' , 'color' , 'rgb' ), 'left_color' ),
1652
+ (('border' , 'left' , 'color' ), 'left_color' ),
1653
+ (('border' , 'left' , 'style' ), 'left' ),
1654
+ ]
1655
+
1599
1656
def _convert_to_style (self , style_dict , num_format_str = None ):
1600
1657
"""
1601
1658
converts a style_dict to an xlsxwriter format object
@@ -1610,35 +1667,56 @@ def _convert_to_style(self, style_dict, num_format_str=None):
1610
1667
return None
1611
1668
1612
1669
# Create a XlsxWriter format object.
1613
- xl_format = self . book . add_format ()
1670
+ props = {}
1614
1671
1615
1672
if num_format_str is not None :
1616
- xl_format . set_num_format ( num_format_str )
1673
+ props [ 'num_format' ] = num_format_str
1617
1674
1618
1675
if style_dict is None :
1619
- return xl_format
1620
-
1621
- # Map the cell font to XlsxWriter font properties.
1622
- if style_dict .get ('font' ):
1623
- font = style_dict ['font' ]
1624
- if font .get ('bold' ):
1625
- xl_format .set_bold ()
1626
-
1627
- # Map the alignment to XlsxWriter alignment properties.
1628
- alignment = style_dict .get ('alignment' )
1629
- if alignment :
1630
- if (alignment .get ('horizontal' ) and
1631
- alignment ['horizontal' ] == 'center' ):
1632
- xl_format .set_align ('center' )
1633
- if (alignment .get ('vertical' ) and
1634
- alignment ['vertical' ] == 'top' ):
1635
- xl_format .set_align ('top' )
1636
-
1637
- # Map the cell borders to XlsxWriter border properties.
1638
- if style_dict .get ('borders' ):
1639
- xl_format .set_border ()
1640
-
1641
- return xl_format
1676
+ return self .book .add_format (props )
1677
+
1678
+ if 'borders' in style_dict :
1679
+ style_dict ['border' ] = style_dict .pop ('borders' )
1680
+
1681
+ for src , dst in self .STYLE_MAPPING :
1682
+ # src is a sequence of keys into a nested dict
1683
+ # dst is a flat key
1684
+ if dst in props :
1685
+ continue
1686
+ v = style_dict
1687
+ for k in src :
1688
+ try :
1689
+ v = v [k ]
1690
+ except (KeyError , TypeError ):
1691
+ break
1692
+ else :
1693
+ props [dst ] = v
1694
+
1695
+ if isinstance (props .get ('pattern' ), string_types ):
1696
+ # TODO: support other fill patterns
1697
+ props ['pattern' ] = 0 if props ['pattern' ] == 'none' else 1
1698
+
1699
+ for k in ['border' , 'top' , 'right' , 'bottom' , 'left' ]:
1700
+ if isinstance (props .get (k ), string_types ):
1701
+ try :
1702
+ props [k ] = ['none' , 'thin' , 'medium' , 'dashed' , 'dotted' ,
1703
+ 'thick' , 'double' , 'hair' , 'mediumDashed' ,
1704
+ 'dashDot' , 'mediumDashDot' , 'dashDotDot' ,
1705
+ 'mediumDashDotDot' , 'slantDashDot' ].\
1706
+ index (props [k ])
1707
+ except ValueError :
1708
+ props [k ] = 2
1709
+
1710
+ if isinstance (props .get ('font_script' ), string_types ):
1711
+ props ['font_script' ] = ['baseline' , 'superscript' , 'subscript' ].\
1712
+ index (props ['font_script' ])
1713
+
1714
+ if isinstance (props .get ('underline' ), string_types ):
1715
+ props ['underline' ] = {'none' : 0 , 'single' : 1 , 'double' : 2 ,
1716
+ 'singleAccounting' : 33 ,
1717
+ 'doubleAccounting' : 34 }[props ['underline' ]]
1718
+
1719
+ return self .book .add_format (props )
1642
1720
1643
1721
1644
1722
register_writer (_XlsxWriter )
0 commit comments