Skip to content

Commit 9d71bc6

Browse files
k-ibarakiclaude
andcommitted
perf: optimize cell style retrieval with caching
Geminiコードレビュー対応: 1. パフォーマンス改善 - 列幅・行高さのキャッシュを_parse_sheetレベルで構築 - 各セルごとのsheet.column_dimensions/row_dimensionsアクセスを削減 - 大きなシートでのパフォーマンス向上 2. テストの改善 - test_cell_styles_none_when_not_setを簡潔化 - より直接的なアサーションに変更 変更内容: - _parse_sheet(): col_widths/row_heightsキャッシュを構築 - _parse_rows(): キャッシュを_parse_cell()に伝播 - _parse_cell(): キャッシュから列幅・行高さを取得 - tests: アサーションを簡潔化 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 8151cc7 commit 9d71bc6

2 files changed

Lines changed: 38 additions & 18 deletions

File tree

src/sharepoint_excel.py

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,19 @@ def _parse_sheet(
526526
if merged_ranges:
527527
sheet_data["merged_ranges"] = merged_ranges
528528

529+
# セルサイズのキャッシュを構築(パフォーマンス最適化)
530+
col_widths: dict[str, float] | None = None
531+
row_heights: dict[int, float] | None = None
532+
if include_cell_styles:
533+
col_widths = {}
534+
row_heights = {}
535+
for col_letter, dim in sheet.column_dimensions.items():
536+
if dim.width:
537+
col_widths[col_letter] = dim.width
538+
for row_num, dim in sheet.row_dimensions.items():
539+
if dim.height:
540+
row_heights[row_num] = dim.height
541+
529542
# データ取得
530543
if cell_range:
531544
# ヘッダー自動追加(include_frozen_rows=Trueの場合)
@@ -540,6 +553,8 @@ def _parse_sheet(
540553
include_cell_styles,
541554
merged_cell_map,
542555
merged_anchor_value_map,
556+
col_widths,
557+
row_heights,
543558
)
544559
)
545560

@@ -552,6 +567,8 @@ def _parse_sheet(
552567
include_cell_styles,
553568
merged_cell_map,
554569
merged_anchor_value_map,
570+
col_widths,
571+
row_heights,
555572
)
556573
)
557574

@@ -566,6 +583,8 @@ def _parse_sheet(
566583
include_cell_styles,
567584
merged_cell_map,
568585
merged_anchor_value_map,
586+
col_widths,
587+
row_heights,
569588
)
570589
)
571590

@@ -754,6 +773,8 @@ def _parse_cell(
754773
include_cell_styles: bool = False,
755774
merged_cell_map: dict[str, str] | None = None,
756775
merged_anchor_value_map: dict[str, Any] | None = None,
776+
col_widths: dict[str, float] | None = None,
777+
row_heights: dict[int, float] | None = None,
757778
) -> dict[str, Any]:
758779
"""
759780
セルを解析してdict形式で返す
@@ -763,6 +784,8 @@ def _parse_cell(
763784
include_cell_styles: セルのスタイル情報を含めるか(デフォルト: False)
764785
merged_cell_map: マージセル座標からマージ範囲へのマップ(パフォーマンス最適化用)
765786
merged_anchor_value_map: マージ範囲 -> アンカー値 のマップ(結合セルの値埋め用)
787+
col_widths: 列幅のキャッシュ(パフォーマンス最適化用)
788+
row_heights: 行高さのキャッシュ(パフォーマンス最適化用)
766789
767790
Returns:
768791
セルデータのdict
@@ -807,17 +830,12 @@ def _parse_cell(
807830
# MergedCellの場合は属性が存在しないため、hasattrでチェック
808831
if hasattr(cell, "column_letter") and hasattr(cell, "row"):
809832
if cell.column_letter and cell.row:
810-
sheet = cell.parent
811-
# 列幅
812-
if cell.column_letter in sheet.column_dimensions:
813-
col_dim = sheet.column_dimensions[cell.column_letter]
814-
if col_dim.width:
815-
cell_data["width"] = col_dim.width
816-
# 行高さ
817-
if cell.row in sheet.row_dimensions:
818-
row_dim = sheet.row_dimensions[cell.row]
819-
if row_dim.height:
820-
cell_data["height"] = row_dim.height
833+
# キャッシュから列幅を取得(パフォーマンス最適化)
834+
if col_widths and cell.column_letter in col_widths:
835+
cell_data["width"] = col_widths[cell.column_letter]
836+
# キャッシュから行高さを取得(パフォーマンス最適化)
837+
if row_heights and cell.row in row_heights:
838+
cell_data["height"] = row_heights[cell.row]
821839

822840
return cell_data
823841

@@ -827,6 +845,8 @@ def _parse_rows(
827845
include_cell_styles: bool = False,
828846
merged_cell_map: dict[str, str] | None = None,
829847
merged_anchor_value_map: dict[str, Any] | None = None,
848+
col_widths: dict[str, float] | None = None,
849+
row_heights: dict[int, float] | None = None,
830850
) -> list[list[dict[str, Any]]]:
831851
"""
832852
行データを解析してリスト形式で返す(コード重複削減用ヘルパー)
@@ -836,6 +856,8 @@ def _parse_rows(
836856
include_cell_styles: セルのスタイル情報を含めるか
837857
merged_cell_map: マージセル情報
838858
merged_anchor_value_map: マージ範囲 -> アンカー値
859+
col_widths: 列幅のキャッシュ(パフォーマンス最適化用)
860+
row_heights: 行高さのキャッシュ(パフォーマンス最適化用)
839861
840862
Returns:
841863
解析された行データのリスト
@@ -848,6 +870,8 @@ def _parse_rows(
848870
include_cell_styles,
849871
merged_cell_map,
850872
merged_anchor_value_map,
873+
col_widths,
874+
row_heights,
851875
)
852876
for cell in row
853877
]

tests/test_sharepoint_excel.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,10 +1498,6 @@ def test_cell_styles_none_when_not_set(self):
14981498
assert cell["coordinate"] == "A1"
14991499

15001500
# スタイルが設定されていないので、fillやwidth/heightは含まれない
1501-
# (openpyxlがデフォルト値を返す場合もあるが、明示的に設定されていない)
1502-
# fill情報がない、またはpattern_typeがNoneの場合は含まれない
1503-
if "fill" in cell:
1504-
# fillが含まれる場合でも、pattern_typeが設定されていないはず
1505-
assert cell["fill"].get("pattern_type") is None or cell["fill"].get(
1506-
"pattern_type"
1507-
) == "none"
1501+
assert "fill" not in cell
1502+
assert "width" not in cell
1503+
assert "height" not in cell

0 commit comments

Comments
 (0)