@@ -596,6 +596,7 @@ def _convert_to_style(cls, style_dict, num_format_str=None):
596
596
Parameters
597
597
----------
598
598
style_dict: style dictionary to convert
599
+ num_format_str: optional number format string
599
600
"""
600
601
import xlwt
601
602
@@ -611,3 +612,95 @@ def _convert_to_style(cls, style_dict, num_format_str=None):
611
612
612
613
register_writer (_XlwtWriter )
613
614
615
+
616
+ class _XlsxWriter (ExcelWriter ):
617
+ engine = 'xlsxwriter'
618
+ supported_extensions = ('.xlsx' ,)
619
+
620
+ def __init__ (self , path , ** engine_kwargs ):
621
+ # Use the xlsxwriter module as the Excel writer.
622
+ import xlsxwriter
623
+
624
+ super (_XlsxWriter , self ).__init__ (path , ** engine_kwargs )
625
+
626
+ self .book = xlsxwriter .Workbook (path , ** engine_kwargs )
627
+
628
+ def save (self ):
629
+ """
630
+ Save workbook to disk.
631
+ """
632
+ return self .book .close ()
633
+
634
+ def write_cells (self , cells , sheet_name = None , startrow = 0 , startcol = 0 ):
635
+ # Write the frame cells using xlsxwriter.
636
+
637
+ sheet_name = self ._get_sheet_name (sheet_name )
638
+
639
+ if sheet_name in self .sheets :
640
+ wks = self .sheets [sheet_name ]
641
+ else :
642
+ wks = self .book .add_worksheet (sheet_name )
643
+ self .sheets [sheet_name ] = wks
644
+
645
+ style_dict = {}
646
+
647
+ for cell in cells :
648
+ val = _conv_value (cell .val )
649
+
650
+ num_format_str = None
651
+ if isinstance (cell .val , datetime .datetime ):
652
+ num_format_str = "YYYY-MM-DD HH:MM:SS"
653
+ if isinstance (cell .val , datetime .date ):
654
+ num_format_str = "YYYY-MM-DD"
655
+
656
+ stylekey = json .dumps (cell .style )
657
+ if num_format_str :
658
+ stylekey += num_format_str
659
+
660
+ if stylekey in style_dict :
661
+ style = style_dict [stylekey ]
662
+ else :
663
+ style = self ._convert_to_style (cell .style , num_format_str )
664
+ style_dict [stylekey ] = style
665
+
666
+ if cell .mergestart is not None and cell .mergeend is not None :
667
+ wks .merge_range (startrow + cell .row ,
668
+ startrow + cell .mergestart ,
669
+ startcol + cell .col ,
670
+ startcol + cell .mergeend ,
671
+ val , style )
672
+ else :
673
+ wks .write (startrow + cell .row ,
674
+ startcol + cell .col ,
675
+ val , style )
676
+
677
+ def _convert_to_style (self , style_dict , num_format_str = None ):
678
+ """
679
+ converts a style_dict to an xlsxwriter format object
680
+ Parameters
681
+ ----------
682
+ style_dict: style dictionary to convert
683
+ num_format_str: optional number format string
684
+ """
685
+ if style_dict is None :
686
+ return None
687
+
688
+ # Create a XlsxWriter format object.
689
+ xl_format = self .book .add_format ()
690
+
691
+ # Map the cell font to XlsxWriter font properties.
692
+ if style_dict .get ('font' ):
693
+ font = style_dict ['font' ]
694
+ if font .get ('bold' ):
695
+ xl_format .set_bold ()
696
+
697
+ # Map the cell borders to XlsxWriter border properties.
698
+ if style_dict .get ('borders' ):
699
+ xl_format .set_border ()
700
+
701
+ if num_format_str is not None :
702
+ xl_format .set_num_format (num_format_str )
703
+
704
+ return xl_format
705
+
706
+ register_writer (_XlsxWriter )
0 commit comments