今天遇到一个问题,从某平台下载Excel文件,后缀xlsx,需要取出文件中的一些数据,
看似容易的操作,却历经了一下午的波折:
首先我使用的是最常见的 xlrd
import requestsimport xlrdurl = 'https://example.com/file.xls'# 替换为你的xls文件的URL# 发起请求获取xls文件的二进制数据response = requests.get(url)content = response.content# 使用xlrd库加载二进制数据workbook = xlrd.open_workbook(file_contents=content)# 获取第一个sheetsheet = 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_workbookdef 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 openpyxlfrom win32com.client import Dispatchdef just_open(filename):xlApp = Dispatch("Excel.Application")xlApp.Visible = FalsexlBook = 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.activecell = worksheet['A5'].valueprint(cell)
不出意外,成功了。
那么,部署上线吧。
结束了么?
并没有
由于我是在Linux服务器上部署的,刚才没想到,现在尴尬了
为什么:
由于 win32com 是特定于 Windows 的库,因此在 Linux 系统上无法直接安装
凉凉了
此方法失败了
——————–
好在天无绝人之路
Python还有一个库xlwings
于是:
import xlwings as xwfilename = '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").valueprint(cell)
总算是可以了