2016-04-07 95 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