关于VS2010创建xlsx的问题

hztj2005 2014-08-15 08:58:15
我试着用VS操作excel,在网上找代码,有两种方案,包含的头文件不同,
a.请教两者之间的关系,这些头文件都是微软提供的吗?
b.方案1能创建xlsx文件,而方案2不能创建xls文件,即使创建了用office 2010也打不开,为什么?


方案1.
#include "CApplication.h"
#include "CRange.h"
#include "CWorkbook.h"
#include "CWorkbooks.h"
#include "CWorksheet.h"
#include "CWorksheets.h"

void CCreatexlsxDlg::OnBnClickedButtonwrite()
{
CString strFile = _T("D:\\WriteToExcelTest.xlsx");

COleVariant covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);

CApplication app;
CWorkbook book;
CWorkbooks books;
CWorksheet sheet;
CWorksheets sheets;
CRange range;
CFont font;

if (!app.CreateDispatch(_T("Excel.Application")))
{
MessageBox(_T("Error!Creat Excel Application Server Faile!"));
}

books = app.get_Workbooks();
//books.AttachDispatch(app.get_Workbooks());可代替上面一行

book = books.Add(covOptional);
//book.AttachDispatch(books.Add(covOptional),true); 可代替上面一行

sheets=book.get_Worksheets();
//sheets.AttachDispatch(book.get_Worksheets(),true); 可代替上面一行

sheet = sheets.get_Item(COleVariant((short)1));
//sheet.AttachDispatch(sheets.get_Item(_variant_t("sheet1")),true); 可代替上面一行

//下面两行,是向A1中写入"Yeah!I can write data to excel!"

range = sheet.get_Range(COleVariant(_T("A1")),COleVariant(_T("A1")));
range.put_Value2(COleVariant(_T("Yeah!I can write data to excel!")));

//下面是向第二行的前十个单元格中输入1到10,十个数字

for(long i=1;i<11;i++)
range.put_Item(_variant_t((long)2),_variant_t((long)i),_variant_t((long)i));


//设置列宽
range = sheet.get_Range(COleVariant(_T("A1")),COleVariant(_T("J1")));
range.put_ColumnWidth(_variant_t((long)5));

//显示表格
app.put_Visible(TRUE);

//保存
book.SaveCopyAs(COleVariant(strFile));
book.put_Saved(true);

//结尾,释放
book.ReleaseDispatch();
books.ReleaseDispatch();

app.ReleaseDispatch();
app.Quit();

}


