-
-
Notifications
You must be signed in to change notification settings - Fork 19.2k
ENH: Add autofilter parameter to DataFrame.to_excel #62928
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
64f0742
b5faff1
3e8d5e3
89058bf
59f2bc4
ed54a54
dd7a53e
3bc720f
72562b4
5ce62dc
d82c621
e4012f0
763090d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -449,6 +449,7 @@ def _write_cells( | |
| startrow: int = 0, | ||
| startcol: int = 0, | ||
| freeze_panes: tuple[int, int] | None = None, | ||
| autofilter: bool = False, | ||
| ) -> None: | ||
| # Write the frame cells using openpyxl. | ||
| sheet_name = self._get_sheet_name(sheet_name) | ||
|
|
@@ -486,6 +487,11 @@ def _write_cells( | |
| row=freeze_panes[0] + 1, column=freeze_panes[1] + 1 | ||
| ) | ||
|
|
||
| min_r = None | ||
| min_c = None | ||
| max_r = None | ||
| max_c = None | ||
|
|
||
| for cell in cells: | ||
| xcell = wks.cell( | ||
| row=startrow + cell.row + 1, column=startcol + cell.col + 1 | ||
|
|
@@ -506,10 +512,23 @@ def _write_cells( | |
| for k, v in style_kwargs.items(): | ||
| setattr(xcell, k, v) | ||
|
|
||
| abs_row = startrow + cell.row + 1 | ||
| abs_col = startcol + cell.col + 1 | ||
|
|
||
| # track bounds (1-based for openpyxl) | ||
| if min_r is None or abs_row < min_r: | ||
|
Comment on lines
+518
to
+519
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we able to determine these by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@rhshadrach To use shape-based calculation, we'd need to:
The current approach tracks bounds while iterating through the cells we're already writing:
If you prefer a shape-based calculation, I can add those parameters to |
||
| min_r = abs_row | ||
| if min_c is None or abs_col < min_c: | ||
| min_c = abs_col | ||
| if max_r is None or abs_row > max_r: | ||
| max_r = abs_row | ||
| if max_c is None or abs_col > max_c: | ||
| max_c = abs_col | ||
|
|
||
| if cell.mergestart is not None and cell.mergeend is not None: | ||
| wks.merge_cells( | ||
| start_row=startrow + cell.row + 1, | ||
| start_column=startcol + cell.col + 1, | ||
| start_row=abs_row, | ||
| start_column=abs_col, | ||
| end_column=startcol + cell.mergeend + 1, | ||
| end_row=startrow + cell.mergestart + 1, | ||
| ) | ||
|
|
@@ -532,6 +551,14 @@ def _write_cells( | |
| for k, v in style_kwargs.items(): | ||
| setattr(xcell, k, v) | ||
|
|
||
| if autofilter and min_r is not None and min_c is not None and max_r is not None and max_c is not None: | ||
| # Convert numeric bounds to Excel-style range e.g. A1:D10 | ||
| from openpyxl.utils import get_column_letter | ||
|
|
||
| start_ref = f"{get_column_letter(min_c)}{min_r}" | ||
| end_ref = f"{get_column_letter(max_c)}{max_r}" | ||
| wks.auto_filter.ref = f"{start_ref}:{end_ref}" | ||
|
|
||
|
|
||
| class OpenpyxlReader(BaseExcelReader["Workbook"]): | ||
| @doc(storage_options=_shared_docs["storage_options"]) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the doc decorator on L2149
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also - it looks like there was a merge issue here and code got duplicated below.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a specific reason to remove the decorator, or would you prefer a different docstring format? If you saw something else at L2149, can you point me to the exact location?