在上一篇中本人向大家介绍了OLE读取EXCEL文件所用到的动态链接库的方法!下面这一章节为大家介绍简单的UI界面以及使用DLL的方法!
上一章节连接在此:http://blog.csdn.net/qq_35747066/article/details/78942143
(一)界面
界面很垃圾,内容很朴实。在lineedit中输入学生姓名后点击“开始搜索”,之后在textedit显示该学生参加的社会实践队名。(PS:本人就读于一所很普通的985院校--大连理工大学,所以加载的excel也是大连理工大学的寒假社会实践统计表~)
呵呵~是不是特别有趣?因为是利用OLE方法对EXCEL文件进行读取,所以程序刚开始启动时比较慢,需要将本程序的excel(1000多行记录)读入到数据结构中,大概得等17秒左右的时间,您耐心等待,千万不要以为程序死机没反应了啊~
(二)封装的DLL类结构
文件:CDH_CppExcelFileRead.cpp
#pragma once
//----------------------------------------------------------------------//
// CDH_CppReadExcelDLL类定义:完成DLL的加载、卸载以及函数访问
// 当初始化一个类对象的时候代表DLL的加载,而类对象消失析构的时
// 时候代表DLL的卸载。
// 对于本例中Excel读取来说,加载DLL后要首先初始化Excel OLE才能
// 进行后续的读取操作;而卸载DLL之前要将Excel OLE释放。因此在本类
// 的构造和析构函数中分别完成上述工作。
//----------------------------------------------------------------------//
#pragma once
#include<Windows.h>
#include<string>
using namespace std;
// 根据CppReadExcelDLL的接口函数定义
typedef bool(*DLL_API_pFunc_Excel_Init)(void);
typedef void(*DLL_API_pFunc_Excel_Release)(void);
typedef int(*DLL_API_pFunc_get_sheets_count)(string&);
typedef string(*DLL_API_pFunc_get_sheet_name)(string&, long);
typedef int(*DLL_API_pFunc_get_rows_count)(string&, long);
typedef int(*DLL_API_pFunc_get_cols_count)(string&, long);
typedef int(*DLL_API_pFunc_get_sheet_index)(string&, string&);
typedef string(*DLL_API_pFunc_get_cell_string)(string&, long, long, long);
typedef int(*DLL_API_pFunc_get_cell_int)(string&, long, long, long);
typedef double(*DLL_API_pFunc_get_cell_double)(string&, long, long, long);
typedef bool(*DLL_API_pFunc_IsCellEmpty)(string&, long, long, long);
// CDH_CppReadExcelDLL类定义
class CDH_CppReadExcelDLL
{
private:
HINSTANCE hdll;
bool LoadedSuccessFlag;
bool ExcelInitFlag;
protected:
// Excel的加载和释放
bool Excel_Init(void)
{
DLL_API_pFunc_Excel_Init func = (DLL_API_pFunc_Excel_Init)GetProcAddress(hdll, "Excel_Init");
return func();
}
void Excel_Release(void)
{
DLL_API_pFunc_Excel_Release func = (DLL_API_pFunc_Excel_Release)GetProcAddress(hdll, "Excel_Release");
return func();
}
public:
// 构造函数:加载DLL
CDH_CppReadExcelDLL(string &CppReadExcelDLL_pathStr)
{
LoadedSuccessFlag = false;
ExcelInitFlag = false;
// 加载DLL
hdll = LoadLibraryA(CppReadExcelDLL_pathStr.c_str());
// hdll = LoadLibrary(CppReadExcelDLL_pathStr);
if (hdll == NULL)return;
else LoadedSuccessFlag = true;
// 加载Excel
if (Excel_Init())ExcelInitFlag = true;
}
// 析构函数:卸载DLL
~CDH_CppReadExcelDLL()
{
if (!LoadedSuccessFlag)return;
// 释放Excel
Excel_Release();
// 卸载DLL
FreeLibrary(hdll);
}
// 判断是否加载DLL成功
bool IsLoadedSuccess() { return LoadedSuccessFlag; }
// 判断Excel是否初始化成功
bool IsExcelInit() { return ExcelInitFlag; }
// DLL接口函数
int get_sheets_count(string &file_name)
{
DLL_API_pFunc_get_sheets_count func = (DLL_API_pFunc_get_sheets_count)GetProcAddress(hdll, "get_sheets_count");
return func(file_name);
}
string get_sheet_name(string &file_name, long iSheet)
{
DLL_API_pFunc_get_sheet_name func = (DLL_API_pFunc_get_sheet_name)GetProcAddress(hdll, "get_sheet_name");
return func(file_name, iSheet);
}
int get_rows_count(string &file_name, long iSheet)
{
DLL_API_pFunc_get_rows_count func = (DLL_API_pFunc_get_rows_count)GetProcAddress(hdll, "get_rows_count");
return func(file_name, iSheet);
}
int get_cols_count(string &file_name, long iSheet)
{
DLL_API_pFunc_get_cols_count func = (DLL_API_pFunc_get_cols_count)GetProcAddress(hdll, "get_cols_count");
return func(file_name, iSheet);
}
int get_sheet_index(string &file_name, string &sheet_name)
{
DLL_API_pFunc_get_sheet_index func = (DLL_API_pFunc_get_sheet_index)GetProcAddress(hdll, "get_sheet_index");
return func(file_name, sheet_name);
}
string get_cell_string(string &file_name, long iSheet, long iRows, long iCols)
{
DLL_API_pFunc_get_cell_string func = (DLL_API_pFunc_get_cell_string)GetProcAddress(hdll, "get_cell_string");
return func(file_name, iSheet, iRows, iCols);
}
int get_cell_int(string &file_name, long iSheet, long iRows, long iCols)
{
DLL_API_pFunc_get_cell_int func = (DLL_API_pFunc_get_cell_int)GetProcAddress(hdll, "get_cell_int");
return func(file_name, iSheet, iRows, iCols);
}
double get_cell_double(string &file_name, long iSheet, long iRows, long iCols)
{
DLL_API_pFunc_get_cell_double func = (DLL_API_pFunc_get_cell_double)GetProcAddress(hdll, "get_cell_double");
return func(file_name, iSheet, iRows, iCols);
}
bool IsCellEmpty(string &file_name, long iSheet, long iRows, long iCols)
{
DLL_API_pFunc_IsCellEmpty func = (DLL_API_pFunc_IsCellEmpty)GetProcAddress(hdll, "IsCellEmpty");
return func(file_name, iSheet, iRows, iCols);
}
};
在这里,本人定义了一个类CDH_CppExcelFileRead,为了增强代码的可维护性,本人大量的使用了typedef函数指针,
typedef函数指针使用教程请撮这里!,有人会问我怎么加载的dll,
那就请看这里!动态链接dll是一个有难度的方法,CSDN等很多网站都没有成功的实现案例!在这里我要由衷的感谢我的老同学--
上海交通大学的潘博士的帮助,没有他的帮助,我也不可能会调通动态链接dll到内存的代码!
(三)数据结构
本工程的数据结构是根据大连理工大学社会实践队的实际背景而来的,故没有太多的参考价值,大家都能根据EXCEL数据背景的需要构造自己的数据结构!!!
文件名称:DataStructure.h
#pragma once
#include<iostream>
#include<vector>
using namespace std;
//团队成员基本信息
struct SOnePerson
{
string number;//学号
string name;//成员姓名
string department;//学部
};
//团队信息
struct SOneTeam
{
int ID;//团队ID
string name;//团队名称
vector <SOnePerson> person;//团队成员信息
};
//队伍类
class CTeam
{
private :
vector<SOneTeam> Team;
public:
//---构造函数
CTeam() { Team.clear(); }
CTeam(SOneTeam &OneTeam) { Team.push_back(OneTeam); }
//---重置函数
void Reset() { Team.clear(); }
//判断是否有效
operator bool()
{
if (Team.size())
{
return true;
}
else { return false; }
}
//---返回队伍的个数
int get_Team_count() { return Team.size(); }
//---返回某一个队伍
SOneTeam& get_team(int index) { return Team.at(index); }
//---添加一个队伍的信息
void AddTeam(int ID/*队伍ID*/, string &TeamName/*队伍名称*/, string &number/*队长学号*/, string &name/*队长姓名*/, string &department/*队长所在的学部*/)
{
vector<SOnePerson> person;
SOnePerson temp_person = { name,number,department };
person.push_back(temp_person);
SOneTeam temp = { ID,TeamName,person };
Team.push_back(temp);
}
//---添加一个队员的基本信息
//---参数一:队伍的编号(从1开始),结构体引用
void AddPerson(int ID,SOnePerson &OnePerson)
{
Team.at(ID - 1).person.push_back(OnePerson);//将这个成员的信息以结构体的数据结构压入栈
}
//---返回成员容器
vector<SOneTeam> GetTeamInfo()
{
return Team;
}
};
(四)MainWindow.cpp
#include "MainWindow.h"
#include "CDH_CExcelFileRead.h"
#include "DataStructure.h"
#include<QTextCodec>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->textEdit->setReadOnly(true);
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(SearchSlot()));
LoadExcelFile();
}
//以下函数解决了中文QString转String乱码的问题
QString str2qstr(const string str)
{
return QString::fromLocal8Bit(str.data());
}
void MainWindow::LoadExcelFile()
{
//---获取dll的当前路径
QString path;
QApplication *path_1 = NULL;
//---path是dll的根目录
path = path_1->applicationDirPath();
//---将一个'/'改为两个'//'
vector<int> position;
for (int i = 0; i < path.length(); i++)
{
if (path[i] == '/') { position.push_back(i); }
}
QString y = "\\";
int initial = position.size();//记录'/'的位置
for (int i = 0; i < initial; i++)
{
path.replace(position[position.size() - 1], 1, y);//替代操作
position.pop_back();//弹出操作,不返回任何值
}
QString dll_path = path + "\\ExcelFileRead.dll";
CDH_CppReadExcelDLL DH_CppReadExcelDLL(dll_path.toStdString());
//---读取相关的excel
QString student_path = path + "\\2016StudentInfo.xlsx";
//---1.1读取团队数目
int team_row_count = DH_CppReadExcelDLL.get_rows_count(student_path.toStdString(),1);
//---1.2读取excel的最大列数
int team_col_count = DH_CppReadExcelDLL.get_cols_count(student_path.toStdString(),1);
//---1.3读取团队信息
for (int i = 1; i <= team_row_count; i++)
{
int Col_index = 6;
int ID = DH_CppReadExcelDLL.get_cell_int(student_path.toStdString(), 1, i, 1);
string TeamName = DH_CppReadExcelDLL.get_cell_string(student_path.toStdString(), 1, i, 2);
string StudentName = DH_CppReadExcelDLL.get_cell_string(student_path.toStdString(), 1, i, 3);
string StudentNumber = DH_CppReadExcelDLL.get_cell_string(student_path.toStdString(), 1, i, 4);
string StudentDepart = DH_CppReadExcelDLL.get_cell_string(student_path.toStdString(), 1, i, 5);
Team.AddTeam(ID, TeamName, StudentName, StudentNumber, StudentDepart);//创建一个队伍
StudentName = DH_CppReadExcelDLL.get_cell_string(student_path.toStdString(), 1, i, Col_index);
while (StudentName != "")
{
StudentNumber = DH_CppReadExcelDLL.get_cell_string(student_path.toStdString(), 1, i, Col_index + 1);
StudentDepart = DH_CppReadExcelDLL.get_cell_string(student_path.toStdString(), 1, i, Col_index + 2);
SOnePerson OnePerson = { StudentNumber,StudentName,StudentDepart };
Team.AddPerson(i, OnePerson);
Col_index += 3;
StudentName = DH_CppReadExcelDLL.get_cell_string(student_path.toStdString(), 1, i, Col_index);
}
}
}
//---搜索按钮触发函数
void MainWindow::SearchSlot()
{
int SuccessFlag = 0;
int SuccessNum = 0;
//---清屏
ui->textEdit->clear();
//---获得待查学生姓名
QString StudentName = ui->lineEdit->text();
//---开始大循环
for (int i = 0; i < Team.get_Team_count(); i++)
{
int TeamNum = Team.get_team(i).person.size();
for (int j = 0; j < TeamNum; j++)
{
if (QString(str2qstr(Team.get_team(i).person.at(j).name)) == StudentName)
{
ui->textEdit->setPlainText(QString(str2qstr(Team.get_team(i).name)) + "\n");
SuccessNum++;
}
}
}
ui->textEdit->append(QString(str2qstr("一共找到")) + QString::number(SuccessNum, 10) + QString(str2qstr("条结果!")));
}
这是本工程的主体代码!
完整代码链接如下:http://download.csdn.net/download/qq_35747066/10205399
作者简介:大连理工大学2014级计算机科学与技术本科生,哈尔滨工业大学2018级计算机技术硕士研究生。我的QQ号码:1012638836,如果您对本人的博客有任何疑问,请与我联系!
个人经历:2014年高考645考入大连理工大学计算机专业,2017年以专业第六名保研进入哈工大计算机学院攻读硕士,大连市优秀毕业生,大二发表一篇第一作者高质量学术论文,目前从事模式识别领域的研究。