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 6305 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表格的操作。" u' m# x6 t9 Z2 k/ J
  * ^  W9 \! ?, `* H8 y
本文源码的应用环境说明:1 q, a( \: V' T' ^4 z: Z- W9 g; C
Windows XP SP3
7 V5 |9 r- N4 c+ ]/ qMicrosoft Visual Studio 2010' Y# z3 v' n& ~& ~8 {
Microsoft Office Excel 20070 a- B+ P/ b6 U; P( O
  7 L4 `6 v% H! u' \, P2 @+ A
1、添加OLE/COM支持。6 n4 m! n! B; I/ P$ L2 A7 A+ _
首先,应用程序必须添加对OLE/COM的支持,才能导入OLE/COM组件。" D1 v" K3 l/ G2 u  l* |% r; b
本文使用的是MFC对话框程序,在创建工程的向导中选中Automation选项即可为程序自动添加相应的头文件和OLE库初始化代码。
$ n( ~$ d7 F6 y4 @3 v6 C( K9 x$ A通过查看源代码,可以知道在stdafx.h的头文件中,添加了OLE/COM很多类所需添加的头文件。: ]9 X$ t7 a* T5 Y0 ~# Q. q0 `2 v: |
#include <afxdisp.h>        // MFC 自动化类5 X2 y! F% [# M0 E! l  _
同时,在应用程序类的InitInstance函数中,添加了OLE/COM的初始化代码,如下所示:, W/ L! g4 y& h$ @% J- q0 A6 n+ k) K
// 初始化 OLE 库
' K* o! ?! a' kif (!AfxOleInit())+ w: E. h* a4 M" a; N& _( N
{
2 i- }2 r+ ?- N$ y! R9 Y3 ]AfxMessageBox(IDP_OLE_INIT_FAILED);
- d8 @1 t! O  ^# T( {# M7 P6 h; y) Creturn FALSE;4 e; F' ]: |5 p/ F& X) D
}3 G+ s# ]' e# k# ^
  
