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

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

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

Open XMLは、マイクロソフト社が開発したオープンなXMLベースのオフィススイート用のファイル形式です。従来のバイナリ形式のフォーマットに代わって、XMLを用いた規格を標準ファイル形式として採用しています。

Python 3.x

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

Q&A

解決済

1回答

1359閲覧

.xlsx ファイルが開けない .xml

mn.py

総合スコア41

Open XML

Open XMLは、マイクロソフト社が開発したオープンなXMLベースのオフィススイート用のファイル形式です。従来のバイナリ形式のフォーマットに代わって、XMLを用いた規格を標準ファイル形式として採用しています。

Python 3.x

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

0グッド

0クリップ

投稿2023/04/16 14:27

編集2023/04/17 00:03

実現したいこと

ダウンロードした.xlsxのファイルをpandasのデータフレームで開きたいです。

前提

大量の.xlsxファイルがあります。
これらは一度直接開いてから、上書き保存するとpandasで読み込めるのですが、
そのままpd.read_excelしても読み込めません。
どうやら中身が圧縮されたxmlファイルで構成されており、そのまま開けないようです。

発生している問題・エラーメッセージ

KeyError: "There is no item named '[Content_Types].xml' in the archive"

該当のソースコード

python

1import pandas as pd 2fname = 'file.xlsx' 3df = pd.read_excel(fname) 4print(df)

試したこと

中身はこのような階層でした。
encordingを変えたりもしましたが、読み込めませんでした。
どなたかヒントだけでも良いので助けていただきたいです。

python

1from zipfile import ZipFile, ZIP_DEFLATED, BadZipfile 2import xml.etree.ElementTree as ET 3 4archive = ZipFile(fname) 5for _i in archive.infolist(): 6 print('zip info: {}'.format(_i.filename)) 7 8# 出力 9zip info: xl/worksheets/sheet1.xml 10zip info: _rels/.rels 11zip info: xl/styles.xml 12zip info: [content_types].xml 13zip info: xl/_rels/workbook.xml.rels 14zip info: xl/sharedstrings.xml 15zip info: xl/workbook.xml

補足情報①

pandasで問題なく読み込めるファイル(一度直接開いて上書き保存したもの)の階層を追記
一度上書き保存したら※のファイルが増えますが、なぜ増えるのかがわからないです。

zip info: [Content_Types].xml zip info: _rels/.rels zip info: xl/_rels/workbook.xml.rels zip info: xl/workbook.xml zip info: xl/styles.xml zip info: xl/theme/theme1.xml ※ zip info: xl/worksheets/sheet1.xml zip info: xl/sharedStrings.xml zip info: docProps/core.xml ※ zip info: docProps/app.xml ※

補足情報②

https://qiita.com/ty21ky/items/44d0f6079440247b8698
拡張子を.xlsxを.odsに変更して、掲載の試してみましたが
KeyError: '.ods'
となりました。

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

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

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

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

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

mn.py

2023/04/16 23:27

ありがとうございます。 書き漏れており失礼いたしました。 ご紹介いただいたteratailのページは確認しており、以下のページを参考にしてみました。 https://qiita.com/ty21ky/items/44d0f6079440247b8698 拡張子を.xlsxを.odsに変更して、掲載の試してみましたが KeyError: '.ods' となりました。 この次(もしくは私の試し方が間違えているのか等)何を試していけば良いのか、もしアイディアがあればお伺いできたらと思います。 元のファイルはデータベースから自動でダウンロードしたものです。
jbpb0

2023/04/16 23:54 編集

> 以下のページを参考にしてみました。 https://qiita.com/ty21ky/items/44d0f6079440247b8698 拡張子を.xlsxを.odsに変更して、掲載の試してみましたが KeyError: '.ods' となりました。 は、質問を編集して追記してください > 元のファイルはデータベースから自動でダウンロードしたもの が、エクセルでも、odsでもない、さらに別のものとか そのデータベースの仕様を確認した方がいいのではないですかね
mn.py

2023/04/17 00:04

ありがとうございました。 データベースの仕様書を再度確認してみます。
jbpb0

2023/04/17 00:08

