问题
I'm working with Django and need to read the sheets and cells of an uploaded xlsx file. It should be possible with xlrd but because the file has to stay in memory and may not be saved to a location I'm not sure how to continue.
The start point in this case is a web page with an upload input and a submit button. When submitted the file is caught with request.FILES['xlsx_file'].file
and send to a processing class that would have to extract all the important data for further processing.
The type of request.FILES['xlsx_file'].file
is BytesIO and xlrd is not able to read that type because of no getitem methode.
After converting the BytesIO to StringIO the error messages seems to stay the same '_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)
回答1:
I'm moving my comment into an answer of it's own. It related to the example code (which includes decoding) given in the updated question:
Ok, thanks for your pointers. I downloaded xlrd and tested it locally. It seems the best way to go here is to pass it a string ie. open_workbook(file_contents=xlsx_file.read().decode(encoding=file_enc, errors='replace'))
. I misunderstood the docs, but I'm positive that file_contents= will work with a string.
回答2:
Try xlrd.open_workbook(file_contents=request.FILES['xlsx_file'].read())
回答3:
I had a similar problem but in my case I needed to unit test a Djano app with download by the user of an xls file.
The basic code using StringIO worked for me.
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
来源:https://stackoverflow.com/questions/36472681/open-bytesio-xlsx-with-xlrd