如何在 Python 中从流(不是磁盘支持的文件)中读取 Excel 文件?

Posted

技术标签:

【中文标题】如何在 Python 中从流(不是磁盘支持的文件)中读取 Excel 文件?【英文标题】:How to read Excel files from a stream (not a disk-backed file) in Python? 【发布时间】:2012-08-10 22:07:18 【问题描述】:

XLRD 已安装并测试:

>>> import xlrd
>>> workbook = xlrd.open_workbook('Sample.xls')

当我通过下面的 html 表单读取文件时,我可以访问所有值。

  xls_file = request.params['xls_file']
  print xls_file.filename, xls_file.type

我正在使用 Pylons 模块,请求来自:from pylons import request, tmpl_context as c

我的问题:

    xls_file 是通过 requst.params 读取的对象吗? 如何阅读 xls_file 并使其与 xlrd 一起使用?

更新:

xls_file 已上传到 Web 服务器,但 xlrd 库需要文件名而不是打开的文件对象,如何使上传的文件与 xlrd 一起使用? (感谢 Martijn Pieters,我无法清楚地提出这个问题。)

【问题讨论】:

我们是否应该猜一下“request”是什么,“request”来自哪里以及您使用的是哪个 Web 框架? 来自:from pylons import request, tmpl_context as c 看来您的问题是您正在 Web 服务器上接收文件上传,但 xlrd 库需要文件名而不是打开的文件对象。我对么?如果是这样,您可能希望将其添加到您的问题中。 :-) 【参考方案1】:

你可以试试...

import xlrd

def newopen(fileobject, modes):
    return fileobject

oldopen = __builtins__.open
__builtins__.open = newopen
InputWorkBook = xlrd.open_workbook(fileobject)
__builtins__.open = oldopen

如果文件对象还不是文件句柄,您可能必须将文件对象包装在 StringIO 中。

【讨论】:

__builtins__ 中重新定义open这样 一个坏主意。你至少可以将替换函数插入xlrd 模块only.. 为什么?这似乎是一个简单的解决方案,前提是您已经对其进行了测试,它对给定的应用程序没有不利影响。【参考方案2】:

xlrd 确实支持直接提供数据而无需文件路径,只需使用 file_contents 参数:

xlrd.open_workbook(file_contents=fileobj.read())

来自documentation:

file_contents – 字符串或mmap.mmap 对象或其他行为相似的对象。如果提供了file_contents,则不会使用filename,除非(可能)在消息中。

【讨论】:

同意这应该是答案【参考方案3】:

我遇到的问题与问题并不完全相同,但我认为可能相似,我可以提供一些提示。

我正在使用 django rest 框架的请求而不是 pylons 请求。

如果我编写如下简单代码:

@api_view(['POST'])
@renderer_classes([JSONRenderer])
def upload_files(request):
    file_obj = request.FILES['file']
    from xlrd import open_workbook
    wb = open_workbook(file_contents=file_obj.read())
    result = "code": "0", "message": "success", "data": 
    return Response(status=200, data=result)

这里我们可以使用之前cmets中提到的open_workbook(file_contents=file_obj.read())来阅读。

但是如果你按照以下方式编写代码:

from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser
class FileUploadView(APIView):
    parser_classes = (MultiPartParser,)

    def put(self, request, filename, format=None):
        file_obj = request.FILES.get('file')
        from xlrd import open_workbook
        wb = open_workbook(file_contents=file_obj.read())
        # do some stuff with uploaded file
        return Response(status=204)

你必须注意使用MultiPartParser而不是FileUploadParser,使用FileUploadParser会引发一些BOF错误。

所以我想知道它也会受到您编写 API 的方式的影响。

【讨论】:

【参考方案4】:

对我来说,这段代码有效。 Python 3

xlrd.open_workbook(file_contents=fileobj.content)

【讨论】:

以上是关于如何在 Python 中从流(不是磁盘支持的文件)中读取 Excel 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何测试是不是支持稀疏文件

如何在 Python 中从 SXS 加载 C DLL?

如何从流中读取 CSV 文件并在写入时处理每一行?

从流而不是文件加载配置文件

在python中从.txt写入.md [重复]

我可以在 python3 中从 excel 文件(不是 CSV)创建字典吗?