Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open BytesIO (xlsx) with xlrd

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)
like image 483
Adrian Z. Avatar asked Apr 07 '16 09:04

Adrian Z.


2 Answers

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.

like image 58
Protagonist Avatar answered Nov 13 '22 17:11

Protagonist


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

like image 27
Sergey Gornostaev Avatar answered Nov 13 '22 17:11

Sergey Gornostaev