> 一度上書き保存したら※のファイルが増えます > zip info: xl/theme/theme1.xml ※ > zip info: docProps/core.xml ※ zip info: docProps/app.xml ※ https://okumuralab.org/~okumura/stat/xlsx.html によると、それらはエクセルで保存したら含まれるもののようです 「試したこと」の「# 出力」と、「補足情報」を比べたら、「※」が増えるだけでなく、順番も変わってますね 元の(エラーになる)ファイルにも > zip info: [content_types].xml があるのに > KeyError: "There is no item named '[Content_Types].xml' in the archive" となるのは、もしかすると、「[Content_Types].xml」が先頭じゃないとダメなのかも (pandasのコード読んでないので、当てずっぽうですが)
mn.py

2023/04/17 00:19

ありがとうございます。 [Content_Types].xml]は、エラーは大文字なのですが、展開されるファイルは[Content_Types].xmlで小文字なので、それでないと言われているのだと思います。 教えていただいたサイトには、そのようなファイルはOpen Office XML」形式のファイルではなく、Libre OfficeやApache Open Officeで作成した「OpenDocument Spreadsheet」形式のファイルなのではとあったのですが、、、そこから先に進めておりません
quickquip

2023/04/17 00:29 編集

そこまで予想できているなら Excelで普通にxlsxを保存する→zipで展開→ファイル名を[content_types].xmlに変更→zipで圧縮して拡張子をxlsxに変更→pandasでエラーになるか検証 をして自分で再現テストができると思いました。(もう一つの仮説はファイルの順番) もし再現するならば、しかるべき所にissueとして上げる/ファイル形式の仕様書を探す/pandasのコードを読む と進むのではないかと。
mn.py

2023/04/17 00:31

ありがとうございます。 ご提示いただいた検証を一度やってみます。
jbpb0

2023/04/17 01:05 編集

> [Content_Types].xml]は、エラーは大文字なのですが、展開されるファイルは[Content_Types].xmlで小文字 なるほど それは見落としてました https://github.com/python/cpython/blob/3.7/Lib/zipfile.py の1365行目の「x = ZipInfo(filename)」で「x」に入ったデータで、1384行目の「self.NameToInfo[x.filename] = x」が実行され、「self.NameToInfo」に情報が入ってるはず 同じファイルの1428行目の「info = self.NameToInfo.get(name)」で、上記1384行目で入ったはずの情報がうまく取り出せないようで、「info」に「None」が入り、1431行目で、この質問のエラー「There is no item named...」が出てます 質問者さんが言うように、大文字・小文字の相違が原因かも
mn.py

2023/04/17 01:36

ありがとうございます。文字ミスってましたね、済みません。 xlsxファイルをpythonで展開→[content_types].xml xlsxファイルをPCでopen後に上書き保存→xlsxファイルをpythonで展開→[Content_Types].xmlになり、ファイルも3つ増える。 大文字、小文字の相違もなのですが、この3つ増えるファイルを展開しないといけないのではないかと推測しているのですが、詰まっています。
jbpb0

2023/04/17 02:44

> 3つ増えるファイルを展開しないといけないのではないかと推測 quickquipさんがコメントに書いた ・pythonで正常に読めるファイルを小文字に変えてみる のと、その逆に ・pythonでエラーになるファイルを大文字に変えてみる(三つのファイルは足りないまま) のとで、それぞれどうなるのか? を試してみたらいいと思います
can110

2023/04/17 02:50

> 元のファイルはデータベースから自動でダウンロードしたもの > データベースの仕様書を再度確認してみます。 元がおかしなモノなので、この確認および 正しい.xlsxをダウンロードできるような方法を探すのが先だと思います。
mn.py

2023/04/17 03:02

エラーが出るのは展開前のxlsxファイルをpandasで読み込んだ際に発生するので、変えてみる事ができないのですが、一度展開してから変更して圧縮してみます。 あとは中身を再度確認していってみます。
jbpb0

2023/04/17 03:35

> エラーが出るのは展開前のxlsxファイルをpandasで読み込んだ際に発生するので、変えてみる事ができない が、私が書いた「pythonでエラーになるファイルを大文字に変えてみる(三つのファイルは足りないまま)」のことを指してるのなら、その手順にもquickquipさんがコメントに書いたように、ファイル名を大文字に変える前後に「zipで展開」と「zipで圧縮」が含まれます quickquipさんがコメントに書いたことの「逆」というのは、「大文字←→小文字 の向き」のことだけで、それ以外の手順は同じです (ただし、エクセルのファイルをzipで展開して、何か操作して、zipで圧縮する、ということをしたことが無いので、その状態でエクセルのファイルとして正しい状態に戻るのかは、よく知りません)
jbpb0

