質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
openpyxl

openpyxlは、Excel2007以降のファイル(xlsx/xlsm/xltx/xltm)を読み書きするためのPythonライブラリです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1289閲覧

openpyxl セルサイズ読み取り時にサイズを上書きしてしまう

mdkh

総合スコア33

openpyxl

openpyxlは、Excel2007以降のファイル(xlsx/xlsm/xltx/xltm)を読み書きするためのPythonライブラリです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/07/01 02:18

編集2022/07/04 05:49

目的としては、python経由で画像ファイルをエクセルの 'A1'セルから横3セル縦4セルの大きさで貼り付けようとしています。
以下、コードの一部で目標位置からサイズ分ループを回し、セルのサイズを取得してリサイズ目標を計算しています。

python

1 wb = openpyxl.load_workbook("testSheet.xlsx") 2 workSheet = wb[wb.sheetnames[0]] 3 Xpoints = 0.0 4 Ypoints = 0.0 5 for i in range(0,sizeX): 6 #! HACK: XXX: ここの2行でかなり違和感のある挙動 7 #! colWidth = ... の行で列幅を読むと書き込みしていないのに列幅が変わって保存される 8 #! workSheet. ...の行を追加して戻すわけだが、9/13倍しないと元の幅にならない 9 colWidth = workSheet.column_dimensions[openpyxl.utils.get_column_letter(pos[1]+i)].width 10 workSheet.column_dimensions[openpyxl.utils.get_column_letter(pos[1]+i)].width = 9 /13 * colWidth 11 #!--------------------------------------- 12 #print("width"+str(i)+" is "+str(colWidth)) 13 Xpoints = Xpoints + colWidth 14 Xpixel = cellSizeToPixel(Xpoints,isWidth = True) 15#以降、高さ取得・画像リサイズ、貼り付け部分省略

不明な挙動としてはおおよそコード内のコメント通りなのですが、

・(10行目をコメントアウトして)9行目でサイズの読み取りを行うと、列幅が広がってしまう
→読み取った値自体は正しく、手動で列幅を戻すと貼り付けた画像が指定したセル数と一致しています

・10行目で読み取った値に戻そうとすると 9/13倍する必要がある
→ 9/13 倍は widthのデフォルト値である 13 を基に試行錯誤的に発見した値です

エクセルシートは空のシートを作成して保存したものを使用しており、colWidth = 13.0と読み取られます。
(列幅を変更して実行した場合それに応じて値が変化し、画像サイズも一致します)

質問したいこととしては、「9 /13 倍して代入している部分以外で代入操作を行っていないにもかかわらず、セルサイズが変更されてしまう要因の候補はあるか」という点です。
サイズに限らず、何らか意図しないタイミングでセルの属性が書き換わってしまったことがある方がおられればそれを修正した手段を回答いただけると助かります

追加
反復した場合、広がるのが初回のみで、widthを短く入れなおすようにすると2回目以降でだんだん短くなってしまう
->読み出しによって大きくなってしまうというよりは、明示的に設定していないときexcel上の見かけ幅が9.0,数値上は13になっていて読みだしたときに見かけが数値に揃う?
見かけと設定値の食い違ったことがある方がおられればそれを修正した手段を回答いただけると助かります

参考:
https://openpyxl.readthedocs.io/en/stable/api/openpyxl.worksheet.dimensions.html?highlight=dimension#openpyxl.worksheet.dimensions.Dimension

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

連続する同サイズのセル幅が連続の頭の部分にしか入っていないこと、デフォルト値がexcel標準の空白のセルと違う?ことが原因で、読みたい値が[9,9,50,50,9]とすると、デフォルト値13として[13,13,50,13,13]などのようにと読んでしまうのが原因だと思われます。(読んだときにシートに反映してしまう理由、height方向で生起しない理由は不明のまま放置)

worksheet読み取り時にwidthの情報を埋めなおしておくことで質問時のコードから( ....= 9 /13 * colWidth)の行を削除した状態で意図通り読めるようになったのでひとまず自己解決としておきます
(openpyxlの定義を曲げてしまっていそうなのでHACK的で非推奨。せめてwsを直接書き換えず別枠で持っておくべき?)

python

1 iterator= iter(range(1,20)) 2 for i in iterator: 3 seqRow = worksheet.column_dimensions[openpyxl.utils.get_column_letter(i)].max #同じサイズの終わり 4 if seqRow != None : 5 if seqRow > i: 6 for j in range(i+1,seqRow+1): 7 #print ("replace col "+openpyxl.utils.get_column_letter(j)+" to "+str(worksheet.column_dimensions[openpyxl.utils.get_column_letter(i)].width)) 8 worksheet.column_dimensions[openpyxl.utils.get_column_letter(j)].width = worksheet.column_dimensions[openpyxl.utils.get_column_letter(i)].width 9 next(iterator) 10 else: 11 worksheet.column_dimensions[openpyxl.utils.get_column_letter(i)].width = 9.0 #default

投稿2022/07/04 09:03

mdkh

総合スコア33

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

この10行目?は、セル幅を9に設定 = 13だったのを9にしているのだから9/13にしている、ようにみえますが、どういう意図の処理ですか?

python

1workSheet.column_dimensions[openpyxl.utils.get_column_letter(pos[1]+i)].width = 9

この処理を目的どおりにすればいいのではないでしょうか。

投稿2022/07/01 10:35

TakaiY

総合スコア12765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mdkh

2022/07/01 10:58

そのひとつ上のcolWidthを読み取る行で列幅13という値が読まれるのですが、こちらのみ実行した時読み取り後worksheetでは列幅が他の列よりも長くなって保存されます。 ご指摘の行は対処療法的に少し短い値を入れ直して体裁を保つという意図の処理です。 この行を挟むことで、目的どおりの画像挿入はできているのですが、読み取った値より小さい値を代入する事で戻るという理解不能な挙動が残らないことを是としたく思っています
TakaiY

2022/07/01 11:25 編集

なるほど。質問の意味がやっとわかりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問