PLM之家精品课程培训,联系电话:18301858168 QQ: 939801026

  • NX二次开培训

    NX二次开培训

    适合初级入门或想深入了解二次开发的工程师,本培训结合ufun,NXOpen C++,大量的实例及官方内部的开发技术对于老鸟也值得借鉴!.

    NX CAM二次开发培训报名 NX二次开发基础培训报名
  • PLM之家Catia CAA二次开发培训

    Catia二次开发培训

    Catia二次开发的市场大,这方面开发人才少,难度大。所以只要你掌握了开发,那么潜力巨大,随着时间的积累,你必将有所用武之地!

  • PLM之Teamcenter最佳学习方案

    Teamcenter培训

    用户应用基础培训,管理员基础培训,管理员高级培训,二次开发培训应有尽有,只要你感兴趣肯学习,专业多年经验大师级打造!

  • PLM之Tecnomatix制造领域培训

    Tecnomatix培训

    想了解制造领域数字化吗?想了解工厂,生产线设计吗?数字化双胞胎,工业4.0吗?我们的课程虚位以待!

PLM之家PLMHome-国产软件践行者

[转载电子书] VS C++操作Excel详细教程

[复制链接]

2014-11-8 08:13:41 6439 0

admin 发表于 2014-11-8 08:13:41 |阅读模式

admin 楼主

2014-11-8 08:13:41

请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!

您需要 登录 才可以下载或查看,没有账号?注册

x
通过VC实现对Excel表格的操作的方法有多种,如:通过ODBC数据库实现,通过解析Excel表格文件,通过OLE/COM的实现。本文主要研究通过OLE/COM实现对Excel表格的操作。6 u. Y; T& P, b, Z1 q2 D  F) w+ O- W5 k
  9 u# L! D& D! I( V$ [* |0 W# z
本文源码的应用环境说明:0 v/ R# E$ Q  h/ ^8 s+ [( e# Y+ s
Windows XP SP3
. K1 {9 n5 m  i, X3 l9 q0 U" SMicrosoft Visual Studio 20101 y% U8 P" _2 z' A& T& R
Microsoft Office Excel 20078 L' m8 @/ n2 k. h, z0 K1 D
  
9 Q9 k7 R6 U; Q4 D$ K) @1、添加OLE/COM支持。
0 j, D5 S  a2 o8 L2 O# j首先,应用程序必须添加对OLE/COM的支持,才能导入OLE/COM组件。
3 h: x9 C9 F! S- J9 Z# T本文使用的是MFC对话框程序,在创建工程的向导中选中Automation选项即可为程序自动添加相应的头文件和OLE库初始化代码。
) A- H0 L7 O3 }6 Z2 B+ m! r通过查看源代码,可以知道在stdafx.h的头文件中,添加了OLE/COM很多类所需添加的头文件。/ Y) t( c1 N$ h* o+ A
#include <afxdisp.h>        // MFC 自动化类
2 |/ S7 J8 Z8 ]同时,在应用程序类的InitInstance函数中,添加了OLE/COM的初始化代码,如下所示:/ j7 K3 J4 b( P1 A+ E9 t% C
// 初始化 OLE 库
& ~& n1 {" R9 ]if (!AfxOleInit())
: p8 V) v0 E8 o1 t4 T: i& ?# V{
% P9 e# P* w3 J  G/ Y: k/ fAfxMessageBox(IDP_OLE_INIT_FAILED);0 i! [7 n0 H' @% j- C
return FALSE;  n6 j: Z  R  L) }9 @
}6 i  x1 e, e, ?% D4 \  F
  
