Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python XlsxWriter:内存中为什么会给出损坏的字节序列?_Python_Xlsxwriter_Bytesio - Fatal编程技术网

Python XlsxWriter:内存中为什么会给出损坏的字节序列?

Python XlsxWriter:内存中为什么会给出损坏的字节序列?,python,xlsxwriter,bytesio,Python,Xlsxwriter,Bytesio,我正在生成一个excel文件,并将其返回到flask应用程序中下载。如果我使用“内存中”:True,则文件已损坏,excel无法打开它。如果直接写入磁盘,同样的代码也可以工作。对于内存中的代码,我遵循 我怀疑字节是否不同,所以我编写了一个小脚本进行测试,它们确实略有不同(5730个字节中有44个字节) 这是我的脚本生成的相同工作簿,一个在内存中,一个在磁盘上。然后比较字节,发现它们是不同的。为什么? from io import BytesIO from xlsxwriter import W

我正在生成一个excel文件,并将其返回到flask应用程序中下载。如果我使用
“内存中”:True
,则文件已损坏,excel无法打开它。如果直接写入磁盘,同样的代码也可以工作。对于内存中的代码,我遵循

我怀疑字节是否不同,所以我编写了一个小脚本进行测试,它们确实略有不同(5730个字节中有44个字节)

这是我的脚本生成的相同工作簿,一个在内存中,一个在磁盘上。然后比较字节,发现它们是不同的。为什么?

from io import BytesIO

from xlsxwriter import Workbook


def fill_workbook(workbook):
    """Populate the workbook with some test data"""
    first_sheet = workbook.add_worksheet("First")
    first_sheet.write(0, 0, "test")

    next_sheet = workbook.add_worksheet("Next")
    next_sheet.write(0, 0, "sample")
    next_sheet.write(0, 1, "value")
    workbook.close()


def get_bytes():
    """Get the bytes for the in-memory and on-disk workbooks"""
    output = BytesIO()
    in_mem = Workbook(output, {'in_memory': True})

    filename = "direct.xlsx"
    on_disk = Workbook(filename)

    fill_workbook(in_mem)
    fill_workbook(on_disk)

    output.seek(0)
    mem_bytes = output.read()

    with open(filename, "rb") as f:
        disk_bytes = f.read()

    return mem_bytes, disk_bytes


def compare_bytes():
    """Compare the bytes of the two workbooks"""
    mem_bytes, disk_bytes = get_bytes()

    print(mem_bytes == disk_bytes)

    same = 0
    diff = 0
    for mb, db in zip(mem_bytes, disk_bytes):
        if mb == db:
            same += 1
        else:
            diff +=1

    print(f"{same} bytes same")
    print(f"{diff} bytes different")


if __name__ == '__main__':
    compare_bytes()


我用
XlsxWriter==1.2.8
python3.7.3
上运行脚本,当
内存中的
设置为
False
时,它对我有效。让我们看看in_memory参数在XlsxWriter源代码中的实际作用:


由于其中一个Excel元数据文件中的时间戳,任何两个相隔超过一秒(或可能是一毫秒)的XlsxWriter文件都将不同。为了确保文件是二进制的,您应该通过
set\u properties()
workbook方法设置“创建”日期:
    for file_id, file_data in enumerate(xml_files):
        os_filename, xml_filename, is_binary = file_data

        if self.in_memory:

            # Set sub-file timestamp to Excel's timestamp of 1/1/1980.
            zipinfo = ZipInfo(xml_filename, (1980, 1, 1, 0, 0, 0))

            # Copy compression type from parent ZipFile.
            zipinfo.compress_type = xlsx_file.compression

            if is_binary:
                xlsx_file.writestr(zipinfo, os_filename.getvalue())
            else:
                xlsx_file.writestr(zipinfo,
                                   os_filename.getvalue().encode('utf-8'))`

        else:
            # The sub-files are tempfiles on disk, i.e, not in memory.

            # Set sub-file timestamp to 31/1/1980 due to portability
            # issues setting it to Excel's timestamp of 1/1/1980.
            timestamp = time.mktime((1980, 1, 31, 0, 0, 0, 0, 0, -1))
            os.utime(os_filename, (timestamp, timestamp))

            try:
                xlsx_file.write(os_filename, xml_filename)
                os.remove(os_filename)