如何从 python 中的 xlsx(而不是公式)读取数据?
How to read data from xlsx (instead of formulas) in python?
我将从 posting 用于为该线程创建测试用例 (foo.xlsx) 的代码示例开始。
这个简单的代码创建了一个包含数字条目和公式的 xlsx 文件:
[boris@E7490-DELL temp]$ cat xlsx1.py
#!/bin/env python
import pandas as pd
d = {'col1': [7, 2, 5, 9, 1], 'col2': [3, 6, 6, 7, 9]}
df = pd.DataFrame(data=d)
writer = pd.ExcelWriter("foo.xlsx", engine="xlsxwriter")
df["prod"] = None
df["prod"] = (
'=INDIRECT("R[0]C[%s]", 0)*INDIRECT("R[0]C[%s]", 0)'
% (
df.columns.get_loc("col1") - df.columns.get_loc("prod"),
df.columns.get_loc("col2") - df.columns.get_loc("prod"),
)
)
df["sum"] = None
df["sum"] = (
'=SUM(INDIRECT("R[0]C[%s]:R[0]C[%s]",0))'
% (
df.columns.get_loc("col1") - df.columns.get_loc("sum"),
df.columns.get_loc("col2") - df.columns.get_loc("sum"),
)
)
df["max"] = None
df["max"] = (
'=MAX(INDIRECT("R[0]C[%s]:R[0]C[%s]",0))'
% (
df.columns.get_loc("col1") - df.columns.get_loc("max"),
df.columns.get_loc("col2") - df.columns.get_loc("max"),
)
)
df["min"] = None
df["min"] = (
'=MIN(INDIRECT("R[0]C[%s]:R[0]C[%s]",0))'
% (
df.columns.get_loc("col1") - df.columns.get_loc("min"),
df.columns.get_loc("col2") - df.columns.get_loc("min"),
)
)
print(df)
df.to_excel(writer, index=False)
writer.save()
执行上述代码后的CLI输出,即print(df)
:
[boris@E7490-DELL temp]$ ./xlsx1.py
col1 col2 prod sum max min
0 7 3 =INDIRECT("R[0]C[-2]", 0)*INDIRECT("R[0]C[-1]"... =SUM(INDIRECT("R[0]C[-3]:R[0]C[-2]",0)) =MAX(INDIRECT("R[0]C[-4]:R[0]C[-3]",0)) =MIN(INDIRECT("R[0]C[-5]:R[0]C[-4]",0))
1 2 6 =INDIRECT("R[0]C[-2]", 0)*INDIRECT("R[0]C[-1]"... =SUM(INDIRECT("R[0]C[-3]:R[0]C[-2]",0)) =MAX(INDIRECT("R[0]C[-4]:R[0]C[-3]",0)) =MIN(INDIRECT("R[0]C[-5]:R[0]C[-4]",0))
2 5 6 =INDIRECT("R[0]C[-2]", 0)*INDIRECT("R[0]C[-1]"... =SUM(INDIRECT("R[0]C[-3]:R[0]C[-2]",0)) =MAX(INDIRECT("R[0]C[-4]:R[0]C[-3]",0)) =MIN(INDIRECT("R[0]C[-5]:R[0]C[-4]",0))
3 9 7 =INDIRECT("R[0]C[-2]", 0)*INDIRECT("R[0]C[-1]"... =SUM(INDIRECT("R[0]C[-3]:R[0]C[-2]",0)) =MAX(INDIRECT("R[0]C[-4]:R[0]C[-3]",0)) =MIN(INDIRECT("R[0]C[-5]:R[0]C[-4]",0))
4 1 9 =INDIRECT("R[0]C[-2]", 0)*INDIRECT("R[0]C[-1]"... =SUM(INDIRECT("R[0]C[-3]:R[0]C[-2]",0)) =MAX(INDIRECT("R[0]C[-4]:R[0]C[-3]",0)) =MIN(INDIRECT("R[0]C[-5]:R[0]C[-4]",0))
foo.xlsx 文件内容(屏幕截图显示 LibreOffice Calc 显示的 foo.xlsx)
这就是我的测试用例 (foo.xlsx) 的创建方式。这个xlsx里面只有数值,有的是整数,有的是公式计算出来的。现在我想在 pandas 数据框中读取此 xlsx 文件以进行 post 处理(不需要公式,但需要公式计算的实际值)。
我尝试了两种方法(均未成功),接下来将进行说明...
方法 1) 使用 pandas.read_excel
:
代码:
[boris@E7490-DELL temp]$ cat xlsx2.py
#!/bin/env python
import pandas as pd
read_file = pd.read_excel("foo.xlsx")
print(read_file)
read_file.to_csv ("foo.csv", index = None, header=True)
CLI 输出:
[boris@E7490-DELL temp]$ ./xlsx2.py
col1 col2 prod sum max min
0 7 3 0 0 0 0
1 2 6 0 0 0 0
2 5 6 0 0 0 0
3 9 7 0 0 0 0
4 1 9 0 0 0 0
foo.csv文件内容:
[boris@E7490-DELL temp]$ cat foo.csv
col1,col2,prod,sum,max,min
7,3,0,0,0,0
2,6,0,0,0,0
5,6,0,0,0,0
9,7,0,0,0,0
1,9,0,0,0,0
方法 2) 使用 openpyxl.load_workbook
:
代码:
[boris@E7490-DELL temp]$ cat xlsx3.py
#!/bin/env python
import pandas as pd
from openpyxl import load_workbook
wb = load_workbook("foo.xlsx", data_only=True)
ws = wb['Sheet1']
df = pd.DataFrame(ws.values)
print(df.head())
df.to_csv ("foo.csv", index = None, header=True)
CLI 输出:
[boris@E7490-DELL temp]$ ./xlsx3.py
0 1 2 3 4 5
0 col1 col2 prod sum max min
1 7 3 0 0 0 0
2 2 6 0 0 0 0
3 5 6 0 0 0 0
4 9 7 0 0 0 0
foo.csv文件内容:
[boris@E7490-DELL temp]$ cat foo.csv
0,1,2,3,4,5
col1,col2,prod,sum,max,min
7,3,0,0,0,0
2,6,0,0,0,0
5,6,0,0,0,0
9,7,0,0,0,0
1,9,0,0,0,0
两种方法都无法从 xlsx 中获取数值。我被困在这里,非常感谢任何帮助。
这里有一些解决方法,不是对正在发生的事情的真正解释,但是...
我得到的结果和你一样,但是如果我打开 excel 文件并保存它,然后在 pandas 中读取它就会得到你想要的数字。所以试试看,打开 excel 并保存它。您可以轻松编写脚本。
由于我不知道如何进一步自动化,我将继续执行无头执行:
soffice --headless --convert-to csv foo.xlsx
foo.csv 文件内容:
[boris@E7490-DELL temp]$ cat foo.csv
col1,col2,prod,sum,max,min
7,3,21,10,7,3
2,6,12,8,6,2
5,6,30,11,6,5
9,7,63,16,9,7
1,9,9,10,9,1
然后我将把这个 csv 文件读到 pandas data-frame post-processing。
我将从 posting 用于为该线程创建测试用例 (foo.xlsx) 的代码示例开始。
这个简单的代码创建了一个包含数字条目和公式的 xlsx 文件:
[boris@E7490-DELL temp]$ cat xlsx1.py
#!/bin/env python
import pandas as pd
d = {'col1': [7, 2, 5, 9, 1], 'col2': [3, 6, 6, 7, 9]}
df = pd.DataFrame(data=d)
writer = pd.ExcelWriter("foo.xlsx", engine="xlsxwriter")
df["prod"] = None
df["prod"] = (
'=INDIRECT("R[0]C[%s]", 0)*INDIRECT("R[0]C[%s]", 0)'
% (
df.columns.get_loc("col1") - df.columns.get_loc("prod"),
df.columns.get_loc("col2") - df.columns.get_loc("prod"),
)
)
df["sum"] = None
df["sum"] = (
'=SUM(INDIRECT("R[0]C[%s]:R[0]C[%s]",0))'
% (
df.columns.get_loc("col1") - df.columns.get_loc("sum"),
df.columns.get_loc("col2") - df.columns.get_loc("sum"),
)
)
df["max"] = None
df["max"] = (
'=MAX(INDIRECT("R[0]C[%s]:R[0]C[%s]",0))'
% (
df.columns.get_loc("col1") - df.columns.get_loc("max"),
df.columns.get_loc("col2") - df.columns.get_loc("max"),
)
)
df["min"] = None
df["min"] = (
'=MIN(INDIRECT("R[0]C[%s]:R[0]C[%s]",0))'
% (
df.columns.get_loc("col1") - df.columns.get_loc("min"),
df.columns.get_loc("col2") - df.columns.get_loc("min"),
)
)
print(df)
df.to_excel(writer, index=False)
writer.save()
执行上述代码后的CLI输出,即print(df)
:
[boris@E7490-DELL temp]$ ./xlsx1.py
col1 col2 prod sum max min
0 7 3 =INDIRECT("R[0]C[-2]", 0)*INDIRECT("R[0]C[-1]"... =SUM(INDIRECT("R[0]C[-3]:R[0]C[-2]",0)) =MAX(INDIRECT("R[0]C[-4]:R[0]C[-3]",0)) =MIN(INDIRECT("R[0]C[-5]:R[0]C[-4]",0))
1 2 6 =INDIRECT("R[0]C[-2]", 0)*INDIRECT("R[0]C[-1]"... =SUM(INDIRECT("R[0]C[-3]:R[0]C[-2]",0)) =MAX(INDIRECT("R[0]C[-4]:R[0]C[-3]",0)) =MIN(INDIRECT("R[0]C[-5]:R[0]C[-4]",0))
2 5 6 =INDIRECT("R[0]C[-2]", 0)*INDIRECT("R[0]C[-1]"... =SUM(INDIRECT("R[0]C[-3]:R[0]C[-2]",0)) =MAX(INDIRECT("R[0]C[-4]:R[0]C[-3]",0)) =MIN(INDIRECT("R[0]C[-5]:R[0]C[-4]",0))
3 9 7 =INDIRECT("R[0]C[-2]", 0)*INDIRECT("R[0]C[-1]"... =SUM(INDIRECT("R[0]C[-3]:R[0]C[-2]",0)) =MAX(INDIRECT("R[0]C[-4]:R[0]C[-3]",0)) =MIN(INDIRECT("R[0]C[-5]:R[0]C[-4]",0))
4 1 9 =INDIRECT("R[0]C[-2]", 0)*INDIRECT("R[0]C[-1]"... =SUM(INDIRECT("R[0]C[-3]:R[0]C[-2]",0)) =MAX(INDIRECT("R[0]C[-4]:R[0]C[-3]",0)) =MIN(INDIRECT("R[0]C[-5]:R[0]C[-4]",0))
foo.xlsx 文件内容(屏幕截图显示 LibreOffice Calc 显示的 foo.xlsx)
这就是我的测试用例 (foo.xlsx) 的创建方式。这个xlsx里面只有数值,有的是整数,有的是公式计算出来的。现在我想在 pandas 数据框中读取此 xlsx 文件以进行 post 处理(不需要公式,但需要公式计算的实际值)。 我尝试了两种方法(均未成功),接下来将进行说明...
方法 1) 使用 pandas.read_excel
:
代码:
[boris@E7490-DELL temp]$ cat xlsx2.py
#!/bin/env python
import pandas as pd
read_file = pd.read_excel("foo.xlsx")
print(read_file)
read_file.to_csv ("foo.csv", index = None, header=True)
CLI 输出:
[boris@E7490-DELL temp]$ ./xlsx2.py
col1 col2 prod sum max min
0 7 3 0 0 0 0
1 2 6 0 0 0 0
2 5 6 0 0 0 0
3 9 7 0 0 0 0
4 1 9 0 0 0 0
foo.csv文件内容:
[boris@E7490-DELL temp]$ cat foo.csv
col1,col2,prod,sum,max,min
7,3,0,0,0,0
2,6,0,0,0,0
5,6,0,0,0,0
9,7,0,0,0,0
1,9,0,0,0,0
方法 2) 使用 openpyxl.load_workbook
:
代码:
[boris@E7490-DELL temp]$ cat xlsx3.py
#!/bin/env python
import pandas as pd
from openpyxl import load_workbook
wb = load_workbook("foo.xlsx", data_only=True)
ws = wb['Sheet1']
df = pd.DataFrame(ws.values)
print(df.head())
df.to_csv ("foo.csv", index = None, header=True)
CLI 输出:
[boris@E7490-DELL temp]$ ./xlsx3.py
0 1 2 3 4 5
0 col1 col2 prod sum max min
1 7 3 0 0 0 0
2 2 6 0 0 0 0
3 5 6 0 0 0 0
4 9 7 0 0 0 0
foo.csv文件内容:
[boris@E7490-DELL temp]$ cat foo.csv
0,1,2,3,4,5
col1,col2,prod,sum,max,min
7,3,0,0,0,0
2,6,0,0,0,0
5,6,0,0,0,0
9,7,0,0,0,0
1,9,0,0,0,0
两种方法都无法从 xlsx 中获取数值。我被困在这里,非常感谢任何帮助。
这里有一些解决方法,不是对正在发生的事情的真正解释,但是...
我得到的结果和你一样,但是如果我打开 excel 文件并保存它,然后在 pandas 中读取它就会得到你想要的数字。所以试试看,打开 excel 并保存它。您可以轻松编写脚本。
由于我不知道如何进一步自动化,我将继续执行无头执行:
soffice --headless --convert-to csv foo.xlsx
foo.csv 文件内容:
[boris@E7490-DELL temp]$ cat foo.csv
col1,col2,prod,sum,max,min
7,3,21,10,7,3
2,6,12,8,6,2
5,6,30,11,6,5
9,7,63,16,9,7
1,9,9,10,9,1
然后我将把这个 csv 文件读到 pandas data-frame post-processing。