6 ?5 F& A$ k. J8 v5 p, m, ]2、导入并封装Excel中的接口
6 h' U8 o; T7 p( E' tExcel作为OLE/COM库插件,定义好了各类交互的接口,这些接口是跨语言的接口。VC可以通过导入这些接口,并通过接口来对Excel的操作。
! w/ L( F. S, Z. x3 ]4 J由于本文只关心对Excel表格中的数据的读取,主要关注几个_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range等几个接口。Excel的各类接口的属性、方法可以通过MSDN的Office Development进行查询。
7 c$ ]! m% R6 o4 ]& ~! x) K* M  _VS2010导入OLE/COM组件的接口的步骤为:Project->Class Wizard->Add Class->MFC Class From TypeLib,先选择要导入的组件所在的路径,即Excel.exe所在的路径,然后再选择+ a" ~, @# }: n, t6 b
要导入的Excel类型库中的接口。; a4 b& }$ Z$ t9 x$ @- D
在完成接口导入后,VS2010将自动为导入的接口创建相应的实现类,用于对接口属性和方法的实现。由于标准的C++没有属性访问器,只能添加一个两个存取函数来实现对属性的访问,通过在属性名称前加上get_和put_前缀分别实现对属性的读写操作。即,由VC自动完成C++类对接口的封装。
) N: @. q% s. @  
. t+ d( a& a  f! v  F: p本文所导入的接口对应的类和头文件的说明如下所示:
. c, V1 h. l% b8 J  
; ^2 s( J: g7 @; v3 v  ^$ H" kExcel接口* C2 v' r) C1 P2 q
导入类# N% L  R6 V. n! H6 t  m# }' o4 `
头文件- n0 ~# v6 c' r3 ^7 q- I4 [
说明) _5 O: e$ P* `+ m" T6 q
_Application8 ~. g( D5 m8 ^. X5 H1 F4 w
CApplicaton# {0 Q# S/ ^8 p4 I( d! S3 x
Application.h
, ^+ e1 P. z0 X+ Z  vExcel应用程序。
4 p6 P4 o0 R. D' |( hWorkbooks' d# w6 n0 l! D6 o
CWorkbooks
% w) h  U7 Y% M0 R5 J* JWorkbooks.h
9 E# U1 P- j9 G( ~工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。
" b1 X! r* Q  S- {" K_Workbook' S; g! C" F, g) m% C" k
CWorkbook% l) z1 x" X+ L4 C$ L/ ^5 i6 Z
Workbook.h% v. I$ v6 v1 ], ~1 @
单个工作簿。
+ P( b) W5 x2 K6 C0 U- O+ lWorksheets7 N  `; o* i# f, c
CWorksheets" A% K" D) q4 [
Worksheets.h$ V" P% r; k, ^, k
单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。
" j5 d* L8 Z7 T4 }1 p2 E( N3 U_Worksheet: I' l9 ^( ~; V8 ]
CWorksheet
$ ^3 ]- s& ?  U6 B2 o" j) U7 |% }Worksheet.h
- h# _4 F! T* Q/ U6 T6 u1 S单个Sheet表格。
& F: ~) ^( y; \/ y) Y; JRange+ V% K' P+ H7 O: C2 J. B
CRange! e/ m8 t6 ^5 B6 Q% ]$ q8 k
Range.h* w* H; r. Z' N) _% W! ]# B
一定数量的单元格,可对单元格进行单个或多个单元格进行操作。
" f' P; O; s, w2 d$ N  4 S% z& B- O) d& X6 |" u( w
3、导入Excel的整个类型库
( W0 W! g# L' w8 u+ ^: Z, ]接口对应类只是对接口的属性和方法进行了封装,而Excel中的数据类型,如枚举类型却并为并不能使用,因此,为了更方便的操作Excel,还需要导入Excel的数据类型。
4 s* J9 r3 n( ^9 g  X7 z通过查看导入接口对应的头文件可以发现,在所有导入接口的头文件中,都会有这么行:
0 l. j! C, w9 G+ @1 O% G. C: e#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace
' w- d% ]( t; ]6 t1 G; }  ~这行代码的作用是导入Excel整个类型库到工程中。
9 V& H0 G3 S8 _9 f. N( ~由VS2010自动产生的导入代码存在以下几个问题:
8 {, R- S( a! r5 G(1)如果导入了多个接口,每个头文件都会把类型库导入一次,如果引用多个头文件,会导致类型库重复导入。
2 a* u8 j9 D2 H( X$ p(2)Excel类型库中有些类型会跟MFC类库的某些类型冲突。* F% U0 M9 Z% w* P+ M: R0 ?2 [
(3)Excel类型库的某些类型跟其他Office和VB的某些库相关,如果不导入相关库,将导致这些类型无法使用。。
7 x% a' A8 M3 z以上三点问题的解决方法如下:
3 `6 `5 p: [) U5 P5 N( t(1)仅在_Application接口对应头文件中导入Excel类型库。
, S" U5 ?7 j) V: `3 ^  i5 \* Z(2)对冲突的类型进行重命名。
$ R- n4 N% j  I/ h(3)在导入Excel类型库之前,先导入Office和VB的相关库。( F' r! u9 n/ F7 [
更改后的导入类型库的代码如下:
. ~4 |/ c, }4 u6 M7 e4 t  3 }4 v1 F: N; t! p- c" i: v
/*导入Office的类型库*/
8 R9 |  z' \0 {) g4 Q#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL" \
. s3 ?0 y7 I- Frename("RGB", "MSORGB") \5 F0 k4 F' q0 K" |( O, Y% v- A
rename("DocumentProperties", "MSODocumentProperties")
; W; }  K" t& k& k8 @' Nusing namespace Office;! ^" @- |1 M) m- Y
  9 A: w8 z: [6 x  O1 U
/*导入VB的类型库*/$ J9 [) d: D. m# @
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"
2 B4 S) R, `+ R7 M" Nusing namespace VBIDE;. M  F: j/ s+ P, n- M
  
% `+ b0 o& x% D% X2 l/*导入Excel的类型库*/4 W8 S9 D& |0 }
#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" \: _" p* F+ @' K1 |: j: j/ Q
rename("DialogBox", "ExcelDialogBox") \
& P; t  Z4 `  ^1 ^1 \6 O/ U! mrename("RGB", "ExcelRGB") \  q1 [1 W/ G( ]( |" s/ @3 G( z
rename("CopyFile", "ExcelCopyFile") \
; X0 l. T+ ~9 Prename("ReplaceText", "ExcelReplaceText") \) w! Y7 g3 A* i+ t/ i
no_auto_exclude. I( g) k( \- \1 X0 k
Using namespace Excel;' x; T7 E. d; \6 j+ P6 s, F
  
5 k, c! ]& [  T* C* ]编译程序后,会在DebUG或Release目录下生成三个文件mso.tlh、vbe6ext.tlh和excel.tlh。通过打开文件可知,该三个文件的命名空间分别是Office、VBIDE和Excel。导入了Excel的整个类型库后,就可以使用Excel中的所有类型了。  {! u  n8 R5 m
  ' [8 _, Z3 l) A* y6 h- _3 ?
4、操作Excel步骤8 O4 R0 U1 p  y/ W2 c: z* a
操作Excel的主要步骤如下:1 t+ i( ]( i/ S2 f5 b$ V8 ~$ H
(1)创建一个Excel应用程序。
0 Y7 U- v$ X5 G' V$ x: X- q(2)得到Workbook的容器。
/ q; q) N* g1 l(3)打开一个Workbook或者创建一个Workbook。
6 I6 R# W2 M9 I( o5 v9 _. I, }(4)得到Workbook中的Worksheet的容器。" Z4 |8 ~. u9 J1 R
(5)打开一个Worksheet或者创建一个WorkSheet。/ K( d' P! e7 E& h
(6)通过Range对WorkSheet中的单元格进行读写操作。
$ r, r; C$ h5 B* w6 o6 w- J' Y) \; k(7)保存Excel。, d+ U0 y6 ?/ }" s. Q
(8)释放资源。* |- n2 V! c$ Y& n7 ^& X6 L; h$ `: v: \
  1 f" W5 r) I) _; a8 z1 p
5、批量处理Excel表格7 ?; l/ ?" ^- t5 D7 j6 z1 J% b
VC通过OLE/COM操作Excel,是通过进程间的组件技术。因此,每次读写Excel中的单元格时,都要进行进程间的切换。当数据量大,如果一个单元格一个单元格的读取,主要的时间都花费在进程切换中。因此读取多个单元格,将可有效的提高程序的运行效率。, }: G4 L' f9 _$ D; C& A
对多个单元格的读写操作可以通过CRange中以下两个成员函数来完成。
* ]9 ~- g' g  H7 RVARIANT get_Value2();& ~. _5 L  Q, q  c# Y2 J5 I  A. Z* c
void put_Value2(VARIANT& newValue);
& `# h" P6 N  V* E9 s& d其中,输入参数newValue只要输入一个二维数组,即可实现向Excel中一次写入多个单元格的值。
; L% d" k2 W9 `- R其中,VARIANT中实现二维数据的方法可参考
8 r9 u& }' W9 d) W% Y* rhttp://www.cnblogs.com/xianyunhe/archive/2011/09/13/2174703.html9 S/ j! t$ q3 X4 u9 C
当然,在对CRange类进行操作之前,要设置CRange类对应的单元格。
! U& H1 Q+ H) J, H  `" w2 e* C2 a  
0 z4 k+ t/ X! _: U6、Excel表格的保存
( u; n0 z# B4 k5 @$ }0 W7 |(1)如果要保存打开的工作簿,使用CWorkbook类的Save函数就可以保存工作簿,原文件将被覆盖。
  q5 H- s; ?: D9 K- U$ f(2)如果是新创建的工作簿,或者是要另存为,可使用CWorkbook类的SaveAs函数。$ M4 u2 k, s0 V7 b
SaveAs的参数比较多。其中,第1个参数是设置要保存文件的路径;第2个参数是设置文件的格式,可在MSDN中查看枚举类型XlFileFormat来了解Excel的文件格式。经过测试,在本文所用的测试环境中,Excel2003的文件格式是xlExcel8,Excel2007的文件格式是xlExcel4。
- ?1 ^& n, T" G/ W5 E) }  7 g6 a. Y0 C9 x7 _7 i
7、获取当前Excel的版本
4 y2 S" l2 Y2 N可以通过CApplication的get_Version函数来获得Excel的版本,其中,Excel2007的主版本号是12,Excel2003的主版本号是11。$ R$ u) b% D. }* ~% X
  
# _+ y! L( b4 i3 l- P8、示例源代码# {9 N) C2 n4 U3 o+ {' U
主要代码如下:: P& i& `$ @7 O; N& M( Z
  : p; W0 a7 P; t. D7 g

3 @  Z% T: s/ _2 k# Y3 l6 x" S# s/ c/ @( v
    m_LisTCtrl.SetExtendedStyle(LVS_REPORT | LVS_EX_FULLROWSELECT);
* Q% Y! N/ @4 }& j" v0 K& F& b( K& j; V3 p0 s# B
    CApplication ExcelApp;- P' e6 x$ r7 e  J8 H
    CWorkbooks books;7 H' ~8 {' b9 B7 R* Z7 A/ W8 i
    CWorkbook book;9 p+ P* [8 C4 Q5 N7 r
    CWorksheets sheets;$ f- `* r# b3 \* r1 |" H/ K3 v
    CWorksheet sheet;5 m2 ^) W; L4 z; O8 ?  Q3 S
    CRange range;
( Y: P' F( \: w( m) X: ^    LPDISPATCH lpDisp = NULL;
" X( ~. J) o) L% T+ H% y4 O  P' J7 j9 H9 B& l$ B" ?: \
    //创建Excel 服务器(启动Excel)( l5 {1 H' U' O; @6 X3 ^* ^
    if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL))
/ b3 x( v8 g, o  [% ?    {* H. A; V: }7 r' N9 w# F
        AfxMessageBox(_T("启动Excel服务器失败!"));
9 \8 d5 f/ E: g7 A& U; p9 J2 c        return -1;' H, D* g9 Y0 o  C! K
    }
7 F) h, V7 w- s; C
6 @" A7 z: t# H    /*判断当前Excel的版本*/( u$ A# K2 H$ k- h9 a( h: B; @
    CString strExcelVersion = ExcelApp.get_Version();
* @' z* G' N, `8 G  c    int iStart = 0;
! `$ Z& R8 g) q# L) p# e    strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);
4 I- R6 @, K( w; E2 b' t: h    if (_T("11") == strExcelVersion)3 d' c/ }% l$ M# a/ ?+ u0 q: y' ^3 U
    {5 t! b8 D# _: F/ L0 {
        AfxMessageBox(_T("当前Excel的版本是2003。"));  n0 @' z/ _4 K. N7 K% h! c, Y+ K
    }
9 G7 e4 q; ?! |- r6 G2 B! u    else if (_T("12") == strExcelVersion)$ G# X, r1 m' T
    {/ |- P- \8 A% U+ a! X( F
        AfxMessageBox(_T("当前Excel的版本是2007。"));2 t1 L! g  q8 ]2 L
    }9 o3 q! j# t1 T* B: ?7 q. x
    else6 {; J- h4 X- Y+ e* Z# X
    {
0 l( _, q* {* Y- Z        AfxMessageBox(_T("当前Excel的版本是其他版本。"));
9 H5 e2 V) e. @3 H( I. q& |    }: d$ O1 R6 I1 Q$ R' x

+ n. t! }  `( x* d/ k$ u    ExcelApp.put_Visible(TRUE);- R& m, a: A9 u) W
    ExcelApp.put_UserControl(FALSE);/ h2 C) s. x* N) F: D4 M

