kei0425tan’s blog

技術的なことを主に

pyExceleratorで作成したファイルをoffice2010で開くと「ファイルエラー:データが失われた可能性があります。」

pythonexcelのxlsファイルの読み書きができるモジュールでpyExceleratorというものがあります。

 

現状ではもうメンテされておらず、python-excelライブラリ(xlrd, xlwt,xlutils)に移行するのが推奨かとは思いますが、何らかの事情で使わなければいけない&office2010でエラーが発生して困っている人向け。

 

原因

ハイパーリンクのヒントの扱いが間違えている。

 

xlsファイルはBIFFフォーマットというもので記述されています。

BIFFフォーマット内では文字列はUNICODE(UTF-16le)で扱い、0x0000の2バイトでターミネイトされます。

ところが、ライブラリではハイパーリンクのヒントのターミネイトが0x00と1バイトでターミネイトされているため、エクセルがオープン時に1文字削除して補正します。

office2010になって、チェックが強化されたため、上記エラーが出力されることがあります。

 

対処

BIFFRecords.py:1750

class QuicktipRecord(BiffRecord):
    """
    This record contains the cell range and text for a tool tip. It occurs in
    conjunction with the HLINK record for hyperlinks (6.53) in the Hyperlink
    Table (5.13). This record is only available in Excel 9.0 (Excel 2000) and
    later.

    Record QUICKTIP, BIFF8:

    Offset Size Contents
    0      2   0800H (repeated record identifier)
    2      8   Cell range address of all cells containing the tool tip (3.13.1)
    10    var. Character array of the tool tip, no Unicode string header, always 16-bit characters, zero-
            terminated

    """
    _REC_ID = 0x0800

    def __init__(self, frow, lrow, fcol, lcol, hint):
        BiffRecord.__init__(self)
        hint = hint.encode('UTF-16le')
        self._rec_data = pack('<5H%dsx'%len(hint), self._REC_ID, frow, lrow, fcol, lcol, hint)

こんなふうに変更すればOK

        self._rec_data = pack('<5H%dsxx'%len(hint), self._REC_ID, frow, lrow, fcol, lcol, hint)