From 60337c6863df2ddfb5331d322ce1fef545820104 Mon Sep 17 00:00:00 2001 From: Akira Date: Mon, 11 Nov 2024 09:17:30 +0900 Subject: [PATCH] Fix printing area and options step5 --- SumasenLibs/excel_lib/sumaexcel/sumaexcel.py | 305 ++++++++++--------- 1 file changed, 167 insertions(+), 138 deletions(-) diff --git a/SumasenLibs/excel_lib/sumaexcel/sumaexcel.py b/SumasenLibs/excel_lib/sumaexcel/sumaexcel.py index 6b13944..f02dbc5 100644 --- a/SumasenLibs/excel_lib/sumaexcel/sumaexcel.py +++ b/SumasenLibs/excel_lib/sumaexcel/sumaexcel.py @@ -882,6 +882,31 @@ class SumasenExcel: logging.error(f"Error verifying merged cell borders: {str(e)}") return None + def initialize_worksheet_properties(self, worksheet): + """ + ワークシートのプロパティを初期化する + + Args: + worksheet: 初期化対象のワークシート + """ + try: + from openpyxl.worksheet.properties import WorksheetProperties, PageSetupProperties + + # sheet_properties が None の場合は新しく作成 + if worksheet.sheet_properties is None: + worksheet.sheet_properties = WorksheetProperties() + + # pageSetUpPr が None の場合は新しく作成 + if worksheet.sheet_properties.pageSetUpPr is None: + worksheet.sheet_properties.pageSetUpPr = PageSetupProperties(fitToPage=True) + + logging.info(f"Worksheet properties initialized successfully") + + except Exception as e: + logging.error(f"Error initializing worksheet properties: {str(e)}") + import traceback + logging.error(traceback.format_exc()) + def copy_print_scaling_settings(self, source_sheet, target_sheet): """ 印刷の拡大縮小設定を正確にコピーする @@ -891,69 +916,63 @@ class SumasenExcel: target_sheet: コピー先のワークシート """ try: + # シートプロパティの初期化 + self.initialize_worksheet_properties(target_sheet) + if not hasattr(source_sheet, 'page_setup') or not hasattr(target_sheet, 'page_setup'): logging.error("Sheet does not have page_setup attribute") return - source_setup = source_sheet.page_setup - target_setup = target_sheet.page_setup + # page_setup の取得と検証 + source_setup = getattr(source_sheet, 'page_setup', None) + target_setup = getattr(target_sheet, 'page_setup', None) - # シートプロパティの初期化確認 - if not hasattr(target_sheet, 'sheet_properties'): - target_sheet.sheet_properties = openpyxl.worksheet.properties.WorksheetProperties() - - # 基本的な印刷設定の初期化 - target_setup.paperSize = source_setup.paperSize - target_setup.orientation = source_setup.orientation - - # 印刷の拡大縮小設定 - target_sheet.sheet_properties.pageSetUpPr = openpyxl.worksheet.properties.PageSetupProperties( - fitToPage=True - ) + if source_setup is None or target_setup is None: + logging.error("Page setup is not available") + return - # まず現在の設定をクリア + + # 印刷の拡大縮小設定をクリア target_setup.scale = None target_setup.fitToWidth = None target_setup.fitToHeight = None # fitToPage の設定 - if hasattr(source_setup, 'fitToPage'): - fitToPage = source_setup.fitToPage - else: - # テンプレートに設定がない場合のデフォルト - fitToPage = True + fit_to_page = getattr(source_setup, 'fitToPage', True) + target_setup.fitToPage = fit_to_page - if fitToPage: + if fit_to_page: # 「次のページに合わせる」設定 - target_setup.fitToPage = True - if hasattr(source_setup, 'fitToWidth'): - target_setup.fitToWidth = source_setup.fitToWidth or 1 - else: - target_setup.fitToWidth = 1 + target_setup.fitToWidth = getattr(source_setup, 'fitToWidth', 1) or 1 + target_setup.fitToHeight = getattr(source_setup, 'fitToHeight', None) - if hasattr(source_setup, 'fitToHeight'): - target_setup.fitToHeight = source_setup.fitToHeight - else: - target_setup.fitToHeight = None + # シートプロパティでも fitToPage を設定 + if hasattr(target_sheet.sheet_properties, 'pageSetUpPr'): + target_sheet.sheet_properties.pageSetUpPr.fitToPage = True else: # 拡大縮小率指定 - target_setup.fitToPage = False - if hasattr(source_setup, 'scale'): - target_setup.scale = source_setup.scale or 100 - else: - target_setup.scale = 100 + scale = getattr(source_setup, 'scale', 100) + target_setup.scale = scale if scale is not None else 100 + + if hasattr(target_sheet.sheet_properties, 'pageSetUpPr'): + target_sheet.sheet_properties.pageSetUpPr.fitToPage = False - logging.info(f"Print scaling settings copied - " + logging.info(f"Print scaling settings - " f"fitToPage: {target_setup.fitToPage}, " f"fitToWidth: {target_setup.fitToWidth}, " f"fitToHeight: {target_setup.fitToHeight}, " f"scale: {target_setup.scale}") + except AttributeError as ae: + logging.error(f"Attribute error while copying print settings: {str(ae)}") + import traceback + logging.error(traceback.format_exc()) except Exception as e: logging.error(f"Error copying print scaling settings: {str(e)}") import traceback logging.error(traceback.format_exc()) + def copy_cell_formatting(self, source_cell, target_cell): """ セルのフォーマット(罫線を含む)を正確にコピーする @@ -1077,6 +1096,40 @@ class SumasenExcel: target_min_col, target_min_row, target_max_col, target_max_row = range_boundaries(target_range) #print(f"min_col, min_row, max_col, max_row = {orig_min_col}, {orig_min_row}, {orig_max_col}, {orig_max_row}") + # シートプロパティの初期化を先に実行 + self.initialize_worksheet_properties(self.current_sheet) + + # 印刷設定のコピー + self.copy_print_scaling_settings(self.template_sheet, self.current_sheet) + + # 印刷範囲の設定をコピー + if self.template_sheet.print_area: + self.current_sheet.print_area = self.template_sheet.print_area + + # 印刷範囲の設定をコピーして調整 + if self.template_sheet.print_area: + # 最終データ行を取得 + last_data_row = self.get_last_data_row() + + # 印刷範囲を調整 + adjusted_print_area = self.adjust_print_area( + self.template_sheet.print_area, + last_data_row + ) + + if adjusted_print_area: + self.current_sheet.print_area = adjusted_print_area + logging.info(f"Print area set to: {adjusted_print_area}") + + + # 印刷タイトルの設定をコピー + if self.template_sheet.print_title_rows: + self.current_sheet.print_title_rows = self.template_sheet.print_title_rows + if self.template_sheet.print_title_cols: + self.current_sheet.print_title_cols = self.template_sheet.print_title_cols + + + # Get template sheet name from ini file section_config = self.conf.get_section(self.section_list[0]) # 現在の処理中のセクション template_sheet_name = section_config.get("template_sheet") @@ -1132,50 +1185,7 @@ class SumasenExcel: # #print(f"Merge : {target_merge_range}") - # 印刷範囲の設定をコピー - if self.template_sheet.print_area: - self.current_sheet.print_area = self.template_sheet.print_area - - # 印刷範囲の設定をコピーして調整 - if self.template_sheet.print_area: - # 最終データ行を取得 - last_data_row = self.get_last_data_row() - - # 印刷範囲を調整 - adjusted_print_area = self.adjust_print_area( - self.template_sheet.print_area, - last_data_row - ) - - if adjusted_print_area: - self.current_sheet.print_area = adjusted_print_area - logging.info(f"Print area set to: {adjusted_print_area}") - - - # 印刷タイトルの設定をコピー - if self.template_sheet.print_title_rows: - self.current_sheet.print_title_rows = self.template_sheet.print_title_rows - if self.template_sheet.print_title_cols: - self.current_sheet.print_title_cols = self.template_sheet.print_title_cols - - # 拡大縮小印刷の設定を正確にコピー - self.copy_print_scaling_settings(self.template_sheet, self.current_sheet) - - # シートプロパティの確認と初期化 - if not hasattr(self.current_sheet, 'sheet_properties'): - self.current_sheet.sheet_properties = openpyxl.worksheet.properties.WorksheetProperties() - - # 印刷範囲の設定をコピーして調整 - if hasattr(self.template_sheet, 'print_area') and self.template_sheet.print_area: - last_data_row = self.get_last_data_row() - adjusted_print_area = self.adjust_print_area( - self.template_sheet.print_area, - last_data_row - ) - if adjusted_print_area: - self.current_sheet.print_area = adjusted_print_area - logging.info(f"Print area set to: {adjusted_print_area}") - + # ページ設定のコピー if hasattr(self.template_sheet, 'page_setup') and hasattr(self.current_sheet, 'page_setup'): @@ -1255,76 +1265,95 @@ class SumasenExcel: return {"status": True, "message": "Successfully copied template range"} + except AttributeError as ae: + logging.error(f"Attribute error in copy_template_to_current: {str(ae)}") + import traceback + logging.error(traceback.format_exc()) + return {"status": False, "message": f"Attribute error in copy_template_to_current: {str(ae)}"} except Exception as e: logging.error(f"Error in copy_template_to_current: {str(e)}") - return {"status": False, "message": f"Exception in copy_template_to_current: {str(e)}"} + import traceback + logging.error(traceback.format_exc()) + return {"status": False, "message": f"Error in copy_template_to_current: {str(e)}"} def _verify_print_settings(self): """ 印刷設定が正しくコピーされたことを検証する """ try: - source_setup = self.template_sheet.page_setup - target_setup = self.current_sheet.page_setup + source_setup = getattr(self.template_sheet, 'page_setup', None) + target_setup = getattr(self.current_sheet, 'page_setup', None) + + if source_setup is None or target_setup is None: + logging.warning("Cannot verify print settings - page_setup not available") + return + + # fitToPage の検証 + source_fit_to_page = getattr(source_setup, 'fitToPage', None) + target_fit_to_page = getattr(target_setup, 'fitToPage', None) + + if source_fit_to_page != target_fit_to_page: + logging.warning(f"fitToPage setting mismatch: " + f"template={source_fit_to_page}, current={target_fit_to_page}") + + if source_fit_to_page: + # fitToWidth/Height の検証 + source_fit_to_width = getattr(source_setup, 'fitToWidth', None) + target_fit_to_width = getattr(target_setup, 'fitToWidth', None) + if source_fit_to_width != target_fit_to_width: + logging.warning(f"fitToWidth setting mismatch: " + f"template={source_fit_to_width}, current={target_fit_to_width}") + + source_fit_to_height = getattr(source_setup, 'fitToHeight', None) + target_fit_to_height = getattr(target_setup, 'fitToHeight', None) + if source_fit_to_height != target_fit_to_height: + logging.warning(f"fitToHeight setting mismatch: " + f"template={source_fit_to_height}, current={target_fit_to_height}") + else: + # scale の検証 + source_scale = getattr(source_setup, 'scale', None) + target_scale = getattr(target_setup, 'scale', None) + if source_scale != target_scale: + logging.warning(f"scale setting mismatch: " + f"template={source_scale}, current={target_scale}") + + except AttributeError as ae: + logging.error(f"Attribute error in verify print settings: {str(ae)}") + import traceback + logging.error(traceback.format_exc()) + except Exception as e: + logging.error(f"Error in verify print settings: {str(e)}") + import traceback + logging.error(traceback.format_exc()) - # 拡大縮小設定の検証 - if source_setup.fitToPage != target_setup.fitToPage: - logging.warning( - f"fitToPage setting mismatch: template={source_setup.fitToPage}, " - f"current={target_setup.fitToPage}" - ) - if source_setup.fitToPage: - # 「次のページに合わせる」設定の検証 - if source_setup.fitToWidth != target_setup.fitToWidth: - logging.warning( - f"fitToWidth setting mismatch: template={source_setup.fitToWidth}, " - f"current={target_setup.fitToWidth}" - ) - if source_setup.fitToHeight != target_setup.fitToHeight: - logging.warning( - f"fitToHeight setting mismatch: template={source_setup.fitToHeight}, " - f"current={target_setup.fitToHeight}" - ) - elif source_setup.scale != target_setup.scale: - logging.warning( - f"scale setting mismatch: template={source_setup.scale}, " - f"current={target_setup.scale}" - ) - - # 罫線の検証(サンプリング) - self._verify_borders() + def _verify_borders(self): + """ + 罫線が正しくコピーされているか検証する + """ + try: + # サンプリングで罫線をチェック + for row in self.current_sheet.iter_rows(min_row=1, max_row=10): + for cell in row: + if cell.border: + # 対応するテンプレートのセルを取得 + template_cell = self.template_sheet.cell( + row=cell.row, + column=cell.column + ) + + # 罫線の設定を比較 + if template_cell.border: + if (template_cell.border.left != cell.border.left or + template_cell.border.right != cell.border.right or + template_cell.border.top != cell.border.top or + template_cell.border.bottom != cell.border.bottom): + logging.warning( + f"Border mismatch at cell {cell.coordinate}" + ) except Exception as e: - logging.error(f"Error in _verify_print_settings: {str(e)}") - -def _verify_borders(self): - """ - 罫線が正しくコピーされているか検証する - """ - try: - # サンプリングで罫線をチェック - for row in self.current_sheet.iter_rows(min_row=1, max_row=10): - for cell in row: - if cell.border: - # 対応するテンプレートのセルを取得 - template_cell = self.template_sheet.cell( - row=cell.row, - column=cell.column - ) - - # 罫線の設定を比較 - if template_cell.border: - if (template_cell.border.left != cell.border.left or - template_cell.border.right != cell.border.right or - template_cell.border.top != cell.border.top or - template_cell.border.bottom != cell.border.bottom): - logging.warning( - f"Border mismatch at cell {cell.coordinate}" - ) - - except Exception as e: - logging.error(f"Error in _verify_borders: {str(e)}") + logging.error(f"Error in _verify_borders: {str(e)}") # Style operations def apply_style(