美文网首页
labwindows/cvi 2019入门(4)——读写EXCE

labwindows/cvi 2019入门(4)——读写EXCE

作者: 菜鸟笔记 | 来源:发表于2019-06-06 08:09 被阅读0次

在工控领域,上位机经常需要操作excel,用于保存测试的数据及测试结果。LabwindowsCVI提供了专门工具库ExcelReport实现对Excel操作。ExcelReport库就是对windows的excel库进行了一层封装,这样我们就能更好的操作excel了,同时也要求计算机上要安装Excel软件。Excelreport.fp的主要函数如下图。


image.png

下面将介绍操作Excel的常用API:
1、ExcelRpt_ApplicationNew
ExcelRpt_ApplicationNew用于启动excel程序,其函数原型如下所示:
HRESULT CVIFUNC ExcelRpt_ApplicationNew (int makeVisible, CAObjHandle *applicationHandle);
其中makeVisible为加载的excel程序是否显示的标志,当其值为1时,显示excel程序界面,如下图所示,applicationHandle为获取的excel程序句柄。

2、ExcelRpt_WorkbookOpen
ExcelRpt_WorkbookOpen用于打开excel的文件,其函数原型如下所示:
HRESULT CVIFUNC ExcelRpt_WorkbookOpen (CAObjHandle applicationHandle, const char *fileName,CAObjHandle *workbookHandle);
其中applicationHandle为excel程序的句柄,fileName为要打开的excel文件路径,workbookHandle为获取的excel文件句柄。

3、ExcelRpt_GetWorksheetFromIndex
ExcelRpt_GetWorksheetFromIndex为获取excel文件中某个sheet句柄,其函数原型如下所示:
HRESULT CVIFUNC ExcelRpt_GetWorksheetFromIndex (CAObjHandle workbookHandle, int Index,CAObjHandle *worksheetHandle);
其中workbookHandle为excel文件的句柄,Index为excel文件中sheet的索引,其索引值从1开始,worksheetHandle为获得的sheet句柄。

4、ExcelRpt_GetCellValue
ExcelRpt_GetCellValue为获取sheet中某cell的内容,其函数原型如下所示:
HRESULT CVIFUNC ExcelRpt_GetCellValue (CAObjHandle worksheetHandle, const char *cellRange,enum ExREnum_ExDataType dataType, void *dataValue);
其中worksheetHandle为sheet句柄,cellRange为cell的索引,dataType为数据类型,通常情况下,该值设置为CAVT_CSTRING,这样我们可以读取各种数据,然后进行转换,dataValue为读取的数据指针。

5、ExcelRpt_SetCellValue
ExcelRpt_SetCellValue用于设置sheet中某cell内容,其函数原型如下所示:
HRESULT ExcelRpt_SetCellValue (CAObjHandle worksheetHandle, char cellRange[], enum ExREnum_ExDataType dataType, ...);
其中worksheetHandle为sheet句柄,cellRange为cell的索引,dataType为数据类型。

6、ExcelRpt_SetCellRangeAttribute
ExcelRpt_SetCellRangeAttribute为设置cell的属性值,其函数原型如下所示:
HRESULT CVIFUNC_C ExcelRpt_SetCellRangeAttribute (CAObjHandle worksheetHandle, const char* cellRange,int attribute, ...);
其中worksheetHandle为sheet句柄,cellRange为cell的索引,attribute为属性的名称,…为属性的值。在测试中,我们经常使用该函数用于设置cell的背景颜色,用于直观感受是否测试通过。

7、ExcelRpt_WorkbookClose
ExcelRpt_WorkbookClose用于关闭打开的excel文件,其函数原型如下所示: HRESULT CVIFUNC ExcelRpt_WorkbookClose (CAObjHandle workbookHandle, int saveChanges);
其中workbookHandle为excel打开文件的句柄,saveChanges为关闭时,是否保存excel文件的标志,通常我们设置该值为1,否则测试的数据将保存不了。

8、ExcelRpt_ApplicationQuit
ExcelRpt_ApplicationQuit用于关闭打开的excel程序,其函数原型如下所示:
HRESULT CVIFUNC ExcelRpt_ApplicationQuit (CAObjHandle applicationHandle);
其中applicationHandle为打开的excel程序实例句柄。

9、ExcelRpt_GetErrorInfo
ExcelRpt_GetErrorInfo用于得到操作excel异常原因,其函数原型如下所示:
ERRORINFO * CVIFUNC ExcelRpt_GetErrorInfo(void);
该函数返回ERRORINFO的指针,我们可以观察ERRORINFO-> description的异常描述。