& R+ F( s* _0 L! `- Z2、导入并封装Excel中的接口
/ F* U' x" g3 l- L# [- tExcel作为OLE/COM库插件,定义好了各类交互的接口,这些接口是跨语言的接口。VC可以通过导入这些接口,并通过接口来对Excel的操作。
6 Z0 ^& b& B# ~! w" s, i& l由于本文只关心对Excel表格中的数据的读取,主要关注几个_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range等几个接口。Excel的各类接口的属性、方法可以通过MSDN的Office Development进行查询。
6 r1 V# i' |' w/ z* i2 o2 X. [VS2010导入OLE/COM组件的接口的步骤为:Project->Class Wizard->Add Class->MFC Class From TypeLib,先选择要导入的组件所在的路径,即Excel.exe所在的路径,然后再选择3 P1 s, v2 ]& Z, o, ?* j
要导入的Excel类型库中的接口。
" k9 J: S4 }3 r  B/ O( @2 S在完成接口导入后,VS2010将自动为导入的接口创建相应的实现类,用于对接口属性和方法的实现。由于标准的C++没有属性访问器,只能添加一个两个存取函数来实现对属性的访问,通过在属性名称前加上get_和put_前缀分别实现对属性的读写操作。即,由VC自动完成C++类对接口的封装。
% R9 b% h& W0 Q  g: A8 K/ Z  . ]2 u% c% k6 B
本文所导入的接口对应的类和头文件的说明如下所示:
4 X# h  f' c' V1 R$ t  ! L) N2 Z" Q6 T: W, H
Excel接口* f* B' {) C% K1 [  x
导入类! T5 k$ C+ M. k% i' ^* [- U
头文件
5 Q5 B4 t  L0 v# T( e) S0 n说明. H' T& C" A$ C' e
_Application
7 [, j( j0 L/ _2 d$ c$ H; }/ VCApplicaton
9 ~! l! \( g4 Y% r* ?8 m+ e- w- ?Application.h
+ T% t' i# m% ?0 j4 \, ?& ~Excel应用程序。
* t3 X: N. q' tWorkbooks
  a) u( m: p( J7 n4 K/ F0 jCWorkbooks, S; a2 r' l0 P9 q7 g
Workbooks.h$ `$ T2 s6 P  ~. D$ }1 ^
工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。
# a7 ?* z" o! p' q_Workbook4 w, O! F, y  T0 T% h
CWorkbook" R8 X4 A, A# d! A
Workbook.h
1 U: [; A% M! v" I; J' a% M单个工作簿。
; O- p0 R6 L. QWorksheets
9 b1 u1 [' K3 kCWorksheets
2 G: H& p7 k% T1 g# mWorksheets.h
- r% r; u4 A$ A+ `; W/ z单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。
" \% E2 e: W3 Q2 S# E_Worksheet, V' w0 X8 m. a& J
CWorksheet- M4 }8 h* y' [& m- q% N
Worksheet.h& @& m* y. G. T3 ~. u
单个Sheet表格。# c1 _/ Q/ s  d  R; z+ z6 m: X0 H9 Z
Range
% t; e. X6 ?& R! U" ~# |CRange  m9 ]- q* W5 K
Range.h
1 m9 q- I  c  z0 x4 A$ I7 r7 l2 S) E! I+ |一定数量的单元格,可对单元格进行单个或多个单元格进行操作。
' @7 w" M6 O; t: A0 W  
5 q# `5 |. I. L, q3、导入Excel的整个类型库/ K0 y0 j" c7 i* C
接口对应类只是对接口的属性和方法进行了封装,而Excel中的数据类型,如枚举类型却并为并不能使用,因此,为了更方便的操作Excel,还需要导入Excel的数据类型。: I/ c4 l7 P% h9 @5 _
通过查看导入接口对应的头文件可以发现,在所有导入接口的头文件中,都会有这么行:
9 P+ Q, o. I' M) \; |3 z#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace
  `( h% P( r! g* B3 S这行代码的作用是导入Excel整个类型库到工程中。
7 u* \; s! z, a# ?由VS2010自动产生的导入代码存在以下几个问题:
2 A1 a" B  X* C" E1 j(1)如果导入了多个接口,每个头文件都会把类型库导入一次,如果引用多个头文件,会导致类型库重复导入。1 y; s7 D/ c0 a& J
(2)Excel类型库中有些类型会跟MFC类库的某些类型冲突。
) Z% ?$ `! @0 H# }. k(3)Excel类型库的某些类型跟其他Office和VB的某些库相关,如果不导入相关库,将导致这些类型无法使用。。
  m0 a' h0 W; \+ }8 q, a以上三点问题的解决方法如下:
5 C) |/ k0 g4 C) B4 c9 M9 k% ?(1)仅在_Application接口对应头文件中导入Excel类型库。
! J. Q6 k9 G) C( W, X/ w(2)对冲突的类型进行重命名。% P! G8 t, U$ x+ V( J  K2 Z5 v
(3)在导入Excel类型库之前,先导入Office和VB的相关库。$ s, r8 q' K. z2 G8 ~! Z0 H
更改后的导入类型库的代码如下:3 D, y, S. g) [5 e% }
  4 ?# w( s; P# @( t0 y5 y7 K
/*导入Office的类型库*/
0 M- I6 e0 N) ?2 Y! S. C* a#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL" \
3 C; g, L% M6 ]/ {8 Frename("RGB", "MSORGB") \
1 f* d# _$ U3 x; U0 ~rename("DocumentProperties", "MSODocumentProperties")3 Q5 E4 C* Y8 `
using namespace Office;
, W1 ?! H3 ~  X4 l2 o4 m/ }  
! Y3 l5 U! ]) A3 d! X& j$ l4 p/*导入VB的类型库*/
1 d1 X5 m! D. T2 x+ r#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB": t: j4 q( p5 o3 F
using namespace VBIDE;
. N( p' @  ^) t1 \2 |- e( h  
$ h5 a" c7 e+ Z2 s8 A# p! f) J/*导入Excel的类型库*/
8 h% z; G# F: Y# S$ `  S#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" \, T/ y+ {7 ]; i( F/ m5 T$ F+ y
rename("DialogBox", "ExcelDialogBox") \% H- H  x$ i% f( g* i9 w
rename("RGB", "ExcelRGB") \
1 m4 B2 l' W  }$ j$ `4 S; mrename("CopyFile", "ExcelCopyFile") \
0 q: t4 [) A0 e' T9 ~rename("ReplaceText", "ExcelReplaceText") \, _$ {+ f8 r2 ]
no_auto_exclude8 o( q" T6 x6 p% r
Using namespace Excel;
, c. r' v, _6 H! q  
9 a( \/ f* X4 t5 X/ m% A+ O编译程序后,会在DebUG或Release目录下生成三个文件mso.tlh、vbe6ext.tlh和excel.tlh。通过打开文件可知,该三个文件的命名空间分别是Office、VBIDE和Excel。导入了Excel的整个类型库后,就可以使用Excel中的所有类型了。) o+ X( o. j& F8 r4 C
  : q, C9 \6 {4 [) T- y' e/ J
4、操作Excel步骤
, n( R7 M, s2 a3 Q! `# y+ K操作Excel的主要步骤如下:+ F  G* Y5 ^9 k/ K3 z
(1)创建一个Excel应用程序。8 G6 R( y6 s: H& q! S/ l) _5 s
(2)得到Workbook的容器。# q! x0 f" c# f7 Z# y! |
(3)打开一个Workbook或者创建一个Workbook。
# Y) O0 Z9 u* C(4)得到Workbook中的Worksheet的容器。% s9 M% [2 W1 C1 _' k
(5)打开一个Worksheet或者创建一个WorkSheet。0 ^- i" F5 Q4 _* U; z8 q
(6)通过Range对WorkSheet中的单元格进行读写操作。
; Z4 O& S2 C' O+ \2 j/ E% X(7)保存Excel。
( t9 v. B" v- I5 R( I(8)释放资源。
; K7 G  Y- w1 e  
6 L( q+ b1 X. z5、批量处理Excel表格
' U7 s) n+ T& @! S' DVC通过OLE/COM操作Excel,是通过进程间的组件技术。因此,每次读写Excel中的单元格时,都要进行进程间的切换。当数据量大,如果一个单元格一个单元格的读取,主要的时间都花费在进程切换中。因此读取多个单元格,将可有效的提高程序的运行效率。: P- e# X, @9 c" r) M
对多个单元格的读写操作可以通过CRange中以下两个成员函数来完成。
( M0 _: I& w/ R& ?& NVARIANT get_Value2();4 j9 w( v) B+ ?5 G0 z
void put_Value2(VARIANT& newValue);+ H9 X% e5 J' U- J' b
其中,输入参数newValue只要输入一个二维数组,即可实现向Excel中一次写入多个单元格的值。
+ @. j" y# m! `4 {6 Y# ]5 P其中,VARIANT中实现二维数据的方法可参考
1 x0 t* i! I1 j2 Uhttp://www.cnblogs.com/xianyunhe/archive/2011/09/13/2174703.html
6 n8 r% A" w7 g, y) b9 g当然,在对CRange类进行操作之前,要设置CRange类对应的单元格。
! I* d0 X( G- `! |7 |* t  ) F' Y( M; \+ D5 g, j. c
6、Excel表格的保存0 Y" R# W4 s( ^. W1 I: ~
(1)如果要保存打开的工作簿,使用CWorkbook类的Save函数就可以保存工作簿,原文件将被覆盖。; E1 o- p) z% V
(2)如果是新创建的工作簿,或者是要另存为,可使用CWorkbook类的SaveAs函数。: i5 v# C5 |5 X7 @: D) o
SaveAs的参数比较多。其中,第1个参数是设置要保存文件的路径;第2个参数是设置文件的格式,可在MSDN中查看枚举类型XlFileFormat来了解Excel的文件格式。经过测试,在本文所用的测试环境中,Excel2003的文件格式是xlExcel8,Excel2007的文件格式是xlExcel4。8 |" Y& H" t" g$ d3 i/ R5 }
  / O2 A. s- h2 w9 K
7、获取当前Excel的版本7 ]: O' x2 T$ H2 R, e7 `# l
可以通过CApplication的get_Version函数来获得Excel的版本,其中,Excel2007的主版本号是12,Excel2003的主版本号是11。
! G- h  X$ ^( V" L* `4 q  
2 h1 t6 I5 ]6 @: J8、示例源代码  `# U5 H6 V2 Q6 n* u
主要代码如下:
! Q5 `6 _% I3 c! |  $ [, J( c* _$ h8 F
- D: w* Z  l$ X2 @" `$ f2 U! _

6 N! {+ j" R" c0 C+ e    m_LisTCtrl.SetExtendedStyle(LVS_REPORT | LVS_EX_FULLROWSELECT);/ I5 `+ G. M' k& ?

2 ~8 n. a6 x+ D/ \, v. q( y    CApplication ExcelApp;
0 A  L  F, e- u    CWorkbooks books;
& ?* u  A7 ~6 T( L) S2 e    CWorkbook book;8 Y' S3 D4 s% e/ L  R6 @
    CWorksheets sheets;* M7 X- ]  `/ D$ J4 `! Z4 j8 {* {8 B
    CWorksheet sheet;5 W' k9 o% k: M" N. I
    CRange range;
( P0 ~3 r5 z' D0 }  d+ O    LPDISPATCH lpDisp = NULL;
3 `% t+ Z) r0 R5 X
- F( O7 b' K, H$ r4 @    //创建Excel 服务器(启动Excel)
: E( x2 W3 ~2 `, {' F# _$ A    if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL))
! c. X/ i( v( k    {/ ^* [8 G4 y$ N% c" o; T; g
        AfxMessageBox(_T("启动Excel服务器失败!"));' i+ A' x+ o+ ~5 T8 r
        return -1;) b, d. c" |' O$ q! _- k
    }
, j& o, y& E; j* d, w# a$ K3 u  i+ K) @  G
    /*判断当前Excel的版本*/2 h/ p* d# [" Q4 t
    CString strExcelVersion = ExcelApp.get_Version();
3 p& d: k8 \; T    int iStart = 0;6 o! ~* ^  h/ c) f. m) Y8 `1 H
    strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);4 W+ y" f' ?' E3 E/ |" g& _! g
    if (_T("11") == strExcelVersion)7 a, ]6 R# Z) ?/ u' Z& n: p& Q
    {& G+ y6 G5 C) e
        AfxMessageBox(_T("当前Excel的版本是2003。"));
  G, \$ Q$ s) i% A% T3 K% N8 q    }3 n3 {# ~. Q. O% Q! z0 x
    else if (_T("12") == strExcelVersion)& i/ a" Y0 v; ~" A
    {
2 x& x% f# F) e- e1 N: L' R$ O% I* T3 p        AfxMessageBox(_T("当前Excel的版本是2007。"));
- u  D4 J. ~/ J6 C% @- r    }2 k* p2 x( U" I5 z5 M
    else: k  W$ @4 [0 {/ m3 S6 T5 q
    {
& p" Z" W7 e) C9 _! Z( R        AfxMessageBox(_T("当前Excel的版本是其他版本。"));$ N9 B. a7 Q$ A3 W
    }1 E" x% e1 p1 F; u
% s7 E) V% O; I/ j( b
    ExcelApp.put_Visible(TRUE);6 h  X' w7 x) N' P8 }0 H3 v
    ExcelApp.put_UserControl(FALSE);+ T4 l% V( ?# e$ t: i6 {8 t: C

, S/ J& \8 j/ ~, ^, ^    /*得到工作簿容器*// B2 b9 G: C: b8 t, |5 T- d6 Z
    books.AttachDispatch(ExcelApp.get_Workbooks());) d, Q4 e% T6 R7 F5 c7 \; r
6 ?% S) u1 ?4 \7 Q' w
    /*打开一个工作簿,如不存在,则新增一个工作簿*/8 Y- b) |4 z; ^  D3 a
    CString strBookPath = _T("C:\\tmp.xls");  K/ u9 ^  D" n7 `! @" J" I
    try: `& o' Q/ j4 N  }
    {
: C7 ^+ f1 |, M        /*打开一个工作簿*/
2 z$ D5 H0 `! z- H% ~' f        lpDisp = books.Open(strBookPath,
/ l/ K+ h6 h2 O5 c) C" J: ?; M            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,( a: r- |+ h# h( n% n! ~
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
: b4 A2 K/ J" b9 p            vtMissing, vtMissing, vtMissing, vtMissing);+ c8 j5 f6 B& X4 p& A  u
        book.AttachDispatch(lpDisp);( ?& f% X! m+ e; K
    }9 A8 n" `1 Y8 d1 [
    catch(...); v; r1 O: `8 |# E
    {
4 H, d+ U" l" v/ ~3 `+ M$ B9 ^" `* T* n+ r        /*增加一个新的工作簿*/: u8 ]' K; J) S# v  z6 G: _
        lpDisp = books.Add(vtMissing);, B4 F  S& p: H" ]  h
        book.AttachDispatch(lpDisp);
) t- k1 Q$ o1 \, y& L0 z: Q7 m' ?" \5 ^    }
( j" B7 ?, p/ R# Y1 h- C: x     . S( C( ], \# w5 A. v

. j# C- F( G0 s. k0 o    /*得到工作簿中的Sheet的容器*/# t6 M* A; B! m0 T! B/ g
    sheets.AttachDispatch(book.get_Sheets());0 Z& H9 ?7 X% R; s7 N# _  b

/ r% z+ l" \$ r1 I, q    /*打开一个Sheet,如不存在,就新增一个Sheet*/
& l& j) H- y+ e/ |! ?    CString strSheetName = _T("NewSheet");6 q, t" b1 g  C) I8 e. f
    try( [7 l, y# I& j2 X5 U
    {
  W! o4 r& s$ r& x        /*打开一个已有的Sheet*/2 X9 `8 w7 N; j( _/ B
        lpDisp = sheets.get_Item(_variant_t(strSheetName));# }5 f- J% |" z: ~3 Z) p, p# m
        sheet.AttachDispatch(lpDisp);
& m; u/ U$ R% A+ c- \) c    }
+ a8 v  ^3 v2 {1 C( j7 C    catch(...)  P  ^! X% A# |
    {1 a! N" J) l3 v
        /*创建一个新的Sheet*/
0 c9 J3 {0 H, a; Q        lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);0 T$ r2 P7 D+ d# z
        sheet.AttachDispatch(lpDisp);' x- r) V6 U! w4 t2 P2 E4 T' @
        sheet.put_Name(strSheetName);7 O0 D( `; K' M, w$ A( _
    }
- E5 y$ @/ ~- Z
7 V5 Y4 h8 v4 h. U& E    system("pause");
8 e4 P, x9 u  r- _6 \" z3 j. p/ T3 l9 ~' S1 T' H
    /*向Sheet中写入多个单元格,规模为10*10 */
; B/ v0 S3 d1 i& W# k0 ?) W    lpDisp = sheet.get_Range(_variant_t("A1"), _variant_t("J10"));
- o3 r! a) v7 K2 }5 p* ]    range.AttachDispatch(lpDisp);
% i* E, [) H, M% I8 c3 z; a" O* g. Z8 [1 V4 ^7 X
    VARTYPE vt = VT_I4; /*数组元素的类型,long*/
7 H3 ^: T6 n9 u* c2 F  d0 I    SAFEARRAYBOUND sabWrite[2]; /*用于定义数组的维数和下标的起始值*/
6 E3 q; U" y7 C/ A. ?& I8 _% s2 ^    sabWrite[0].cElements = 10;
* U) J2 f1 g: m% Q4 z. }: i    sabWrite[0].lLbound = 0;3 s, I  R6 E& e9 }, e; [  {
    sabWrite[1].cElements = 10;7 V6 K! K$ [7 Q+ k) S* f0 h
    sabWrite[1].lLbound = 0;
! E4 z0 K" `9 ?/ U
5 o9 Y% B2 |( r( x( J0 w    COleSafeArray olesaWrite;* S- w  P- D7 u
    olesaWrite.Create(vt, sizeof(sabWrite)/sizeof(SAFEARRAYBOUND), sabWrite);
  F. U6 ?% `6 z
$ U! v+ v4 W4 j$ M! O% S' M    /*通过指向数组的指针来对二维数组的元素进行间接赋值*/
) h( Q+ e% W9 O8 G, i$ Y    long (*pArray)[2] = NULL;0 ]; v9 q. g% i  a5 V, W# f% y
    olesaWrite.AccessData((void **)&pArray);4 q% k' W% G# d! y& i5 W+ ~
    memset(pArray, 0, sabWrite[0].cElements * sabWrite[1].cElements * sizeof(long));
& j( ?3 R* Z2 k$ w: J! K' p- T3 x) @
! t: B9 F# N4 ]0 B    /*释放指向数组的指针*/
1 T" g0 T$ L% J3 K3 R0 c    olesaWrite.UnaccessData();
4 E% G2 C' T2 ]9 e, J. ~    pArray = NULL;
4 J7 V4 k0 F( x0 ]
! J" g9 e; Q, @% X' c0 Z2 ]" v9 N    /*对二维数组的元素进行逐个赋值*/4 z  N8 C1 ?" I! c% ?+ O
    long index[2] = {0, 0};" ?. k+ g( [6 J) r
    long lFirstLBound = 0;
) R8 D# t& o9 R( e/ ]& K    long lFirstUBound = 0;& d8 C1 q7 d. _/ W8 {
    long lSecondLBound = 0;. H2 J1 l3 z( q/ E
    long lSecondUBound = 0;! X, v. ?: U! W
    olesaWrite.GetLBound(1, &lFirstLBound);, M1 l# e3 P8 M7 n2 E) d
    olesaWrite.GetUBound(1, &lFirstUBound);7 d9 T8 C+ f) K. x( T9 _
    olesaWrite.GetLBound(2, &lSecondLBound);
$ O7 N. e# d: f! z" m    olesaWrite.GetUBound(2, &lSecondUBound);+ K; B, L0 c3 y/ @4 T
    for (long i = lFirstLBound; i <= lFirstUBound; i++)3 j$ U2 n- Z) K6 m. |1 B. N1 H
    {2 c" x$ K+ K* Q$ Q5 Q
        index[0] = i;# U6 |8 n+ j1 a& w6 o3 M! G
        for (long j = lSecondLBound; j <= lSecondUBound; j++), T: m( k. v4 X5 y7 V
        {8 |# x& @9 W) X" |9 }% v+ S9 U
            index[1] = j;1 b( @5 o, Z+ V
            long lElement = i * sabWrite[1].cElements + j; ' D; b4 L3 U+ `. P: h2 a4 w% E! g
            olesaWrite.PutElement(index, &lElement);0 K& W/ L( \5 l: ~8 @" X7 {% ]
        }
6 w8 G. P) O) F4 F8 b( W    }
4 H* o# m6 c4 \2 o5 V4 k) R' E% D: Z+ U6 S) l& S1 n% u
    /*把ColesaWritefeArray变量转换为VARIANT,并写入到Excel表格中*/2 p) p# m  W7 m9 ?3 ^
    VARIANT varWrite = (VARIANT)olesaWrite;/ p! F1 h' ~$ r
    range.put_Value2(varWrite);8 ~0 V. M! ]6 O9 {, ~! F
" ^. X0 h9 X! R# C7 R3 T
    system("pause");
! d$ Q( b. t7 F' _/ W3 b& E
7 m  s& o9 X# P" |8 W5 U    /*根据文件的后缀名选择保存文件的格式*/! n0 Q+ V: w; N" y
     CString strSaveAsName = _T("C:\\new.xlsx");
8 x% U8 C2 `! h0 E+ K    CString strSuffix = strSaveAsName.Mid(strSaveAsName.ReverseFind(_T('.')));
1 E! W' w( ~1 K+ T/ b1 P' c! ^    XlFileFormat NewFileFormat = xlOpeNXMLWorkbook;
1 A4 c1 k3 u2 m: _+ c    if (0 == strSuffix.CompareNoCase(_T(".xls")))
. x$ {4 T6 F4 V) ?; }    {# P- R) T& K; G6 ?- o7 |% P
        NewFileFormat = xlExcel8;$ u3 a5 e5 g( T# c
    }
0 G" L4 d7 J) F* H4 f. {0 B    book.SaveAs(_variant_t(strSaveAsName), _variant_t((long)NewFileFormat), vtMissing, vtMissing, vtMissing, $ F) |# ~" m5 ?: m1 p
        vtMissing, 0, vtMissing, vtMissing, vtMissing,
9 |  b( J. K7 w+ h! D+ i        vtMissing, vtMissing);
8 S( k8 v+ K0 z! A8 ^3 H. k3 l9 o. H) {/ A2 }# B
    system("pause");& V5 E) T; f3 N$ O( Z

6 V3 S2 n; i' w6 q( B' D/ b    /*读取Excel表中的多个单元格的值,在listctrl中显示*/
4 M7 q: p, M7 }6 k# e% X    VARIANT varRead = range.get_Value2();1 Z* [' V1 p8 r
    COleSafeArray olesaRead(varRead);* T, B3 a* Z4 j; _
' s0 o% V; ?1 H4 H1 I* X9 }
    VARIANT varItem;- S- n8 i& N2 I/ ^
    CString strItem;
' C* N; F- o+ R) I0 H    lFirstLBound = 0;
* k* f1 p  F* {4 g. S% b    lFirstUBound = 0;
- W8 `1 b7 j- D1 b2 ~    lSecondLBound = 0;
  t: z, a3 n/ \; s9 D    lSecondUBound = 0;
. ^2 T6 A4 N3 k4 Q    olesaRead.GetLBound(1, &lFirstLBound);& c5 Q9 f- m# q$ S- R0 j6 }+ }
    olesaRead.GetUBound(1, &lFirstUBound);
: o5 p+ i6 C( z1 B* S    olesaRead.GetLBound(2, &lSecondLBound);
2 W/ I- a! @9 x  K. u; f    olesaRead.GetUBound(2, &lSecondUBound);7 ]) c% ]* J* q0 f
    memset(index, 0, 2 * sizeof(long));
/ `. [5 @% Q5 I3 [" l    m_ListCtrl.InsertColumn(0, _T(""), 0, 100);
& t# Z( z7 A& E% c3 r) O. j    for (long j = lSecondLBound; j<= lSecondUBound; j++)
" s5 W% r" |7 q  U& n$ |1 r    {
3 U0 U% z& y/ L5 ?6 m        CString strColName = _T("");
5 \2 D, q) [: n$ i1 m        strColName.Format(_T("%d"), j);9 A( c& d. V5 e: K" y
        m_ListCtrl.InsertColumn(j, strColName, 0, 100);
! [; c: p7 b5 L, w    }0 w7 z/ n2 @2 X, M2 v0 T0 g
    for (long i = lFirstLBound; i <= lFirstUBound; i++)
' `: p7 m+ c5 E" s; O    {
  i9 H# q+ [1 l: @$ s4 s4 p( E        CString strRowName = _T("");
9 R0 ?7 H4 P5 N8 B1 A        strRowName.Format(_T("%d"), i);
! e# a( T' x6 S6 u9 H1 \        m_ListCtrl.InsertItem(i-1, strRowName);
/ P: j- G+ W* E  ]6 _1 o( T! `- |) |( J/ c- v8 w( w: a7 g
        index[0] = i;
4 D. V  B5 Y  d4 B  ^7 ]! U6 y        for (long j = lSecondLBound; j <= lSecondUBound; j++)' X5 e% ^2 Y8 ]' o- a! z0 T
        {9 Z4 L! g  y6 C# [' ]
            index[1] = j;
. G4 ]# n! ]+ Y( L) k9 ?            olesaRead.GetElement(index, &varItem);
: r/ ?  n( V' `* `  T
# y+ X0 B. r  h% V            switch (varItem.vt)  P6 P: b0 |% x; r( d% e. R" u; C
            {
1 T0 v; f5 K+ C$ g            case VT_R8:. R$ O5 J! s4 o- ^! o
                {
7 \& w2 ?& ]1 y* |' K, R                    strItem.Format(_T("%d"), (int)varItem.dblVal);8 n* m4 K! J# l1 x
                }
! D1 K" R8 i. [5 S
5 \0 P; x7 O) V2 x# Y            case VT_BSTR:0 r; h7 [) L+ W9 L
                {" m) d. M; f, ^, r) c: A: g) H# E  ?
                    strItem = varItem.bstrVal;6 F2 {9 |. M1 d
                }
- ?8 ~2 G8 r& m1 @
2 S# V9 R- I! q$ K            case VT_I4:0 j1 ~2 |& \- M) w  i+ g0 C8 \
                {7 n% e& A7 ?6 F0 e# _8 b
                    strItem.Format(_T("%ld"), (int)varItem.lVal);
4 U2 v: X$ n/ c$ P1 t                }! Z+ u9 E4 M+ w/ F) b. q+ H  ]

2 J- o1 i; f0 k5 l% B+ _            default:
" N  t% N  [- p3 C4 c7 s                {; s+ m0 M! l2 N% h

- G- m, t, R" h( \. E( o  n- g                }- q: e& G) z- Z7 r0 }1 [
            }8 a* K0 f7 B4 Z& R; @' k4 i/ \

2 F; w9 |0 Y9 k; v            m_ListCtrl.SetItemText(i-1, j, strItem);
& G1 R/ O8 V- S( i        }3 x5 ^; N+ R# G  m- Y
    }, N( H% K4 t# N$ I
: d( `2 U, |# t3 P7 {  Q: q
: S$ X. `( X0 e* }7 x3 q8 Y! p6 u
9 F8 j% W  T" C) n1 e/ D" D
    /*释放资源*/( e  N: [! ~; c+ \# U' F
    sheet.ReleaseDispatch();
6 G% k/ B/ [, _# T+ @    sheets.ReleaseDispatch();/ O9 u4 H! F; y7 O5 k4 [( N; o2 j
    book.ReleaseDispatch();7 G7 e" V* d9 g5 j. U- j1 P! q
    books.ReleaseDispatch();
7 i; |8 j# U. G$ r    ExcelApp.Quit();; o" R& v7 @. v! {: o4 ?3 S
    ExcelApp.ReleaseDispatch();
+ p7 q5 ^+ j1 Z* H7 ?; v6 a" ~$ g1 ~0 T: S; S# @' q; p7 h
上海点团信息科技有限公司,承接UG NX,CATIA,CREO,Solidworks 等CAx软件,Teamcenter,3D Experience等PLM软件,工业4.0数字化软件的实施\二次开发\培训相关业务,详情QQ 939801026 Tel 18301858168 网址 www.diantuankj.com/ doTeam.tech
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 注册

返回列表 本版积分规则

  • 发布新帖

  • 在线客服

  • 微信

  • 客户端

  • 返回顶部

  • x
    温馨提示

    本网站(plmhome.com)为PLM之家工业软件学习官网站

    展示的视频材料全部免费,需要高清和特殊技术支持请联系 QQ: 939801026

    PLM之家NX CAM二次开发专题模块培训报名开始啦

    我知道了