@@ -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 ]
0 commit comments