10、CA_DiscardObjHandle
CA_DiscardObjHandle用于释放objHandle对象,其函数原型如下所示:
HRESULT CVIFUNC CA_DiscardObjHandle(CAObjHandle objHandle);

项目实践:

本项目模拟试验情况生成试验报告。
为了简化代码,首先建一个试验报告模板。每次只需要向EXCEL里面添加对应数据即可。
报告中的图表是事先定义好的,只要数据填进去自动更新。实际上你也可以通过代码插入chart图表。

软件运行后界面如下: image.png
全部代码如下:
#include "excelreport.h"
#include "time.h"
#include <ansi_c.h>
#include <utility.h>
#include <cvirte.h>     
#include <userint.h>
#include "CviExcelRpt.h"

static int panelHandle;
//定义句柄变量
static CAObjHandle applicationHandle = 0;
static CAObjHandle workbookHandle = 0;
static CAObjHandle worksheetHandle = 0;
//定义含路径的文件名变量
char ExcelFileName[MAX_PATHNAME_LEN]={0};
#define LAUNCHERR "\
An error occurred trying to launch Excel through its automation interface.\n\n\
Ensure that Excel is installed and that you can launch it manually."
//产品代号
static char ProductID[128]={0};
//试验单位
static char TestCompany[128]={0};
//操作员
static char Operator[128]={0};
//试验日期
static char TestDate[20]={0};
//试验时间
static char TestTime[20]={0};
//工作压力
static double TestMPa=0.0;
//试验温度
static double TestTemperature=10.0;
//试验时长
static int TestDuration=10;
//试验项目1-4结果
static BOOL Test1Rst=FALSE;
static BOOL Test2Rst=FALSE;
static BOOL Test3Rst=FALSE;
static BOOL Test4Rst=FALSE;
//生产新报告的名字=report+年月日时分秒.xls
static char NewRptFileName[128]={0};
//获取面板上设定的试验内容
void GetTestResult()
{
    GetCtrlVal(panelHandle,PANEL_PRODUCTID,ProductID);
    GetCtrlVal(panelHandle,PANEL_TESTCOMPANY,TestCompany);
    GetCtrlVal(panelHandle,PANEL_OPERATOR,Operator);
    GetCtrlVal(panelHandle,PANEL_MPa,&TestMPa);
    GetCtrlVal(panelHandle,PANEL_TEMPERATURE,&TestTemperature);
    GetCtrlVal(panelHandle,PANEL_TESTTIME,&TestDuration);
    GetCtrlVal(panelHandle,PANEL_TEST1,&Test1Rst);
    GetCtrlVal(panelHandle,PANEL_TEST2,&Test2Rst);
    GetCtrlVal(panelHandle,PANEL_TEST3,&Test3Rst);
    GetCtrlVal(panelHandle,PANEL_TEST4,&Test4Rst);
    
    time_t NowTime;
    time(&NowTime);
    struct tm *Now;
    Now = localtime(&NowTime);
        //生成试验日期
    sprintf(TestDate,"%04d-%02d-%02d",Now->tm_year+1900,Now->tm_mon,Now->tm_mday);
        //生成试验时间
    sprintf(TestTime,"%02d:%02d:%02d",Now->tm_hour,Now->tm_min,Now->tm_sec);
        //生成新试验报告名
    sprintf(NewRptFileName,"\\report%04d%02d%02d%02d%02d%02d.xls",Now->tm_year+1900,Now->tm_mon,Now->tm_mday,Now->tm_hour,Now->tm_min,Now->tm_sec);
}   

int main (int argc, char *argv[])
{
    if (InitCVIRTE (0, argv, 0) == 0)
        return -1;  /* out of memory */
    if ((panelHandle = LoadPanel (0, "CviExcelRpt.uir", PANEL)) < 0)
        return -1;
    DisplayPanel (panelHandle);
    RunUserInterface ();
    DiscardPanel (panelHandle);
    return 0;
}

int CVICALLBACK panelCB (int panel, int event, void *callbackData,
                         int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_GOT_FOCUS:
            break;
        case EVENT_LOST_FOCUS:
            break;
        case EVENT_CLOSE:
            break;
    }
    return 0;
}

