众所周知,使用c/c++处理execl文件是很麻烦的事情,而python利用pandas库处理excel非常方便,所以这里使用c/c++调用python函数处理excel
环境:(这里使用的是mac系统)
python3.7
c++11
直接上代码:
python文件代码
import pandas as pd
def AdditionFc(a, b):
print("Now is in python model")
print(f"{a} + {b} = {a + b}")
return a + b
def openXlsx(path):
df = pd.read_excel(path)
c = df.columns.values.tolist()
r = df.index.values.tolist()
data = []
for i in r:
row = []
for j in range(len(c)):
row.append(df.iloc[i, j])
data.append(row)
return data[0]
def openXlsxStr(path):
df = pd.read_excel(path)
c = df.columns.values.tolist()
r = df.index.values.tolist()
data = []
for i in r:
row = []
for j in range(len(c)):
row.append(df.iloc[i, j])
data.append(row)
return c[0]
def openXlsxList(path):
df = pd.read_excel(path)
c = df.columns.values.tolist()
r = df.index.values.tolist()
data = []
for i in r:
row = []
for j in range(len(c)):
row.append(df.iloc[i, j])
data.append(row)
return data
#include <stdio.h>
#include </Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m/Python.h>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
/*
命令 实际输入
Py_BuildValue("") None
Py_BuildValue(“i”, 123) 123
Py_BuildValue(“iii”, 123, 456, 789) (123, 456, 789)
Py_BuildValue(“s”, “hello”) ‘hello’
Py_BuildValue(“ss”, “hello”, “world”) (‘hello’, ‘world’)
Py_BuildValue(“s#”, “hello”, 4) ‘hell’
Py_BuildValue("()") ()
Py_BuildValue("(i)", 123) (123,)
Py_BuildValue("(ii)", 123, 456) (123, 456)
Py_BuildValue("(i,i)", 123, 456) (123, 456)
Py_BuildValue("[i,i]", 123, 456) [123, 456]
Py_BuildValue("{s:i,s:i}", “abc”, 123, “def”, 456) {‘abc’: 123, ‘def’: 456}
Py_BuildValue("((ii)(ii)) (ii)", 1, 2, 3, 4, 5, 6) (((1, 2), (3, 4)), (5, 6))
*/
void printVectorInt(const vector<int>& v)
{
for (vector<int>::const_iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
// 无参函数调用 python 函数无返回值
int python_test_null()
{
// 1、初始化python接口
Py_Initialize();
if(!Py_IsInitialized()){
cout << "python init fail" << endl;
return 0;
}
// 2、初始化python系统文件路径,保证可以访问到 .py文件
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./script')");
// 3、调用python文件名,不用写后缀
PyObject* pModule = PyImport_ImportModule("sayhello");
if( pModule == NULL ){
cout <<"module not found" << endl;
return 1;
}
// 4、调用函数
PyObject* pFunc = PyObject_GetAttrString(pModule, "say");
if( !pFunc || !PyCallable_Check(pFunc)){
cout <<"not found function add_num" << endl;
return 0;
}
//
PyObject_CallObject(pFunc, NULL);
// 5、结束python接口初始化
Py_Finalize();
return 0;
}
// 有参函数调用 python 函数返回一个整数
int python_test()
{
Py_Initialize(); //1、初始化python接口
//初始化使用的变量
PyObject* pModule = NULL;
PyObject* pFunc = NULL;
PyObject* pName = NULL;
/* 添加模块路径 */
//2、初始化python系统文件路径,保证可以访问到 .py文件
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append('./script')");
//3、调用python文件名。当前的测试python文件名是 myadd.py 导入模块
// 在使用这个函数的时候,只需要写文件的名称就可以了。不用写后缀。
pModule = PyImport_ImportModule("myadd");
//4、调用函数 导入函数
pFunc = PyObject_GetAttrString(pModule, "AdditionFc");
//5、给python传参数
// 函数调用的参数传递均是以元组的形式打包的,2表示参数个数
// 如果AdditionFc中只有一个参数时,写1就可以了
PyObject* pArgs = PyTuple_New(2);
// 0:第一个参数,传入 int 类型的值 2
PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 2));
// 1:第二个参数,传入 int 类型的值 4
PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 4));
// 6、使用C++的python接口调用该函数
PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);
// 7、接收python计算好的返回值
int nResult;
// i表示转换成int型变量。
// 在这里,最需要注意的是:PyArg_Parse的最后一个参数,必须加上“&”符号
PyArg_Parse(pReturn, "i", &nResult);
cout << "return result is " << nResult << endl;
//8、结束python接口初始化
Py_Finalize();
return 0;
}
// 有参函数调用,python函数返回一个一维列表
void python_return_list()
{
/* 1、初始化python接口 */
Py_Initialize();
/* 2、初始化python系统文件和pandas库文件 */
PyRun_SimpleString("import sys");
// PyRun_SimpleString("import pandas as pd");
PyRun_SimpleString("sys.path.append('./script')");
/* 3、调用python文件名。当前的测试python文件名是 myadd.py 导入模块 不用添加.py后缀 */
PyObject* pModule = PyImport_ImportModule("myadd");
/* 4、调用函数 导入函数 */
PyObject* pFunc = PyObject_GetAttrString(pModule, "openXlsx");
/* 5、给python传参数 函数调用的参数传递均是以元组的形式打包的,2表示参数个数 */
PyObject* pArgs = PyTuple_New(1);
// 传入 char* 类型的值 path
PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "/Users/python_workstation/Desktop/test.xlsx"));
/* 6、使用C++的python接口调用该函数 */
PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);
/* 7、接收python的返回值 一维列表*/
vector<int> dataInt;
int listSize = PyList_Size(pReturn); // 获取返回的列表长度
int temp;
for (int i = 0; i < listSize; i++)
{
PyArg_Parse(PyList_GetItem(pReturn, i), "i", &temp);
dataInt.push_back(temp);
}
Py_Finalize();
printVectorInt(dataInt);
}
// 有参函数调用,python函数返回一个字符串
void python_return_str()
{
/* 1、初始化python接口 */
Py_Initialize();
/* 2、初始化python系统文件和pandas库文件 */
PyRun_SimpleString("import sys");
// PyRun_SimpleString("import pandas as pd");
PyRun_SimpleString("sys.path.append('./script')");
/* 3、调用python文件名。当前的测试python文件名是 myadd.py 导入模块 不用添加.py后缀 */
PyObject* pModule = PyImport_ImportModule("myadd");
/* 4、调用函数 导入函数 */
PyObject* pFunc = PyObject_GetAttrString(pModule, "openXlsxStr");
/* 5、给python传参数 函数调用的参数传递均是以元组的形式打包的,2表示参数个数 */
PyObject* pArgs = PyTuple_New(1);
// 传入 char* 类型的值 path
PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "/Users/python_workstation/Desktop/test.xlsx"));
/* 6、使用C++的python接口调用该函数 */
PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);
/* 7、接收python的返回值 一个字符串*/
char* pstr = NULL;
PyArg_Parse(pReturn, "s", &pstr);
cout << pstr << endl;
Py_Finalize();
}
// 有参函数调用,python函数返回一个二维列表
void python_return_list_two()
{
/* 1、初始化python接口 */
Py_Initialize();
/* 2、初始化python系统文件和pandas库文件 */
PyRun_SimpleString("import sys");
// PyRun_SimpleString("import pandas as pd");
PyRun_SimpleString("sys.path.append('./script')");
/* 3、调用python文件名。当前的测试python文件名是 myadd.py 导入模块 不用添加.py后缀 */
PyObject* pModule = PyImport_ImportModule("myadd");
/* 4、调用函数 导入函数 */
PyObject* pFunc = PyObject_GetAttrString(pModule, "openXlsxList");
/* 5、给python传参数 函数调用的参数传递均是以元组的形式打包的,2表示参数个数 */
PyObject* pArgs = PyTuple_New(1);
// 传入 char* 类型的值 path
PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "/Users/python_workstation/Desktop/test.xlsx"));
/* 6、使用C++的python接口调用该函数 */
PyObject* pReturn = PyEval_CallObject(pFunc, pArgs);
/* 7、接收python的返回值 一个二维数字列表*/
int temp;
// 获得序列长度
Py_ssize_t rsize = PyObject_Size(pReturn);
cout << "rsize: " << rsize << endl;
PyObject* iter = PyObject_GetIter(pReturn);
while (true)
{
//获取列表的第一行
PyObject* next = PyIter_Next(iter);
if (!next)
{
break;
}
if (!PyList_Check(next))
{
cout << "error, we were expecting a list value" << endl;
}
Py_ssize_t foosize = PyObject_Size(next);
PyObject* iter2 = PyObject_GetIter(next);
while (true)
{
PyObject* next2 = PyIter_Next(iter2);
if (!next2)
{
break;
}
if (!PyList_Check(next))
{
cout << "error, we were expecting a list value" << endl;
}
double foo = PyFloat_AsDouble(next2);
cout << foo << " ";
}
cout << endl;
}
Py_Finalize();
}
int main(int argc, char *argv[])
{
python_return_list_two();
return 0;
}
输出结果:
clang++ python_test.cpp -I/usr/local/python3.7m -o python_test -L/Library/Frameworks/Python.framework/Versions/3.7/lib -lpython3.7m