2014年11月18日火曜日

Excel互換ソフトウェアで、Microsoft Excelが作成した「.xlsx」ファイルを読むと、セルの先頭にある全角スペースが消える?

こんにちは。近藤です。

社内や自宅でMicrosoft Officeを利用しているかたは多いと思います。
文書作成アプリケーションのMicrosoft Word、表計算アプリケーションのMicrosoft Excel、プレゼンテーションアプリケーションのMicrosoft PowerPointなどは、なじみがあるのではないでしょうか。「以前はMicrosoft Accessを使った小規模システムを使っていたけれど…」というかたもいらっしゃると思います。
個人的には、よくデジタルノートアプリケーションのMicrosoft OneNoteを使っていたのですが、昨今のセキュリティ強化に関連して会議の場やお客様への訪問時などにノートPCを持ち込まなくなってからは、使用する機会もめっきり少なくなりました…

今回は、Microsoft Excelの「.xlsx」ファイルで起きた、ある事象のお話です。

.xlsxファイルとは

Excelブックファイルは、Microsoft Excel 2003までは独自ファイル形式の「.xls」でしたが、Microsoft Office 2007からはXMLをベースにしたOffice Open XML形式が新たに採用され、拡張子も「.xlsx」(マクロの無いブック)や「.xlsm」(マクロ有効ブック)となりました。

データの先頭にある全角スペースが無くなる?

この「.xlsx」ファイルについて、先日こんな事象がありました。
  • Microsoft Excelで、全角スペースから始まる文字列をセルに入力して「.xlsx」形式で保存し、そのファイルをMicrosoft Excelではない別のソフトウェアで読み込んだところ、全角スペースが欠落してしまった
今回は、この状況を見てみたいと思います。

現象の再現

状況確認のために、「半角スペースから始まる文字列」と「全角スペースから始まる文字列」が含まれたファイルを使用します。
まず、Microsoft Excelで「.xlsx」ファイルを作成し、そのファイルを開いてみました。
半角スペース= 全角スペース= 
で表しています。
  • Microsoft Excelで作成した「.xlsx」ファイルを、再度Microsoft Excelで読み込んだときの内容
  •    半角スペース3個から始まる文字列
       全角スペース3個から始まる文字列
  • 別のソフトウェアで、Microsoft Excelで作成した「.xlsx」ファイルを読み込んだときの内容
  •    半角スペース3個から始まる文字列
    全角スペース3個から始まる文字列

確かに、別のソフトウェアでは、文字列の先頭にあった全角スペースが消えてしまいました。
次に、別のソフトウェアで同内容の「.xlsx」ファイルを作成し、そのファイルを開いてみました。
  • 別のソフトウェアで作成した「.xlsx」ファイルを、再度別のソフトウェアで読み込んだときの内容
  •    半角スペース3個から始まる文字列
       全角スペース3個から始まる文字列
  • Microsoft Excelで、別のソフトウェアで作成した「.xlsx」ファイルを読み込んだときの内容
  •    半角スペース3個から始まる文字列
       全角スペース3個から始まる文字列

この別のソフトウェア、xlsファイルも読み込めるので、試しにMicrosoft Excelで同条件の「.xls」ファイルを作成し、それを別のソフトウェアに読み込ませてみました。
  • Microsoft Excelで作成した「.xls」ファイルを、再度Microsoft Excelで読み込んだときの内容
  •    半角スペース3個から始まる文字列
       全角スペース3個から始まる文字列
  • 別のソフトウェアで、Microsoft Excelで作成した「.xls」ファイルを読み込んだときの内容
  •    半角スペース3個から始まる文字列
       全角スペース3個から始まる文字列

この場合も、双方共に全角スペースは欠落しませんでした。

ということは、別のソフトウェアがデータ先頭にある全角スペースを処理できないわけでは無さそうです。

これらより、Microsoft Excelが生成する「.xlsx」ファイルと、別のソフトウェアが生成する「.xlsx」ファイルの「全角スペースが先頭にあるセル」のデータ部に何か違いがありそうです。

Office Open XML形式の仕様

Office Open XML形式の仕様は、ISO/IEC 29500で標準化されており、ISOで有償公開されています。「お金を払わないと仕様を見ることができないのか…」と思ったのですが、このISO/IEC 29500、ECMA-376で先行して標準化されているのです。で、ECMAのサイトを見てみると、『ECMA-376 4th edition is technically aligned with ISO/IEC 29500.』という記述があります。そして、この「ECMA-376 4th edition」の仕様書は、無償で公開されています。