& `2 A5 y) G- `4 w+ h, L    /*得到工作簿容器*/
: r+ k' @1 w' |. B. p0 C    books.AttachDispatch(ExcelApp.get_Workbooks());. A) M" a4 O! k" }+ U! _& E% p
5 W3 ^) T7 M; X, c8 T9 f/ g
    /*打开一个工作簿,如不存在,则新增一个工作簿*/
( s3 }( B% J# c  U6 L3 n  P- p! W: E    CString strBookPath = _T("C:\\tmp.xls");" Y( ?6 m: _7 G/ ?/ e1 ~
    try
1 T) W3 ~+ y5 |' r    {
) _% ^9 t% K; {7 P1 o; j, o  J4 `0 E        /*打开一个工作簿*/% Y. ^: K7 T( q: A& T. X
        lpDisp = books.Open(strBookPath, : o" h2 B1 ~" J8 ~. Z! T! t
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
' H3 Q8 M: J( p6 X  ^& p7 l7 K            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
/ F* w4 X) z7 M$ n' K2 M7 {            vtMissing, vtMissing, vtMissing, vtMissing);
/ S% l1 N4 v. i# k' m        book.AttachDispatch(lpDisp);
  g; Y" P9 @  Z% A' ~. n    }3 C5 }6 ]! U0 W- R2 V' u. U
    catch(...)
1 A) Z$ |1 W3 O: d4 a: f$ f6 G" q    {
4 r& p9 M, k8 n, {" Z        /*增加一个新的工作簿*/
' g" w5 n' u4 i0 V7 c2 s9 p& k1 ~: Q        lpDisp = books.Add(vtMissing);$ L2 M( H/ D& H: ]8 O7 k" w
        book.AttachDispatch(lpDisp);
1 r1 o$ i6 W: A* \- Z+ J4 b    }
6 _6 A9 ~5 k7 c, }6 g  _" U     
- |- K) I5 y: C0 C- V. X* X1 i" p' C7 x! I- Y+ ]/ t/ i* \
    /*得到工作簿中的Sheet的容器*/
! H5 C  Y& R. q8 c5 ~8 ?    sheets.AttachDispatch(book.get_Sheets());7 u  R4 g" j3 p4 a( q, }/ D6 G

( `: D+ B( A  u; ?- D6 c    /*打开一个Sheet,如不存在,就新增一个Sheet*/  E8 ~; N9 \/ B! ^
    CString strSheetName = _T("NewSheet");
( W# b4 A( L) \0 W) G; x    try
. K3 p) u6 U+ o6 S    {, K* b8 C( W- L* l/ m! X/ g
        /*打开一个已有的Sheet*/% J2 u) U# V! i
        lpDisp = sheets.get_Item(_variant_t(strSheetName));& n' a, @1 l5 f$ @/ c
        sheet.AttachDispatch(lpDisp);
6 X0 m! o7 |6 P9 B% K    }
2 H/ h, v5 U  ]  @/ t( |    catch(...): b% Y" n" F' E' Q; i
    {2 a! i) s) y9 `. N: S
        /*创建一个新的Sheet*/
2 f# m2 C9 c! f0 D3 {  j        lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);) ]# |$ Y) i' c; t5 E0 j' {
        sheet.AttachDispatch(lpDisp);
2 r' w' m2 n) ?( b( `& C4 z        sheet.put_Name(strSheetName);
) i% S3 X% Z, o+ W    }7 S3 f6 G* C# ~7 M2 {
1 _. K: Q! j' w# B; _. V6 R
    system("pause");" u( F& {1 g; ~' D' B) q+ @
