现在的位置: 首页 > 综合 > 正文

VC读写excel(使用CSpreadSheet类方法)

2018年03月18日 ⁄ 综合 ⁄ 共 8489字 ⁄ 字号 评论关闭

以下代码是使用C++语言实现的excel读写,CSpreadSheet.h和CExcel.h可在网上下载,读excel时,把excel第一行作为list ctrl的列名,其余数据插入到列表控件中。

但要注意:此代码在读excel中的数字时,结果为空,目前还没有找到办法解决。

#include "stdafx.h"
#include "CExcel.h"
#include "CExcelDlg.h"
#include ".\cexceldlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#include <algorithm>
#pragma comment(lib, "comsupp.lib")
using namespace ExcelSpace;

// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// 对话框数据
enum { IDD = IDD_ABOUTBOX };

protected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()

CCExcelDlg::CCExcelDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCExcelDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCExcelDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EXCELLIST, m_list);
DDX_Control(pDX, IDC_EXCELPATH, m_edtPath);
}

BEGIN_MESSAGE_MAP(CCExcelDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_READEXCEL, OnBnClickedReadexcel)
ON_BN_CLICKED(IDC_EXPORT, OnBnClickedExport)
END_MESSAGE_MAP()

// CCExcelDlg 消息处理程序

BOOL CCExcelDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// 将\“关于...\”菜单项添加到系统菜单中。

// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
//  执行此操作
SetIcon(m_hIcon, TRUE);
// 设置大图标
SetIcon(m_hIcon, FALSE);
// 设置小图标

// TODO: 在此添加额外的初始化代码
m_list.SetExtendedStyle( m_list.GetExtendedStyle() | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT );
return TRUE;  // 除非设置了控件的焦点,否则返回 TRUE
}

void CCExcelDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CCExcelDlg::OnPaint() 
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// 使图标在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CCExcelDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}

BOOL SetTextFormat(string strFile)
{
_Application app;
//Excel应用程序接口  
Workbooks books;        //工作薄集合  
_Workbook book;
//工作薄  
Worksheets sheets;      //工作表集合  
_Worksheet sheet;       //工作表  
Range range;            //Excel中针对单元格的操作都应先获取其对应的Range对象  
LPDISPATCH lpDisp;
/* 
COleVariant类为VARIANT数据类型的包装,在自动化程序中,通常都使用 
VARIANT数据类型进行参数传递。故下列程序中,函数参数都是通过COleVariant 
类来转换了的。 
*/  
//covOptional 可选参数的VARIANT类型  
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);  

if( !app.CreateDispatch(_T("Excel.Application"), NULL) )
{  
AfxMessageBox("无法创建Excel应用!");  
return FALSE;  
}  


//获取工作薄集合  
books = app.GetWorkbooks();
lpDisp = books.Add(_variant_t(strFile.c_str()));
book.AttachDispatch(lpDisp);
//获取第一个工作表  
sheets.AttachDispatch(book.GetWorksheets(),true);   
    //得到Worksheet  
    sheet.AttachDispatch(sheets.GetItem(_variant_t((short)(1))));    

range.AttachDispatch(sheet.GetCells(),TRUE);//加载所有单元格
sheet.GetRange(COleVariant("A1"),COleVariant("A1"));
range.SetNumberFormatLocal(COleVariant("@"));

//释放对象 
range.ReleaseDispatch(); 
book.ReleaseDispatch(); 
books.ReleaseDispatch(); 
sheet.ReleaseDispatch(); 
sheets.ReleaseDispatch(); 
app.ReleaseDispatch(); 
return TRUE;
}

void CCExcelDlg::OnBnClickedReadexcel()
{
// TODO: 在此添加控件通知处理程序代码 
static char BASED_CODE szFilter[] = "表格文件(*.xls)|*.xls|所有文件(*.*)|*.*||";
COleDateTime dt(COleDateTime::GetCurrentTime());
CString strFileName;
strFileName.Format("%d_%02d_%02d %02d_%02d_%02d", 
dt.GetYear(), dt.GetMonth(), dt.GetDay(), 
dt.GetHour(), dt.GetMinute(), dt.GetSecond());
CFileDialog dlg(FALSE, ".xls", NULL, OFN_HIDEREADONLY, szFilter);
if(dlg.DoModal() == IDOK)
{
CString strFile = dlg.GetPathName();
SetTextFormat(strFile.GetBuffer());
m_edtPath.SetWindowText(strFile);
UpdateData(TRUE);
ReadExcel(strFile.GetBuffer());
}
else
return;
}

CString GetExcelDriver()
{
    char szBuf[2001];
    WORD cbBufMax = 2000;
    WORD cbBufOut;
    char *pszBuf = szBuf;
    CString sDriver;

    // 获取已安装驱动的名称(涵数在odbcinst.h里)
    if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))
        return "";
    
    // 检索已安装的驱动是否有Excel...
    do
    {
        if (strstr(pszBuf, "Excel") != 0)
        {
            //发现 !
            sDriver = CString(pszBuf);
            break;
        }
        pszBuf = strchr(pszBuf, '\0') + 1;
    }
    while (pszBuf[1] != '\0');

    return sDriver;
}

