未解決のため、調べたこと、試したことが増え次第、随時更新予定です
#環境
windows 10
Microsoft Excel for Office365
Python 3.7.3
openpyxl 2.6.2
#事象
xlsをxlsxとして保存し、openpyxlで別ブックとして保存したとき、xmlエラーが発生する
####エラーメッセージ
置き換えられたパーツ: /xl/worksheets/sheet1.xml パーツに XML エラーがありました。
読み込みエラーが発生しました。場所は、行 5、列 0 です。
#事象発生までの流れ
####xls→xlsx
xlsファイルをExcelで開き、「名前を付けて保存」でxlsx(Excelブック)として保存
例)input.xlsを開き、「名前を付けて保存」でinput.xlsxで保存
####openpyxl
import openpyxl as px
#inputファイルのpathをコンソール上にドラッグ&ドロップで取得
origin=input()
#openpyxlでxlsxファイルを開く
wb=px.load_workbook(origin)
ws=wb.active
#保存先ファイルとして別名に変更
origin=origin.rstrip(".xlsx")
origin+="px.xlsx"
#inputファイルを別ブックとして保存
wb.save(origin)
例)input.xlsxをopenpyxlを通してinputpx.xlsxで保存
####Excelで開く
作成されたxlsxブックをExcelで開くと、
'inputpx.xlsx'の一部の内容に問題が見つかりました。
可能な限り内容を回復しますか?
とダイアログが出て、
「はい」をクリックすると、
'inputpx.xlsx'の修復
読み取れなかった内容を修復または削除することにより、ファイルを開くことができました。
置き換えられたパーツ: /xl/worksheets/sheet1.xml パーツに XML エラーがありました。
読み込みエラーが発生しました。場所は、行 5、列 0 です。
と出る。
開かれたxlsxファイルはすべて空白のセル(新規作成のような状態)になっていた
#調べたこと、気づいたこと
####xls,xlsxについて
-
xlsはBIFF(Binary Interchange File Format),xlsxはxml
-
xlsxは拡張子をzipに変えると、そのxlsxを構成するxmlを見ることができる
-
一般に、sheet1に対応するxmlは\xl\worksheets\sheet1.xml
-
zipに変えたものをxlsxに戻して開くと「ファイルが壊れています」となり、開けない
-
エクスプローラーの「名前の変更」で拡張子をxls→xlsxに変えても、ファイルの中身はxlsのため、開こうとしたときにエラーで開けない
####error.xmlについて
xmlを見たとき自分が気づいた点として、
正常に開けるファイル(openpyxlのinput側ファイル)の先頭にある
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
がxmlエラーを起こすファイルにない
#試したこと
- もともとのxlsファイルの書式を調べる
自分が確認できた範囲で、
セル結合、塗りつぶし、データの入力規則(プルダウン)、改ページプレビュー表示
自分の学習範囲で、openpyxlで編集できる書式としてセル結合、塗りつぶしが挙げられる。
塗りつぶしが悪さをするだろうか…と思ったのと、
過去の経験から、pythonでExcelファイルを扱うとき、セル結合はとても厄介だったため、セル結合あり/なしで検証した
-
xlsxブックを新規作成,openpyxlを通して別名保存
結果:正常に開ける -
xlsxブックを新規作成(セル結合あり),openpyxlを通して別名保存
結果:正常に開ける -
xlsブックを新規作成,xlsxで保存後,openpyxlを通して別名保存
結果:正常に開ける -
xlsブックを新規作成(セル結合あり),xlsxで保存後,openpyxlを通して別名保存
結果:正常に開ける
以上の結果から、xls→xlsxの変換、セル結合あり/なしは正常に開けるかどうかに影響しないことが言えそう
- "気づいたこと"より、正常に開けないファイルのxmlにないものを追加してみる
結果:
- zipに変えたものをxlsxに戻して開くと「ファイルが壊れています」となり、開けない
のため、xmlを編集したものをxlsxとして開くことはできなかった
#とった対処法
"試したこと"から、新規作成したxlsxファイルについては問題なく開けたため、
もともとのxlsファイルと同じものをxlsxで新規作成(手作業)して、それをinputファイルとすることで、
やりたかった作業をpythonで行うことができた。
#考察
- openpyxlのバグ?
- openpyxlはもともとxlsxファイル対応のため、xlsが絡むファイルについてうまく扱えないことがある?
- そもそものxlsファイルに異常が隠れている?
#今後
未解決のため、今後も調査、検証を行っていくつもりです。
解決法をご存知の方がいらっしゃいましたらご教示いただけると幸いです。