|
37 | 37 | WriteExcelBuffer,
|
38 | 38 | )
|
39 | 39 |
|
| 40 | + from pandas.core.frame import DataFrame |
| 41 | + |
40 | 42 |
|
41 | 43 | class OpenpyxlWriter(ExcelWriter):
|
42 | 44 | _engine = "openpyxl"
|
@@ -447,7 +449,10 @@ def _write_cells(
|
447 | 449 | startrow: int = 0,
|
448 | 450 | startcol: int = 0,
|
449 | 451 | freeze_panes: tuple[int, int] | None = None,
|
| 452 | + notes: DataFrame | None = None, |
450 | 453 | ) -> None:
|
| 454 | + from openpyxl.comments import Comment |
| 455 | + |
451 | 456 | # Write the frame cells using openpyxl.
|
452 | 457 | sheet_name = self._get_sheet_name(sheet_name)
|
453 | 458 |
|
@@ -484,7 +489,11 @@ def _write_cells(
|
484 | 489 | row=freeze_panes[0] + 1, column=freeze_panes[1] + 1
|
485 | 490 | )
|
486 | 491 |
|
| 492 | + notes_col = None |
| 493 | + |
487 | 494 | for cell in cells:
|
| 495 | + if notes_col is None: |
| 496 | + notes_col = startcol + cell.col + 1 |
488 | 497 | xcell = wks.cell(
|
489 | 498 | row=startrow + cell.row + 1, column=startcol + cell.col + 1
|
490 | 499 | )
|
@@ -530,6 +539,20 @@ def _write_cells(
|
530 | 539 | for k, v in style_kwargs.items():
|
531 | 540 | setattr(xcell, k, v)
|
532 | 541 |
|
| 542 | + if notes is None or notes_col is None: |
| 543 | + return |
| 544 | + |
| 545 | + for row_idx, val in enumerate(notes.itertuples(index=False)): |
| 546 | + for col_idx, note in enumerate(val): |
| 547 | + xcell = wks.cell( |
| 548 | + # first row has columns and openpyxl starts counting at 1, not 0 |
| 549 | + row=row_idx + 2, |
| 550 | + column=col_idx + notes_col, # n columns with indexes |
| 551 | + ) |
| 552 | + if note: |
| 553 | + comment = Comment(str(note), "") |
| 554 | + xcell.comment = comment |
| 555 | + |
533 | 556 |
|
534 | 557 | class OpenpyxlReader(BaseExcelReader["Workbook"]):
|
535 | 558 | @doc(storage_options=_shared_docs["storage_options"])
|
|
0 commit comments