BOOL CCExcelDlg::ReadExcel(const string& strFile)
{
CStringArray sampleArray, testRow, Rows, Column;
CSpreadSheet SS(strFile.c_str(), "",false);
//SS.Commit();
CString sItem;
m_list.DeleteAllItems();
for(int i = m_list.GetHeaderCtrl()->GetItemCount();i >= 0;i--)
{
m_list.DeleteColumn(i);
}
for (int i = 0; i < SS.GetTotalRows(); i++)    
{    
// Read row
::OutputDebugString("for 1");
SS.ReadRow(Rows, i+1);
for (int j = 0; j < Rows.GetSize(); j++)    
{
::OutputDebugString("for 2");
sItem = Rows.GetAt(j);
::OutputDebugString(sItem);
if(i == 0)
{
m_list.InsertColumn((int)(j),sItem,LVCFMT_LEFT,150);
continue;
}

//显示记取的内容
if(j == 0)
{
m_list.InsertItem(i,sItem);
}
else
{
m_list.SetItemText(i-1,j,sItem);
}
}    
}
return TRUE;
}

CString CCExcelDlg::VariantToCString(CDBVariant *var)
{
CString str; //转换以后的字符串
if(!var)
{
str = "NULL Var Parameter";
return str;
}
switch(var->m_dwType)
{
case DBVT_BOOL: 
str = (var->m_boolVal==0) ?L"FALSE": L"TRUE";
break;
case DBVT_SHORT:
str.Format("%d",(int)var->m_iVal);
break;
case DBVT_LONG:
str.Format("%d",var->m_lVal);
break;
case DBVT_SINGLE:
str.Format("%10.6f",(double)var->m_fltVal);
break;
case DBVT_DOUBLE:
str.Format("%10.6f",var->m_dblVal);
break;
case DBVT_DATE:
str.Format("%d-%d-%d",(var->m_pdate)->year,(var->m_pdate)->month,(var->
m_pdate)->day);
break;
case DBVT_STRING:
str = var->m_pstring->GetBuffer();
break;
case DBVT_ASTRING:
str = var->m_pstringA->GetBuffer();
break;
case DBVT_WSTRING:
str = var->m_pstringW->GetBuffer();
break;
default:
str.Format("Unknown type %d\n",var->m_dwType);
TRACE(L"Unknown type %d\n",var->m_dwType);
}
return str;
}

void CCExcelDlg::OnBnClickedExport()
{
// TODO: 在此添加控件通知处理程序代码
if(m_list.GetItemCount() == 0)
{
MessageBox("当前列表为空,无法导出数据。",WINDOWS_TITLE, MB_ICONWARNING | MB_OK);
return;
}
static char BASED_CODE szFilter[] = "表格文件(*.xls)|*.xls|";
COleDateTime dt(COleDateTime::GetCurrentTime());
CString strFileName;
strFileName.Format("%d_%02d_%02d %02d_%02d_%02d", 
dt.GetYear(), dt.GetMonth(), dt.GetDay(), 
dt.GetHour(), dt.GetMinute(), dt.GetSecond());
CFileDialog dlg(FALSE, ".xls", strFileName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);
if(dlg.DoModal() == IDOK)
{
CString strFile = dlg.GetPathName();
CString strExt = dlg.GetFileExt();
m_edtPath.SetWindowText(strFile);
UpdateData(TRUE);
if(strExt.CompareNoCase("xls") == 0)
{
BOOL flag = ExportExcel(strFile.GetString());
if(flag)
{
MessageBox("文件导出成功。",WINDOWS_TITLE, MB_OK);
}
}
else 
{
MessageBox("文件类型不符合要求。",WINDOWS_TITLE, MB_ICONWARNING | MB_OK);
}
}
else
{
MessageBox("取消文件导出。",WINDOWS_TITLE, MB_ICONWARNING | MB_OK);
}
}

BOOL CCExcelDlg::ExportExcel(const string& strFile)
{
// 获取程序所在目录
//创建并写入Excel文件
CDatabase database;
char *sDriver = "MICROSOFT EXCEL DRIVER (*.XLS)";// Excel安装驱动
CString sSql;
DeleteFile(strFile.c_str());

try 
{
// 创建进行存取的字符串
sSql.Format("DRIVER={%s};DSN='';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s",sDriver, strFile.c_str(), strFile.c_str());
// 创建数据库 (既Excel表格文件)

database.OpenEx(sSql,CDatabase::noOdbcDialog);
// 创建表结构
CString strTypeName;
CHeaderCtrl *pHeaderCtrl = m_list.GetHeaderCtrl();//获取列名
TCHAR lpBuffer[256];
HDITEM hdi;
//保存列表头
hdi.mask = HDI_TEXT;
hdi.pszText = lpBuffer;
hdi.cchTextMax = 256;
pHeaderCtrl->GetItem(0,&hdi);
int count = pHeaderCtrl->GetItemCount();
CString strColumn;
CString strTable;
for(int i = 0;i < count;i++)
{
pHeaderCtrl->GetItem(i,&hdi);
strTypeName.Format("%s",hdi.pszText);
strColumn = strColumn + strTypeName + ",";
strTable = strTable + strTypeName + " TEXT,";
}
strTable = strTable.Left(strTable.GetLength() - 1);
sSql.Format("CREATE TABLE Sheet1(%s)",strTable);
database.ExecuteSQL(sSql);

strColumn = strColumn.Left(strColumn.GetLength() - 1);
for(int j = 0;j < m_list.GetItemCount();j++)//行
{
strTypeName = "";
for (int i = 0;i < count;i++ )//列
{
strTypeName += "'" + m_list.GetItemText(j,i) + "'" + ",";
}
strTypeName = strTypeName.Left(strTypeName.GetLength() - 1);
sSql.Format("INSERT INTO Sheet1(%s) VALUES (%s)",strColumn,strTypeName);
// 执行SQL语句
database.ExecuteSQL(sSql);
}
}
catch (.../*_com_error &e*/)
{
MessageBox("数据写入到Excel错误。",WINDOWS_TITLE, MB_ICONWARNING | MB_OK);
database.Close();
DeleteFile(strFile.c_str());
return FALSE;
}
return TRUE;
}

抱歉!评论已关闭.