今天遇到一个问题,从某平台下载Excel文件,后缀xlsx,需要取出文件中的一些数据,

看似容易的操作,却历经了一下午的波折:

首先我使用的是最常见的 xlrd

import requests
import xlrd

url = 'https://example.com/file.xls'  # 替换为你的xls文件的URL

# 发起请求获取xls文件的二进制数据
response = requests.get(url)
content = response.content

# 使用xlrd库加载二进制数据
workbook = xlrd.open_workbook(file_contents=content)

# 获取第一个sheet
sheet = workbook.sheet_by_index(0)

# 遍历行和列获取单元格内容
for row in range(sheet.nrows):
    for col in range(sheet.ncols):
        cell_value = sheet.cell_value(row, col)
        print(cell_value)

以上代码运行后,凡是公式计算得到的数值全为0.0

此方法失败

于是尝试了第二种方法:使用openpyxl库

但缺点是它无法直接解析二进制的http响应数据,需要先保存为xlsx文件

import openpyxl

# 发送请求并获取响应
response = requests.get(url)

# 将响应内容写入本地文件
with open('example.xls', 'wb') as f:
    f.write(response.content)

# 打开Excel文件
workbook = openpyxl.load_workbook('example.xlsx')

# 获取第一个工作表
worksheet = workbook.active

# 读取单元格中的计算结果
cell_value = worksheet['A1'].value  # 假设计算结果位于第一行第一列的单元格

print(cell_value)

结果输出结果为---------None

显然,失败了,又过了一会儿,了解到openpyxl 的 data_only选项可以消除公式,只留下结果,听起来好像是我想要的,于是:

from openpyxl import load_workbook

def read_excel_with_formulas(filename):
    wb = load_workbook(filename, data_only=True)
    sheet = wb.active

    # 遍历单元格并打印公式计算结果
    for row in sheet.iter_rows(values_only=True):
        for cell in row:
            print(cell)

    wb.close()

# 调用函数来读取带有公式的 Excel 文件
read_excel_with_formulas("your_excel_file.xlsx")

此方法,也管用,也不管用

怎么说呢,对别人可能管用,但是此刻对我仍然无效

原因如下:

如果有一个人为处理过的文件(可以是被打开过,修改过等等),使用上面方法确实管用,

如果是刚下载的Excel,未曾开封修改,此方法无效

是不是很悲催。

貌似此时已经没有路可走了.......................

等等.

我是否可以模拟人为打开此文件,再关闭

于是:

import openpyxl
from win32com.client import Dispatch


def just_open(filename):
    xlApp = Dispatch("Excel.Application")
    xlApp.Visible = False
    xlBook = xlApp.Workbooks.Open(filename)
    xlBook.Save()
    xlBook.Close()

# 首先我们假设文件已经保存到本地
file = ('example.xlsx')
# 打开文件读取数据之前,先借助win32com打开一次,然后关闭
just_open(file)
# 然后再使用openpyxl配合data_only=True选项进行读取
workbook = openpyxl.load_workbook(file,data_only=True)
worksheet = workbook.active
cell = worksheet['A5'].value
print(cell)

不出意外,成功了。

那么,部署上线吧。

结束了么?

并没有

由于我是在Linux服务器上部署的,刚才没想到,现在尴尬了

为什么:

由于 win32com 是特定于 Windows 的库,因此在 Linux 系统上无法直接安装

凉凉了

此方法失败了

--------------------

好在天无绝人之路

Python还有一个库xlwings

于是:

import xlwings as xw

filename = 'example.xlsx'
with open(filename, 'wb') as file:
    file.write(response.content)
app = xw.App(visible=False)
workbook = app.books.open(filename)
sheet = workbook.sheets[0]
cell = sheet.range("A5").value
print(cell)

总算是可以了