, i+ G1 q5 p% C5 a
    /*向Sheet中写入多个单元格,规模为10*10 */
3 ]5 i$ n3 Y8 A$ C) E    lpDisp = sheet.get_Range(_variant_t("A1"), _variant_t("J10"));
: [( o8 P! i! J    range.AttachDispatch(lpDisp);5 D# Z2 k  x. i- P7 X2 |" R; ?1 C& s
+ a" y9 O5 K1 b, {
    VARTYPE vt = VT_I4; /*数组元素的类型,long*/; M# K) L2 H0 f
    SAFEARRAYBOUND sabWrite[2]; /*用于定义数组的维数和下标的起始值*/
  F( N  }7 s; g    sabWrite[0].cElements = 10;# x0 {0 Y8 l& L+ h8 H5 v. _
    sabWrite[0].lLbound = 0;
# H. h4 @- C; D- ^; ~! F- b) Y" M8 a: _8 A    sabWrite[1].cElements = 10;
! f; H9 o1 P& o; X$ g: L0 |    sabWrite[1].lLbound = 0;
' V& F1 e- @/ |
. S3 @$ L3 p/ l' y( I# E    COleSafeArray olesaWrite;1 e9 k! c% u8 G
    olesaWrite.Create(vt, sizeof(sabWrite)/sizeof(SAFEARRAYBOUND), sabWrite);
1 p" q6 U1 e8 h4 X5 k& X# X
5 N9 K. i9 e( g; @/ L- @0 S    /*通过指向数组的指针来对二维数组的元素进行间接赋值*/2 n+ h$ D7 u! m! }0 m
    long (*pArray)[2] = NULL;
/ k$ w8 B5 \! k9 G( g) K/ R- |5 g2 O    olesaWrite.AccessData((void **)&pArray);
0 N. Q- K+ h  G5 q! `. v) T    memset(pArray, 0, sabWrite[0].cElements * sabWrite[1].cElements * sizeof(long));
0 {3 j  d1 U  k
4 h7 V' K# W7 m' x    /*释放指向数组的指针*/
7 V+ j1 ~* C: D( @+ H0 D( A    olesaWrite.UnaccessData();
. h1 ^0 r4 G4 C% d    pArray = NULL;# ?9 P8 J! s( p% ~

% I# y# H# f0 X# ^    /*对二维数组的元素进行逐个赋值*/
% |. Q/ E. P9 q* R  g    long index[2] = {0, 0};
0 H/ H( E# F+ T( ]6 `/ M    long lFirstLBound = 0;
' Z7 B- n" X: e3 p  d) J    long lFirstUBound = 0;
6 E) b$ {2 E# W6 [    long lSecondLBound = 0;
: m6 N- j; L. P    long lSecondUBound = 0;0 v, B2 g3 U% |0 p* M/ r
    olesaWrite.GetLBound(1, &lFirstLBound);
& M) m$ `' j: ?7 R  ?) A2 h1 w    olesaWrite.GetUBound(1, &lFirstUBound);
$ _9 _; }) z3 H  \( c: l/ |    olesaWrite.GetLBound(2, &lSecondLBound);; k$ |1 _3 b* b8 P% S
    olesaWrite.GetUBound(2, &lSecondUBound);7 k# @. {; K9 P$ H3 o! j9 W
    for (long i = lFirstLBound; i <= lFirstUBound; i++)
2 c) a4 ^7 t- x5 i    {. R" T; b; Y3 ?& m9 L$ ?( m
        index[0] = i;
% T% S8 D) |" f: |        for (long j = lSecondLBound; j <= lSecondUBound; j++)
, l/ x7 r! j1 Z$ B& s" n2 f% R2 h        {+ h0 z7 b+ e. j. V0 @0 \7 e0 \
            index[1] = j;% T. T, x9 _/ L" n
            long lElement = i * sabWrite[1].cElements + j;
% z! D( T8 w7 J0 s* N            olesaWrite.PutElement(index, &lElement);
6 C# Z' B* Y. [/ o0 O        }
: `0 X+ y* T6 ]3 j7 R: g4 C    }
" ?- \( f! J! ]
% R% \) v) v! U" n    /*把ColesaWritefeArray变量转换为VARIANT,并写入到Excel表格中*/
8 V5 r3 H5 s% {' P/ L    VARIANT varWrite = (VARIANT)olesaWrite;! K1 x0 P& l' h, ~5 D
    range.put_Value2(varWrite);6 i% [1 q( e8 c

+ {& @1 \) _/ {( ~+ m* O5 J! d    system("pause");
' f% G7 \7 V4 e3 ?' A) T* r0 Z) o- P
    /*根据文件的后缀名选择保存文件的格式*/
/ d; v; X. _- w$ |: O$ g     CString strSaveAsName = _T("C:\\new.xlsx");
4 a2 u( h9 I$ ~9 {* H; G, [4 y& h( P2 i    CString strSuffix = strSaveAsName.Mid(strSaveAsName.ReverseFind(_T('.')));
0 m, N+ J9 ?! n6 o    XlFileFormat NewFileFormat = xlOpeNXMLWorkbook;, G. g) P. H& N8 x8 {; H' n% q
    if (0 == strSuffix.CompareNoCase(_T(".xls")))! C& o. D$ B! ?4 ^
    {
: {2 m/ W* ~  j) v  R) `        NewFileFormat = xlExcel8;/ d1 ]$ \- B; j9 r3 ~
    }  g! H  h. U1 m# Z, Y  K5 Z
    book.SaveAs(_variant_t(strSaveAsName), _variant_t((long)NewFileFormat), vtMissing, vtMissing, vtMissing, 8 G% C+ m; ]" o$ x; o! V- j
        vtMissing, 0, vtMissing, vtMissing, vtMissing, 0 h! ~  i/ C, E8 c
        vtMissing, vtMissing);
: m* {2 \# q$ D9 k+ B
" |" Z% d+ K9 P' a. A    system("pause");2 W+ a3 u5 r& n: Q1 j1 w
1 s( \* ^( ~, N3 n8 p
    /*读取Excel表中的多个单元格的值,在listctrl中显示*/
' n) K& g$ ]) W) R6 M    VARIANT varRead = range.get_Value2();
  _" S- [3 c% L) ~' M    COleSafeArray olesaRead(varRead);% `4 r( M/ ^$ m$ ]. c2 Q% E4 g
3 Z% b: K, U' M" n7 u9 X* M
    VARIANT varItem;
, C# R4 S: I* i" y& E) c    CString strItem;
" q  n9 J0 q8 K0 r" q    lFirstLBound = 0;
6 {9 q1 D9 `8 \    lFirstUBound = 0;
1 r" z: e; ]& L. G$ I9 @    lSecondLBound = 0;
/ p/ _( A; z! g- Z" m9 {7 T- b) v    lSecondUBound = 0;
* \: [6 Z+ g( o/ G( p, I    olesaRead.GetLBound(1, &lFirstLBound);
, M" ]" N4 q4 C  A    olesaRead.GetUBound(1, &lFirstUBound);2 G8 |' `/ x/ ]# ?) V/ x, h
    olesaRead.GetLBound(2, &lSecondLBound);
( k% q7 x/ G1 S7 T# E2 o4 p    olesaRead.GetUBound(2, &lSecondUBound);
' q! k' s& l. G8 h+ V    memset(index, 0, 2 * sizeof(long));1 P( I+ q6 T! D* `
    m_ListCtrl.InsertColumn(0, _T(""), 0, 100);4 D# F& [) B0 [1 H& i# b; h
    for (long j = lSecondLBound; j<= lSecondUBound; j++)4 ~( @5 |- _/ d$ e
    {
6 w. Z1 _, N1 H# w  ]' e; I        CString strColName = _T("");
4 \0 }. @! r5 t. y        strColName.Format(_T("%d"), j);
2 W0 A' t7 `+ Q% X) D! n        m_ListCtrl.InsertColumn(j, strColName, 0, 100);
# A" R2 Z0 g- b* G( J- P    }/ I" g, M. `! u1 N; n
    for (long i = lFirstLBound; i <= lFirstUBound; i++)( q7 }/ n2 w2 s: ?6 t
    {& g4 U8 K* ]; {5 s0 v3 c
        CString strRowName = _T("");
: H/ E, U7 f9 i& G9 z. k8 c  \* r        strRowName.Format(_T("%d"), i);
8 S( N5 R" |/ s6 X$ |, [4 R        m_ListCtrl.InsertItem(i-1, strRowName);
1 {! v" d' W' C( s2 i. Z: ]
' q  j) j( @9 Q2 m  G. E        index[0] = i;7 {! K( g1 `7 R
        for (long j = lSecondLBound; j <= lSecondUBound; j++)
* n; v& Y% k0 f6 v        {* ~& I- d) O( L
            index[1] = j;
, e! H; Z) W1 T3 v, H+ G# i            olesaRead.GetElement(index, &varItem);% f. X1 r9 p: {: n$ x' N1 t6 X

/ F) B1 V/ B- X5 Z            switch (varItem.vt)( U% ~" z- D  N2 u/ k) L5 x% a- h
            {! w$ a7 y- E& e4 C  w
            case VT_R8:4 ]) Q$ Z+ @0 V8 B' ]' B: x. H+ R
                {
8 M, i. B1 b- _2 }$ r% J" U                    strItem.Format(_T("%d"), (int)varItem.dblVal);
( V* R9 ~, x4 E                }
6 K* H+ C6 {3 G5 s- W* t
& @: Y' l3 ]3 \1 z            case VT_BSTR:6 B; |5 F/ H# f' \' N
                {
$ g: d& o) N8 Y1 S5 }8 S0 T                    strItem = varItem.bstrVal;
' O* i$ n% l$ I  [! o5 C/ F                }+ }6 Y8 H, S7 m$ Q% T9 D

2 [) K; c0 V1 c2 G; y            case VT_I4:
7 z5 F+ k9 V9 ~' V4 p1 k3 e4 }                {1 g5 g: K# ^8 U  }, b4 n9 ]
                    strItem.Format(_T("%ld"), (int)varItem.lVal);
, N5 V# ?% q2 ^) q                }$ a4 ?! m. i: v. o& X9 d7 f
3 L( K" n% N- ]& E) G8 V$ G
            default:
- t" {1 q4 T& s# x4 H                {
! y& Z; N2 d+ x, P  t
2 ]4 O! a: I* Y) p+ k& O; g9 n                }$ {& S4 P7 U" T/ b* u
            }* u! w( p% U" h% A, h, m( m" J& k+ Z

3 z& x# [% Q! I( e            m_ListCtrl.SetItemText(i-1, j, strItem);
, q% N- Y! {  G8 b5 Q        }
5 t$ `8 y4 s0 I6 t- W9 B% ?& H    }# P8 W, X. c8 I* d) L
0 W7 A- L$ b; T/ [0 E

  q1 w7 w, d9 Y0 E' s
4 _( S$ H* F# A+ O0 ]" T, D    /*释放资源*/
+ B  |) X4 W# Y. |+ r% n0 C    sheet.ReleaseDispatch();
, c+ S( Y) [' [+ y    sheets.ReleaseDispatch();3 g& F# t8 b/ I
    book.ReleaseDispatch();
# v2 u) h- Z. @# O    books.ReleaseDispatch();
4 E8 f( w- i2 J; N+ @    ExcelApp.Quit();. \# R% m& `. Q( q
    ExcelApp.ReleaseDispatch();
4 c$ G7 a5 W: ^0 y! N- t) f  K. ]' K9 m3 @) `0 i5 }
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了