仕様からファイルの中身を見てみる
では、この「ECMA-376 4th edition」( http://www.ecma-international.org/publications/standards/Ecma-376.htm )を手元に用意して、「.xlsx」ファイルの中身を見てみましょう。

「.xlsx」ファイルは、ブックを構成する各種データがzipで圧縮されているものなので、拡張子を「.zip」に変更して解凍してみます。すると、

Z:\BOOK1
│  [Content_Types].xml
├─docProps
│      app.xml
│      core.xml
├─xl
│  │  sharedStrings.xml
│  │  styles.xml
│  │  workbook.xml
│  ├─theme
│  │      theme1.xml
│  ├─worksheets
│  │      sheet1.xml
│  │      sheet2.xml
│  │      sheet3.xml
│  └─_rels
│          workbook.xml.rels
└─_rels
        .rels

このようなファイル群が解凍されました。これらが、「.xlsx」ファイルを構成している中身です。それぞれ見ていくとおもしろいのですが、とりあえず気にしないことにして…
このファイル群の中で、データが格納されているのは「sharedStrings.xml」なので、その中身を見てみます。

  それぞれのセルにあたる箇所のXMLを抜粋すると、
  •   半角スペース3個から始まる文字列」が格納されたセル
    <si><t xml:space="preserve">   半角スペース3個から始まる文字列</t>~(中略)~</si>
  •    全角スペース3個から始まる文字列」が格納されたセル
    <si><t>   全角スペース3個から始まる文字列</t>~(中略)~</si>
となっています。

念のため、「.xlsx」ファイルのスペースの処理がOffice Open XMLでどのように規定されているか見ておきます。「ECMA-376 4th edition」の「18. SpreadsheetML Reference Material」に、次のように記載されています。
『Specifies how white space should be handled for the contents of this element using the W3C space preservation rules.』
「空白は、W3Cのルールに従うよ」と。
ということは、ここでの「white space」は、XML1.0の定義にある『"white space" (spaces, tabs, and blank lines)』となり、全角スペースは対象外。なので、全角スペースは文字として扱われ、「white space」を保持するためのxml:space="preserve"の記述は不要、というわけですね。

では、別のソフトウェアが生成した「.xlsx」ファイルの「sharedStrings.xml」を見てみます。
それぞれのセルにあたるところのXMLを抜粋すると、
  •   半角スペース3個から始まる文字列」が格納されたセル
    <si><t xml:space="preserve">   半角スペース3個から始まる文字列</t>~(中略)~</si>

  •    全角スペース3個から始まる文字列」が格納されたセル
    <si><t xml:space="preserve">   全角スペース3個から始まる文字列</t>~(中略)~</si>
となっています。Microsoft Excelが生成した「.xlsx」ファイルとは異なり、別のソフトウェアが生成した「.xlsx」ファイルでは、先頭に全角スペースを出力するときも、「xml:space="preserve"」が出力されました。
これらの動作から、

  • Microsoft Excelの動作
    →全角スペースは文字、半角スペースは「white space」として扱っている
  • 「別のソフトウェア」の動作
    →全角スペース、半角スペース共に「white space」として扱っている

という判定になっていることがわかります。

この動作…

さて、ここまでで何か気付いたかたもいらっしゃるのではないでしょうか。

<si><t>   全角スペース3個から始まる文字列</t>~(中略)~</si>

で、先頭にある全角スペースが無くなる、という動作。
そんな言語やXMLパーサー、ありますよね?
恐らく、別のソフトウェアは、全角スペースも「white space」として扱う言語またはXMLパーサーで作成されていて、処理をそれらに任せてしまっていることが原因で、「.xlsx」ファイルを読み込むときに、データ先頭の全角スペースが欠落しているのではないでしょうか?
実際の原因がどちらなのかはわかりませんが…

互換製品ならそのあたりも対処して欲しいところなのですが、2バイト文字を使用しない地域で作成された製品だと、こういった動作が起こることに気が付かないのでしょうね…

おまけ

Microsoft Excelに、「space="preserve"」を削除した

<si><t> 半角スペース</t>~(中略)~</si>

が含まれた「.xlsx」ファイルを渡してみました。
結果、


「読み取れない内容が含まれる」と怒られました…
Microsoft Excelは、ファイルのフォーマットを厳密にチェックしているようです。
ここで「はい」を押すと、半角スペースが無くなった状態で回復されます。

同様に、この「.xlsx」ファイルを別のソフトウェアに渡してみたところ、エラーは出ずに半角スペースが削除されて表示されました。XMLファイル的には問題のあるファイルではないですからね…

0 件のコメント:

コメントを投稿