teratail header banner
teratail header banner
質問するログイン新規登録

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

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

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

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

Q&A

解決済

3回答

908閲覧

pythonでのexcelプロパティ削除時、書式がクリアされてしまう

trouble_maker77

総合スコア10

Python

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

0グッド

0クリップ

投稿2024/05/09 01:38

0

0

実現したいこと

以下のコードでexcelファイルのプロパティを一括削除した際、シート内の書式(取り消し線や太字など)がクリアされてしまうため、書式クリアせずプロパティ削除を行いたい。

発生している問題・分からないこと

書式クリアされない方法を知りたい

該当のソースコード

python

1# coding: utf -8 2from tkinter import filedialog 3import os 4import openpyxl 5 6 7def main(): 8 # 対象のフォルダパス取得 9 fTyp = [("", "*")] 10 iDir = os.path.abspath(os.path.dirname(__file__)) 11 folder_path = filedialog.askdirectory( initialdir=iDir , title="対象のフォルダを選択" ) 12 serch_file(folder_path) 13 return 14 15 16def serch_file(path): 17 with os.scandir(path) as it: 18 for entry in it: 19 # 対象ファイルがディレクトリ 20 if entry.is_dir(): 21 # 再起処理による検索 22 serch_file(entry.path) 23 # 対象ファイルがディレクトリ以外 24 elif entry.is_file(): 25 if ".xlsx" in entry.name: 26 delete_properties(entry.path) 27 print(entry.path) 28 return 29 30 31def delete_properties(path): 32 # Excelファイルの読み込み 33 wb = openpyxl.load_workbook(path) 34 props = wb.properties 35 # プロパティ情報を削除する 36 # 説明 37 props.title=None 38 props.subject=None 39 props.keywords=None 40 props.category=None 41 props.description=None 42 # 元の場所 43 props.creator=None 44 props.lastModifiedBy=None 45 props.revision=None 46 props.version=None 47 # コンテンツ 48 props.contentStatus=None 49 props.language=None 50 # Excelファイルの保存 51 wb.save(path) 52 return 53 54if __name__ == '__main__': 55 main()

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

teratail、googleで検索したが、解決方法が見つからなかった。

補足

ソースは以下のサイトを参考にさせていただきました。
https://telecom-engineer.blog/blog/2023/05/02/excel-properties/

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

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

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

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

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

hiroki-o

2024/05/09 15:07

試したところ、Windows 11、Python 3.12.3、openpyxl 3.1.2、Microsoft 365の環境で、正しく動作しました。 ソースは正しいと思います。
trouble_maker77

2024/05/10 08:36

プロパティが削除されるのは確認しております。 シート内の書式がクリアされてしまう問題を解決したいのです。
trouble_maker77

2024/05/10 08:45

自分の実行環境は以下になります。 Windows 10、Python 3.12.2、openpyxl 3.1.2、Microsoft office 2021
otn

2024/05/10 13:32

> プロパティが削除されるのは確認しております。 他人がその確認を再現できるレベルで記述しましょう。
hiroki-o

2024/05/11 05:47

trouble_maker77さん もちろん、書式がクリアされないことも確認しています。 ちなみに、Windows 10、Python 3.12.2、openpyxl 3.1.2、Microsoft 365の環境でも正しく動作しました。 提示されたソース以外に原因があると思われます。
guest

回答3

0

自己解決

Python3

1wb = openpyxl.load_workbook(path)

以下のオプションをつけることで、部分fontを扱えるようになりました。

Python3

1wb = openpyxl.load_workbook(filename=path, ritch_text=True)

公式万歳!
https://openpyxl.readthedocs.io/en/stable/api/openpyxl.reader.excel.html

投稿2024/05/21 07:46

trouble_maker77

総合スコア10

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

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

0

