2016-04-07 89 views
1

我正在使用Django并需要读取上载的xlsx文件的工作表和单元格。它应该可能与xlrd,但因为文件必须留在内存中,可能不会保存到一个位置,我不知道如何继续。使用xlrd打开BytesIO(xlsx)

这种情况下的起点是一个带有上传输入和提交按钮的网页。提交时,文件被捕获request.FILES['xlsx_file'].file并发送给处理类,该处理类将不得不提取所有重要数据以供进一步处理。

request.FILES['xlsx_file'].file的类型是BytesIO,并且由于没有getitem方法,xlrd无法读取该类型。

转换BytesIO到StringIO的错误消息后似乎保持不变'_io.StringIO' object has no attribute '__getitem__'

file_enc = chardet.detect(xlsx_file.read(8))['encoding'] 
    xlsx_file.seek(0) 

    sio = io.StringIO(xlsx_file.read().decode(encoding=file_enc, errors='replace')) 
    workbook = xlrd.open_workbook(file_contents=sio) 
+0

嗨,你可以给我们任何你用来解决这个问题的代码吗?这将有助于达成解决方案。 从您当前的描述中,我只能冒险猜测xlrd需要一个类似文件的对象,所以应该可以获取上传的xlsx文件,将其提供给一个“StringIO”对象并将其传递给xlrd。 – Protagonist

+0

对于这种特殊情况,没有太多的代码,但我会尝试给出更多的上下文。 –

+0

所以你认为一个StringIO就足够了? –

回答

1

我移动我的评论到它自己的答案。它涉及到在更新的问题中给出的示例代码(包括解码):

好的,谢谢你的指点。我下载了xlrd并在本地进行了测试。看起来最好的方法是将它传递给字符串ie。 open_workbook(file_contents=xlsx_file.read().decode(encoding=file_enc, errors='replace'))。我误解了文档,但我肯定file_contents =会使用字符串。

+1

在这种情况下,似乎不需要解码,并且只读是可行的,因为它是一种ascii类型。 –

1

尝试xlrd.open_workbook(file_contents=request.FILES['xlsx_file'].read())

0

我有一个类似的问题,但在我的情况下,我需要用xls文件的用户下载单元测试一个Djano应用程序。

使用StringIO的基本代码适用于我。

class myTest(TestCase): 
    def test_download(self): 
     response = self.client('...') 
     f = StringIO.StringIO(response.content) 
     book = xlrd.open_workbook(file_contents = f.getvalue()) 
     ... 
     #unit-tests here