int CVICALLBACK btnCreateRpt (int panel, int control, int event,    void *callbackData, int eventData1, int eventData2)
{
    HRESULT error = 0;
    switch (event)
    {
            //插入图表的横坐标纵坐标值cell号和值
            char index[8]={0};
            char data[8]={0};
            int datavalue=0;
            
        case EVENT_COMMIT:
            error = ExcelRpt_ApplicationNew(1, &applicationHandle);
            if (error<0) 
            {
                MessagePopup ("Error:  Microsoft Excel Automation", LAUNCHERR);
                return 0;
            }
            GetProjectDir(ExcelFileName);
            strcat(ExcelFileName,"\\report.xls");
            //打开报告模板文件
            ExcelRpt_WorkbookOpen(applicationHandle,ExcelFileName,&workbookHandle);
            //获取想激活worksheet的句柄 
            ExcelRpt_GetWorksheetFromName(workbookHandle,"Sheet1",&worksheetHandle);
            //激活指定sheet 
            ExcelRpt_ActivateWorksheet(worksheetHandle);
            GetTestResult();
            //向报告中插入试验数据    
            ExcelRpt_SetCellValue(worksheetHandle,"C3",ExRConst_dataString,ProductID);
            ExcelRpt_SetCellValue(worksheetHandle,"C4",ExRConst_dataString,TestCompany);
            ExcelRpt_SetCellValue(worksheetHandle,"C5",ExRConst_dataString,Operator);
            ExcelRpt_SetCellValue(worksheetHandle,"F4",ExRConst_dataString,TestDate);
            ExcelRpt_SetCellValue(worksheetHandle,"F5",ExRConst_dataString,TestTime);
            
            ExcelRpt_SetCellValue(worksheetHandle,"C7",ExRConst_dataDouble,TestMPa);
            ExcelRpt_SetCellValue(worksheetHandle,"C8",ExRConst_dataInt,TestDuration);
            ExcelRpt_SetCellValue(worksheetHandle,"C9",ExRConst_dataDouble,TestTemperature);
            
            if(Test1Rst)
                ExcelRpt_SetCellValue(worksheetHandle,"F19",ExRConst_dataString,"合格");
            else
                ExcelRpt_SetCellValue(worksheetHandle,"F19",ExRConst_dataString,"不合格");
            if(Test2Rst)
                ExcelRpt_SetCellValue(worksheetHandle,"F20",ExRConst_dataString,"合格");
            else
                ExcelRpt_SetCellValue(worksheetHandle,"F20",ExRConst_dataString,"不合格");
            if(Test3Rst)
                ExcelRpt_SetCellValue(worksheetHandle,"F21",ExRConst_dataString,"合格");
            else
                ExcelRpt_SetCellValue(worksheetHandle,"F21",ExRConst_dataString,"不合格");
            if(Test4Rst)
                ExcelRpt_SetCellValue(worksheetHandle,"F22",ExRConst_dataString,"合格");
            else
                ExcelRpt_SetCellValue(worksheetHandle,"F22",ExRConst_dataString,"不合格");
            //随机生成曲线图表用数据
            for(int i=0;i<100;i++)
            {
                sprintf(index,"C%d",30+i);
                sprintf(data,"D%d",30+i);
                datavalue = rand()%100;
                ExcelRpt_SetCellValue(worksheetHandle,index,ExRConst_dataInt,i);
                ExcelRpt_SetCellValue(worksheetHandle,data,ExRConst_dataDouble,datavalue/10.0);
            }
            
            GetProjectDir(ExcelFileName);
            strcat(ExcelFileName,NewRptFileName);
            //报告按照新文件名报表    
            ExcelRpt_WorkbookSave(workbookHandle,ExcelFileName,ExRConst_DefaultFileFormat);
            
            break;
    }
    return 0;
}

int CVICALLBACK btnExit (int panel, int control, int event,
                         void *callbackData, int eventData1, int eventData2)
{
    switch (event)
    {
        case EVENT_COMMIT:
            if (worksheetHandle)
                CA_DiscardObjHandle(worksheetHandle);
            if (workbookHandle)
            {
                //退出程序前一定要释放变量存储
                ExcelRpt_WorkbookClose(workbookHandle, 0);
                CA_DiscardObjHandle(workbookHandle);
            }
            if (applicationHandle)
            {
                ExcelRpt_ApplicationQuit(applicationHandle);
                CA_DiscardObjHandle(applicationHandle);
            }
            QuitUserInterface (0);
            break;
    }
    return 0;
}

运行程序,点击“生成试验报告”按钮,结果如下:


image.png

该程序使用简单,但也有不足:1.需要安装office软件;2.运行速度较慢。后续将研究使用第三方控件独立操作Excel文件。
这个例子的练习让我又重新复习了很多C语言的知识。如整数转字符、格式化字符、获取系统时间、获取一定范围随机数等。
欢迎交流QQ:491114509

相关文章

网友评论

      本文标题:labwindows/cvi 2019入门(4)——读写EXCE

      本文链接:https://www.haomeiwen.com/subject/edaexctx.html