方案2.
#include <odbcinst.h>
#include <afxdb.h>
if (m_bExcel) // If file is an Excel spreadsheet
{
m_Database->OpenEx(m_sDsn, CDatabase::noOdbcDialog);

if (m_bAppend)
{
// Delete old sheet if it exists
m_stempString= "[" + m_sSheetName + "$A1:IV65536]";
m_stempSql.Format ("DROP TABLE %s", m_stempString);
try
{
m_Database->ExecuteSQL(m_stempSql);
}
catch(CDBException *e)
{
m_sLastError = e->m_strError;
m_Database->Close();
return false;
}

// Create new sheet
m_stempSql.Format("CREATE TABLE [%s$A1:IV65536] (", m_sSheetName);
for (int j = 0; j < m_aFieldNames.GetSize(); j++)
{
m_stempSql = m_stempSql + "[" + m_aFieldNames.GetAt(j) +"]" + " char(255), ";
}
m_stempSql.Delete(m_stempSql.GetLength()-2, 2);
m_stempSql += ")";
}
else
{
// Create new sheet
m_stempSql.Format("CREATE TABLE [%s] (", m_sSheetName);
for (int i = 0; i < m_aFieldNames.GetSize(); i++)
{
m_stempSql = m_stempSql + "[" + m_aFieldNames.GetAt(i) +"]" + " char(255), ";
}
m_stempSql.Delete(m_stempSql.GetLength()-2, 2);
m_stempSql += ")";
}

try
{
m_Database->ExecuteSQL(m_stempSql);
if (!m_bAppend)
{
m_dTotalColumns = m_aFieldNames.GetSize();
m_bAppend = true;
}
}
catch(CDBException *e)
{
m_sLastError = e->m_strError;
m_Database->Close();
return false;
}

// Save changed data
for (int k = 1; k < m_dTotalRows; k++)
{
ReadRow(m_atempArray, k+1);

// Create Insert SQL
m_stempSql.Format("INSERT INTO [%s$A1:IV%d] (", m_sSheetName, k);
for (int i = 0; i < m_atempArray.GetSize(); i++)
{
m_stempString.Format("[%s], ", m_aFieldNames.GetAt(i));
m_stempSql = m_stempSql + m_stempString;
}
m_stempSql.Delete(m_stempSql.GetLength()-2, 2);
m_stempSql += ") VALUES (";
for (int j = 0; j < m_atempArray.GetSize(); j++)
{
m_stempString.Format("'%s', ", m_atempArray.GetAt(j));
m_stempSql = m_stempSql + m_stempString;
}
m_stempSql.Delete(m_stempSql.GetLength()-2, 2);
m_stempSql += ")";

// Add row
try
{
m_Database->ExecuteSQL(m_stempSql);
}
catch(CDBException *e)
{
m_sLastError = e->m_strError;
m_Database->Close();
return false;
}
}
m_Database->Close();
m_bTransaction = false;
return true;

...全文
514 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_36226996 2016-11-20
  • 打赏
  • 举报
回复
楼主,我想用vs将一堆数导入xlsx文件应该怎么做呢
vcf_reader 2014-08-21
  • 打赏
  • 举报
回复
访问excel有两种方式 1、通过com技术,excel本身即com的 2、通过odbc访问,把excel文件当成数据库 至于 xlsx 格式实际是一个压缩包,你可以解压看看,跟 xls 格式有很大的不同
hztj2005 2014-08-21
  • 打赏
  • 举报
回复
引用 7 楼 Naxx_4DK 的回复:
方案1比较全能,想怎么干就怎么干,纯粹的操作EXCEL,好像还可以做合并单元格这类的操作 方案2就是跟数据库相关了,把excel的sheet当做数据库中的表来操作,一般是和数据库之间倒数据用; 方案2要创建xlsx文件的话需要ACE OLEDB 12.0;看下面的这个帖子 http://blog.163.com/qyzdmb@126/blog/static/135942386201111223039641/
谢谢指教。
hztj2005 2014-08-20
  • 打赏
  • 举报
回复
引用 3 楼 hdt 的回复:
访问excel有两种方式 1、通过com技术,excel本身即com的 2、通过ado访问,把excel文件当成数据库 具体在msdn都有
网上的: 通过VS实现对Excel表格的操作的方法有多种,如:通过ODBC数据库实现,通过解析Excel表格文件,通过OLE/COM的实现。 本文通过OLE/COM实现对Excel表格的操作 。 看来我用的是OLE/COM。没做过com编程,不了解其内涵。
Naxx_4DK 2014-08-20
  • 打赏
  • 举报
回复
方案1比较全能,想怎么干就怎么干,纯粹的操作EXCEL,好像还可以做合并单元格这类的操作 方案2就是跟数据库相关了,把excel的sheet当做数据库中的表来操作,一般是和数据库之间倒数据用; 方案2要创建xlsx文件的话需要ACE OLEDB 12.0;看下面的这个帖子 http://blog.163.com/qyzdmb@126/blog/static/135942386201111223039641/
hztj2005 2014-08-20
  • 打赏
  • 举报
回复
OLE/COM实现C++读excel http://keliguo.blog.163.com/blog/static/9410397420123109550892/ VARIANT变量是COM组件之间互相通信的重要的参数变量之一,它可以容纳多种不同的类型,如short、long、double等,包括各类指针和数组。组件之间的互相调用是比较耗时的,尤其带当组件位于不同进程中时,因此,减少传递次数是提高效率的一种有效方法。其中,Excel表格的操作就可能涉及到大量数据,一次传递一个二维数组是提高对Excel表的操作效率。下面以两种不同方式来实现VARIANT二维数组的操作 1、使用SAFEARRAY实现二维数组 SAFEARRAY安全数组可以实现多维数组,SAFEARRAY实现的步骤可以大致分为三步。 (1)创建SAFEARRAY安全数组,包括设置数组元素的类型、数据的维数,大小等。 (2)对SAFEARRAY数组赋值,既可通过SafeArrayPutElement函数逐个元素进行负责,也可通过指针来获得SAFEARRAY的数据地址,然后对指针指向的值进行赋值操作。其中,如果SAFEARRAY中的数组时多维数组,即可以把多维数组转换为一维数组,也可以通过获得指向数组的指针方式来操作数组中的元素。 (3)使用VARIANT变量把SAFEARRAY进行包装。 2、使用COleSafeArray实现二维数组 COleSafeArray继承于VARIANT,是MFC的自动化类,因此,只有在使用MFC类库时才能使用该类。COleSafeArray封装操作相关的函数,可通过MSDN查询该类的成员函数来了解与安全数组相关的函数。COleSafeArray还可以直接转换为VARIANT。因此,相对于SAFEARRAY,COleSafeArray的使用更方便。COleSafeArray和SAFEARRAY之间的关系就是MFC类库和Win32 SDK的关系,使用步骤类似。 VC通过OLE/COM操作Excel,是通过进程间的组件技术。因此,每次读写Excel中的单元格时,都要进行进程间的切换。当数据量大,如果一个单元格一个单元格的读取,主要的时间都花费在进程切换中。因此读取多个单元格,将可有效的提高程序的运行效率。 对多个单元格的读写操作可以通过CRange中以下两个成员函数来完成。 VARIANT get_Value2(); void put_Value2(VARIANT& newValue); 其中,输入参数newValue只要输入一个二维数组,即可实现向Excel中一次写入多个单元格的值。 安全数组似曾相识,但好久没用了。
oyljerry 2014-08-19
  • 打赏
  • 举报
回复
引用 2 楼 hztj2005 的回复:
for(long i=1;i<11;i++) range.put_Item(_variant_t((long)2),_variant_t((long)i),_variant_t((long)i)); 这个语句执行比较慢,数据上万条时要好长时间。
执行慢估计没办法,API本身限制
真相重于对错 2014-08-19
  • 打赏
  • 举报
回复
访问excel有两种方式 1、通过com技术,excel本身即com的 2、通过ado访问,把excel文件当成数据库 具体在msdn都有
hztj2005 2014-08-18
  • 打赏
  • 举报
回复
for(long i=1;i<11;i++) range.put_Item(_variant_t((long)2),_variant_t((long)i),_variant_t((long)i)); 这个语句执行比较慢,数据上万条时要好长时间。
真相重于对错 2014-08-15
  • 打赏
  • 举报
回复
msdn search office 自动化

4,011

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 数据库
社区管理员
  • 数据库
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