@@ -353,16 +353,84 @@ def test_format_hierarchical_rows_periodindex(merge_cells):
353353
354354
355355@pytest .mark .parametrize ("engine" , ["xlsxwriter" , "openpyxl" ])
356- def test_autofilter (engine , tmp_excel ):
356+ @pytest .mark .parametrize ("with_index" , [True , False ])
357+ def test_autofilter (engine , with_index , tmp_excel ):
357358 # GH 61194
358359 df = DataFrame .from_dict ([{"A" : 1 , "B" : 2 , "C" : 3 }, {"A" : 4 , "B" : 5 , "C" : 6 }])
359360
360361 with ExcelWriter (tmp_excel , engine = engine ) as writer :
361- df .to_excel (writer , autofilter = True , index = False )
362+ df .to_excel (writer , autofilter = True , index = with_index )
362363
363364 openpyxl = pytest .importorskip ("openpyxl" ) # test loading only with openpyxl
364365 with contextlib .closing (openpyxl .load_workbook (tmp_excel )) as wb :
365366 ws = wb .active
366367
367368 assert ws .auto_filter .ref is not None
368- assert ws .auto_filter .ref == "A1:D3"
369+ assert ws .auto_filter .ref == "A1:D3" if with_index else "A1:C3"
370+
371+
372+ @pytest .mark .parametrize ("engine" , ["xlsxwriter" , "openpyxl" ])
373+ def test_autofilter_with_startrow_startcol (engine , tmp_excel ):
374+ # GH 61194
375+ df = DataFrame .from_dict ([{"A" : 1 , "B" : 2 , "C" : 3 }, {"A" : 4 , "B" : 5 , "C" : 6 }])
376+ with ExcelWriter (tmp_excel , engine = engine ) as writer :
377+ df .to_excel (writer , autofilter = True , startrow = 10 , startcol = 10 )
378+
379+ openpyxl = pytest .importorskip ("openpyxl" ) # test loading only with openpyxl
380+ with contextlib .closing (openpyxl .load_workbook (tmp_excel )) as wb :
381+ ws = wb .active
382+ assert ws .auto_filter .ref is not None
383+ # Autofiler range moved by 10x10 cells
384+ assert ws .auto_filter .ref == "K11:N13"
385+
386+
387+ def test_autofilter_not_supported_by_odf (tmp_path ):
388+ # GH 61194
389+ # odf needs 'ods' extension
390+ tmp_excel_ods = tmp_path / f"{ uuid .uuid4 ()} .ods"
391+ tmp_excel_ods .touch ()
392+
393+ with pytest .raises (ValueError , match = "Autofilter is not supported with odf!" ):
394+ with ExcelWriter (str (tmp_excel_ods ), engine = "odf" ) as writer :
395+ DataFrame ().to_excel (writer , autofilter = True , index = False )
396+
397+
398+ @pytest .mark .parametrize ("engine" , ["xlsxwriter" , "openpyxl" ])
399+ def test_autofilter_with_multiindex (engine , tmp_excel ):
400+ # GH 61194
401+ df = DataFrame (
402+ {
403+ "animal" : ("horse" , "horse" , "dog" , "dog" ),
404+ "color of fur" : ("black" , "white" , "grey" , "black" ),
405+ "name" : ("Blacky" , "Wendy" , "Rufus" , "Catchy" ),
406+ }
407+ )
408+ mi_df = df .set_index (["animal" , "color of fur" ])
409+ with ExcelWriter (tmp_excel , engine = engine ) as writer :
410+ mi_df .to_excel (writer , autofilter = True , index = True , merge_cells = False )
411+
412+ openpyxl = pytest .importorskip ("openpyxl" ) # test loading only with openpyxl
413+ with contextlib .closing (openpyxl .load_workbook (tmp_excel )) as wb :
414+ ws = wb .active
415+
416+ assert ws .auto_filter .ref is not None
417+ assert ws .auto_filter .ref == "A1:C5"
418+
419+
420+ def test_autofilter_with_multiindex_and_merge_cells_shows_warning (tmp_excel ):
421+ # GH 61194
422+ df = DataFrame (
423+ {
424+ "animal" : ("horse" , "horse" , "dog" , "dog" ),
425+ "color of fur" : ("black" , "white" , "grey" , "black" ),
426+ "name" : ("Blacky" , "Wendy" , "Rufus" , "Catchy" ),
427+ }
428+ )
429+ mi_df = df .set_index (["animal" , "color of fur" ])
430+ with ExcelWriter (tmp_excel , engine = "openpyxl" ) as writer :
431+ with tm .assert_produces_warning (
432+ UserWarning ,
433+ match = "Excel filters merged cells by showing only the first row."
434+ "'autofiler' and 'merge_cells' should not be used simultaneously." ,
435+ ):
436+ mi_df .to_excel (writer , autofilter = True , index = True , merge_cells = True )
0 commit comments