調べましたが、xlwingsからExcelマクロを使うやり方がありそうです。xlwingsではdocumentが少ないので、VBAで調べて、xlwingsで実装できないか調べるようにしています。
まずは動作確認したうえで、意図した動作になるかご確認いただければと思います。
xlwingsとは
[リンク内容]https://teratail.com/questions/351168

以下はVBAの参考リンクです。
[リンク内容]https://learn.microsoft.com/ja-jp/office/vba/api/excel.workbook.builtindocumentproperties

import xlwings as xw ###appを取得 app = xw.App() ###excelを非表示 app.visible = False ###スクリーン更新をFalseにする(Trueだと画面遷移があり遅いため) app.screen_updating = False ###指定したファイルを開く。複数あると思うのでfor文で回してください。 wb = xw.Book(file_path) ###プロパティを取得。apiはxlwingsでマクロ関係の処理にアクセスするのに必要なもの ###xlwingsのdocumentに載っていないため、VBAで調べてxlwingsで実現できるか調査 properties = wb.api.BuiltinDocumentProperties ###取得したpropertiesをfor文で除去 for x in properties: try: ###x.Nameで表示された内容が出てきます。必要に応じてNameの名前で場合分けしてください。 print(x.Name, x.Type, x.Value) ###空にできない項目以外は空にする x.Value = "" except: pass ###保存 wb.save() ###閉じる wb.close()

投稿2024/05/11 22:15

kei-hanako-sunu

総合スコア6

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

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

trouble_maker77

2024/05/13 00:21

vbaだと個人情報でポップアップが表示されてうまくいかなかったんですよね。。。 他の言語でもできないか検討してみようと思います。 ありがとうございました!
guest

0

openpyxlではcell全体のフォントにアクセスできますが、cell内の部分取消線や太字など、部分fontには対応していません。今回はproperties情報を変更して消えたとのことですが、単純に部分font情報を含んだファイルをopenpyxlでfileを開いて、保存するだけでも部分font情報が消えることを確認しました。
Excelはxmlファイルの集合体になっており、部分fontの情報はxl/sharedStrings.xmlに格納されています。実行前後でファイルで確認すると、openpyxlで開いて保存するという処理をするだけで、xl/sharedStrings.xmlが消えることを確認しました。
以下実行すると"xl/sharedStrings.xmlがありません"となるはずです。
よって、properties情報を書き換えたがために起きたのではなく、openpyxlの仕様ではないかと思います。
暫定の解決策は、zipfileで"xl/sharedStrings.xml"が無いか調べて、ない場合は実行、ある場合は実行せずに手動等で直すとかありそうですがいまいちなので、ほかの代替案がないかは調べてみます(properties情報は確かに書き換えられた方がよさそうですね。)

Python3

1import zipfile 2import os 3 4def search_xmlfile(filename): 5 ###xlsxをzipfileとして開く 6 with zipfile.ZipFile(filename) as xlsx_zip: 7 name_xml = [name for name in list(set(xlsx_zip.namelist()))] 8 9 return name_xml 10 11###fileを実行しているディレクトリを取得 12dir_now = os.path.dirname(os.path.abspath(__file__)) 13 14file1 = os.path.join(dir_now, 'Book2.xlsx') ###file1は実行前 15file2 = os.path.join(dir_now, 'Book2_temp.xlsx') ###file2は実行後 16 17xmlfile1 = search_xmlfile(file1) ###file1は実行前のfile名 18xmlfile2 = search_xmlfile(file2) ##file2は実行後のfile名 19 20not_file = [x for x in xmlfile1 if x not in xmlfile2] 21 22print(f'{",".join(not_file)}がありません')

投稿2024/05/10 23:57

kei-hanako-sunu

総合スコア6

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

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

trouble_maker77

2024/05/11 11:00 編集

確認・回答いただき、ありがとうございます。 openpyxlの仕様の旨、理解いたしました。 他のプロパティクリアも調べてはみましたが、openpyxlを使用したものばかりで、もし代替案あればご教示いただけると大変助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問