2023/04/17 04:02 編集

> 正しい.xlsxをダウンロードできるような方法を探すのが先 もちろん、それが可能なら、それが一番いいですよね ただし、pythonではエラーが出るけど、エクセルでは読めるようなので、現状でもエクセル的には「正しい」のかもしれません (正しくないけど読めてしまう、という可能性もありますが)
mn.py

2023/04/17 03:57

>ファイル名を大文字に変える前後に「zipで展開」と「zipで圧縮」が含まれます >その状態でエクセルのファイルとして正しい状態に戻るのかは、よく知りません ありがとうございます。私も正しく戻るのかやってみないと何ともですのでやってみます。 >正しい.xlsxをダウンロードできるような方法を探すのが先だと思います。 これはデータベンダーの仕様なのでどうしようもなさそうです、、。 また、PCで直接開いてから保存したら通常通りpandasで開けるので、ファイルが壊れている、というわけでもなさそうに、、、でももう一度ダウンロードも試してみます。 ありがとうございます。
can110

2023/04/17 04:29

> これはデータベンダーの仕様なのでどうしようもなさそうです、、。 どのような「ベンダー仕様」なのか不明ですが、以下の仕様と外れているものであれば 「.xlsxファイルではない」ので、わたしならベンダーに問い合わせて対応(修正)をお願いします。 https://www.ecma-international.org/publications-and-standards/standards/ecma-376/
mn.py

2023/04/17 04:41

ありがとうございました。 どうやらファイル名が全て小文字で作成されているようで、、、なのでどのライブラリでもエラーになっていた様です。一応ベンダーには伝えておこうと思います。 大量に取得して、コードで前処理しようと思うとちょっと困る人いると思うので。 普通に手元のPCで開いて作業する分には大丈夫そうなんですが。 ありがとうございました
guest

回答1

0

自己解決

みなさま、沢山ヒントをいただいて本当にありがとうございました。
どうやらファイル名が全て小文字だったために起きていたエラーのようです。
一旦解凍し、rename してから再度圧縮したら読み込めるようになりました!
ありがとうございました!!

python

1import os 2import zipfile 3 4# XLSXファイルを展開する 5with zipfile.ZipFile(daily, 'r') as zip_ref: 6 zip_ref.extractall('example_extracted') 7 8# [content_types].xmlを[Content_Types].xmlにリネームする 9os.rename('example_extracted/[content_types].xml', 'example_extracted/[Content_Types].xml') 10os.rename('example_extracted/xl/sharedstrings.xml', 'example_extracted/xl/sharedStrings.xml') 11 12# 展開先フォルダをXLSXファイルに圧縮する 13with zipfile.ZipFile('new_example.xlsx', 'w') as zip_ref: 14 for foldername, subfolders, filenames in os.walk('example_extracted'): 15 for filename in filenames: 16 filepath = os.path.join(foldername, filename) 17 zip_ref.write(filepath, arcname=filepath[len('example_extracted/'):] )

投稿2023/04/17 04:31

mn.py

総合スコア41

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

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

jbpb0

2023/04/17 05:44

> zip info: xl/sharedstrings.xml も > zip info: xl/sharedStrings.xml に変えないとダメなのですね > 一度上書き保存したら※のファイルが増えます > zip info: xl/theme/theme1.xml ※ > zip info: docProps/core.xml ※ zip info: docProps/app.xml ※ の三つのファイルは、足りないままでも大丈夫でした?
mn.py

2023/04/17 05:48

> zip info: xl/sharedstrings.xml も > zip info: xl/sharedStrings.xml に変えないとダメなのですね おっしゃる通りです。 >三つのファイルは、足りないままでも大丈夫でした? こちらは調べたら、作成者などの文書プロパティがあるファイルの場合に作成されるようです。 なので、一旦PCで開いて自分で上書きすると自身の情報が書き込まれるようです。 最後までお付き合いいただいてほんとうにありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問