1919from pandas .io .parsers import read_csv
2020from pandas .io .excel import (
2121 ExcelFile , ExcelWriter , read_excel , _XlwtWriter , _Openpyxl1Writer ,
22- _Openpyxl2Writer , register_writer , _XlsxWriter
22+ _Openpyxl20Writer , _Openpyxl22Writer , register_writer , _XlsxWriter
2323)
2424from pandas .io .common import URLError
2525from pandas .util .testing import ensure_clean , makeCustomDataframe as mkdf
@@ -1470,17 +1470,28 @@ def test_to_excel_styleconverter(self):
14701470 xlsx_style .alignment .vertical )
14711471
14721472
1473+ def skip_openpyxl_gt21 (cls ):
1474+ """Skip a TestCase instance if openpyxl >= 2.2"""
1475+
1476+ @classmethod
1477+ def setUpClass (cls ):
1478+ _skip_if_no_openpyxl ()
1479+ import openpyxl
1480+ ver = openpyxl .__version__
1481+ if not (ver >= LooseVersion ('2.0.0' ) and ver < LooseVersion ('2.2.0' )):
1482+ raise nose .SkipTest ("openpyxl >= 2.2" )
1483+
1484+ cls .setUpClass = setUpClass
1485+ return cls
1486+
14731487@raise_on_incompat_version (2 )
1474- class Openpyxl2Tests (ExcelWriterBase , tm .TestCase ):
1488+ @skip_openpyxl_gt21
1489+ class Openpyxl20Tests (ExcelWriterBase , tm .TestCase ):
14751490 ext = '.xlsx'
1476- engine_name = 'openpyxl2 '
1491+ engine_name = 'openpyxl20 '
14771492 check_skip = staticmethod (lambda * args , ** kwargs : None )
14781493
14791494 def test_to_excel_styleconverter (self ):
1480- _skip_if_no_openpyxl ()
1481- if not openpyxl_compat .is_compat (major_ver = 2 ):
1482- raise nose .SkipTest ('incompatiable openpyxl version' )
1483-
14841495 import openpyxl
14851496 from openpyxl import styles
14861497
@@ -1532,7 +1543,7 @@ def test_to_excel_styleconverter(self):
15321543
15331544 protection = styles .Protection (locked = True , hidden = False )
15341545
1535- kw = _Openpyxl2Writer ._convert_to_style_kwargs (hstyle )
1546+ kw = _Openpyxl20Writer ._convert_to_style_kwargs (hstyle )
15361547 self .assertEqual (kw ['font' ], font )
15371548 self .assertEqual (kw ['border' ], border )
15381549 self .assertEqual (kw ['alignment' ], alignment )
@@ -1542,7 +1553,116 @@ def test_to_excel_styleconverter(self):
15421553
15431554
15441555 def test_write_cells_merge_styled (self ):
1556+ from pandas .core .format import ExcelCell
1557+ from openpyxl import styles
1558+
1559+ sheet_name = 'merge_styled'
1560+
1561+ sty_b1 = {'font' : {'color' : '00FF0000' }}
1562+ sty_a2 = {'font' : {'color' : '0000FF00' }}
1563+
1564+ initial_cells = [
1565+ ExcelCell (col = 1 , row = 0 , val = 42 , style = sty_b1 ),
1566+ ExcelCell (col = 0 , row = 1 , val = 99 , style = sty_a2 ),
1567+ ]
1568+
1569+ sty_merged = {'font' : { 'color' : '000000FF' , 'bold' : True }}
1570+ sty_kwargs = _Openpyxl20Writer ._convert_to_style_kwargs (sty_merged )
1571+ openpyxl_sty_merged = styles .Style (** sty_kwargs )
1572+ merge_cells = [
1573+ ExcelCell (col = 0 , row = 0 , val = 'pandas' ,
1574+ mergestart = 1 , mergeend = 1 , style = sty_merged ),
1575+ ]
1576+
1577+ with ensure_clean ('.xlsx' ) as path :
1578+ writer = _Openpyxl20Writer (path )
1579+ writer .write_cells (initial_cells , sheet_name = sheet_name )
1580+ writer .write_cells (merge_cells , sheet_name = sheet_name )
1581+
1582+ wks = writer .sheets [sheet_name ]
1583+ xcell_b1 = wks .cell ('B1' )
1584+ xcell_a2 = wks .cell ('A2' )
1585+ self .assertEqual (xcell_b1 .style , openpyxl_sty_merged )
1586+ self .assertEqual (xcell_a2 .style , openpyxl_sty_merged )
1587+
1588+ def skip_openpyxl_lt22 (cls ):
1589+ """Skip a TestCase instance if openpyxl < 2.2"""
1590+
1591+ @classmethod
1592+ def setUpClass (cls ):
15451593 _skip_if_no_openpyxl ()
1594+ import openpyxl
1595+ ver = openpyxl .__version__
1596+ if ver < LooseVersion ('2.2.0' ):
1597+ raise nose .SkipTest ("openpyxl < 2.2" )
1598+
1599+ cls .setUpClass = setUpClass
1600+ return cls
1601+
1602+ @raise_on_incompat_version (2 )
1603+ @skip_openpyxl_lt22
1604+ class Openpyxl22Tests (ExcelWriterBase , tm .TestCase ):
1605+ ext = '.xlsx'
1606+ engine_name = 'openpyxl22'
1607+ check_skip = staticmethod (lambda * args , ** kwargs : None )
1608+
1609+ def test_to_excel_styleconverter (self ):
1610+ import openpyxl
1611+ from openpyxl import styles
1612+
1613+ hstyle = {
1614+ "font" : {
1615+ "color" : '00FF0000' ,
1616+ "bold" : True ,
1617+ },
1618+ "borders" : {
1619+ "top" : "thin" ,
1620+ "right" : "thin" ,
1621+ "bottom" : "thin" ,
1622+ "left" : "thin" ,
1623+ },
1624+ "alignment" : {
1625+ "horizontal" : "center" ,
1626+ "vertical" : "top" ,
1627+ },
1628+ "fill" : {
1629+ "patternType" : 'solid' ,
1630+ 'fgColor' : {
1631+ 'rgb' : '006666FF' ,
1632+ 'tint' : 0.3 ,
1633+ },
1634+ },
1635+ "number_format" : {
1636+ "format_code" : "0.00"
1637+ },
1638+ "protection" : {
1639+ "locked" : True ,
1640+ "hidden" : False ,
1641+ },
1642+ }
1643+
1644+ font_color = styles .Color ('00FF0000' )
1645+ font = styles .Font (bold = True , color = font_color )
1646+ side = styles .Side (style = styles .borders .BORDER_THIN )
1647+ border = styles .Border (top = side , right = side , bottom = side , left = side )
1648+ alignment = styles .Alignment (horizontal = 'center' , vertical = 'top' )
1649+ fill_color = styles .Color (rgb = '006666FF' , tint = 0.3 )
1650+ fill = styles .PatternFill (patternType = 'solid' , fgColor = fill_color )
1651+
1652+ number_format = '0.00'
1653+
1654+ protection = styles .Protection (locked = True , hidden = False )
1655+
1656+ kw = _Openpyxl22Writer ._convert_to_style_kwargs (hstyle )
1657+ self .assertEqual (kw ['font' ], font )
1658+ self .assertEqual (kw ['border' ], border )
1659+ self .assertEqual (kw ['alignment' ], alignment )
1660+ self .assertEqual (kw ['fill' ], fill )
1661+ self .assertEqual (kw ['number_format' ], number_format )
1662+ self .assertEqual (kw ['protection' ], protection )
1663+
1664+
1665+ def test_write_cells_merge_styled (self ):
15461666 if not openpyxl_compat .is_compat (major_ver = 2 ):
15471667 raise nose .SkipTest ('incompatiable openpyxl version' )
15481668
@@ -1560,23 +1680,23 @@ def test_write_cells_merge_styled(self):
15601680 ]
15611681
15621682 sty_merged = {'font' : { 'color' : '000000FF' , 'bold' : True }}
1563- sty_kwargs = _Openpyxl2Writer ._convert_to_style_kwargs (sty_merged )
1564- openpyxl_sty_merged = styles . Style ( ** sty_kwargs )
1683+ sty_kwargs = _Openpyxl22Writer ._convert_to_style_kwargs (sty_merged )
1684+ openpyxl_sty_merged = sty_kwargs [ 'font' ]
15651685 merge_cells = [
15661686 ExcelCell (col = 0 , row = 0 , val = 'pandas' ,
15671687 mergestart = 1 , mergeend = 1 , style = sty_merged ),
15681688 ]
15691689
15701690 with ensure_clean ('.xlsx' ) as path :
1571- writer = _Openpyxl2Writer (path )
1691+ writer = _Openpyxl22Writer (path )
15721692 writer .write_cells (initial_cells , sheet_name = sheet_name )
15731693 writer .write_cells (merge_cells , sheet_name = sheet_name )
15741694
15751695 wks = writer .sheets [sheet_name ]
15761696 xcell_b1 = wks .cell ('B1' )
15771697 xcell_a2 = wks .cell ('A2' )
1578- self .assertEqual (xcell_b1 .style , openpyxl_sty_merged )
1579- self .assertEqual (xcell_a2 .style , openpyxl_sty_merged )
1698+ self .assertEqual (xcell_b1 .font , openpyxl_sty_merged )
1699+ self .assertEqual (xcell_a2 .font , openpyxl_sty_merged )
15801700
15811701
15821702class XlwtTests (ExcelWriterBase , tm .TestCase ):
@@ -1676,9 +1796,9 @@ def test_column_format(self):
16761796 cell = read_worksheet .cell ('B2' )
16771797
16781798 try :
1679- read_num_format = cell .style . number_format . _format_code
1799+ read_num_format = cell .number_format
16801800 except :
1681- read_num_format = cell .style .number_format
1801+ read_num_format = cell .style .number_format . _format_code
16821802
16831803 self .assertEqual (read_num_format , num_format )
16841804
0 commit comments