简体   繁体   中英

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)

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM