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 6455 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表格的操作。
  N& y' w9 k# L3 H1 s' Z' A: J  
+ l2 P: P# g# q1 J' C本文源码的应用环境说明:
, E, I1 w1 f# [- Y3 y* X7 qWindows XP SP3
7 {3 R& W6 j4 u7 p/ zMicrosoft Visual Studio 2010  n9 \, ]. q5 C0 b  M5 S# n
Microsoft Office Excel 2007
" Q6 ], ~3 x1 Y1 F- l5 x+ s5 j  
# \4 u/ o7 X( V# q! y3 S1、添加OLE/COM支持。
$ l$ Z: D, H! J9 F" }0 t. U首先,应用程序必须添加对OLE/COM的支持,才能导入OLE/COM组件。
! R1 M+ d( D" P) r  v本文使用的是MFC对话框程序,在创建工程的向导中选中Automation选项即可为程序自动添加相应的头文件和OLE库初始化代码。
3 a' F! j; `: X! \! _通过查看源代码,可以知道在stdafx.h的头文件中,添加了OLE/COM很多类所需添加的头文件。
$ G. ^! M9 B7 R7 U& q/ @. {#include <afxdisp.h>        // MFC 自动化类. N2 \6 M# \  e3 N& U0 S
同时,在应用程序类的InitInstance函数中,添加了OLE/COM的初始化代码,如下所示:
/ x0 h$ _" l/ B4 W// 初始化 OLE 库$ X% P2 V* p' e8 o
if (!AfxOleInit())1 y# s5 d& m# `7 d$ A
{& {& T  V/ `7 {3 r$ ]* z
AfxMessageBox(IDP_OLE_INIT_FAILED);
# w8 U; ~( r; w' E3 Yreturn FALSE;! u1 J& O  V# L$ U7 d' J2 c8 X
}
0 _# t8 j2 h/ W8 {5 Q$ Y3 C  
7 M- V2 {5 f+ @3 F* D2 I2、导入并封装Excel中的接口/ X5 d7 C. C& \% o% R  h2 {" ]3 d
Excel作为OLE/COM库插件,定义好了各类交互的接口,这些接口是跨语言的接口。VC可以通过导入这些接口,并通过接口来对Excel的操作。* ?8 F& P4 |9 l# h0 Q
由于本文只关心对Excel表格中的数据的读取,主要关注几个_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range等几个接口。Excel的各类接口的属性、方法可以通过MSDN的Office Development进行查询。
- h1 Z( G1 S. `' b. H: BVS2010导入OLE/COM组件的接口的步骤为:Project->Class Wizard->Add Class->MFC Class From TypeLib,先选择要导入的组件所在的路径,即Excel.exe所在的路径,然后再选择
' w( g# n$ [: {" j! V# ^& l5 X( R要导入的Excel类型库中的接口。0 t- Q- P% n( y
在完成接口导入后,VS2010将自动为导入的接口创建相应的实现类,用于对接口属性和方法的实现。由于标准的C++没有属性访问器,只能添加一个两个存取函数来实现对属性的访问,通过在属性名称前加上get_和put_前缀分别实现对属性的读写操作。即,由VC自动完成C++类对接口的封装。7 \5 `! |" H1 ?8 ?+ o
  
) r" t- A" U0 d$ ~% U) q本文所导入的接口对应的类和头文件的说明如下所示:
6 K8 f! {2 c2 V/ i5 X  
1 M' ?9 B1 B- ?( a7 c- j* x0 SExcel接口
3 n. g9 `, i4 F( Z5 V# |' u导入类5 L  f3 F$ s% |
头文件: L4 A2 f3 A+ I( h% G' g1 J1 i
说明
% |% p* b+ @5 S_Application3 u: l, W2 @$ J" _7 c' o3 Q, V5 r
CApplicaton$ }% l# T* W, v9 w# C
Application.h
7 \# Z! U6 v* V5 y  s. q$ C+ `Excel应用程序。* J) x& U3 U# l" V0 a/ m
Workbooks
. ~4 C, a3 W- z* F0 n/ C4 ICWorkbooks& O7 i& D9 d8 f  e( I! }& i
Workbooks.h9 b3 v& D" ^0 N: g
工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。/ I* `. ~( v- k# B  E
_Workbook6 H3 x* E% U7 w+ F7 T
CWorkbook: R3 L: S; s; L4 t7 ?( H0 f
Workbook.h
$ G" X* M7 x3 Y, M( t单个工作簿。
3 g$ M3 X! {! y1 [6 ]Worksheets
- y6 r/ N1 K7 H, m0 k" H( J& f2 q" vCWorksheets7 C* z- t: I) v1 q- s2 W* D0 h
Worksheets.h
3 [4 r# A, Q# k, @7 V单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。
( X. C7 M6 Y' k6 W# I& d_Worksheet
$ s2 p1 H# Z9 v9 w! X4 Z4 |CWorksheet6 d4 g# ?$ r3 P0 j3 h  }; I. r3 F& Q
Worksheet.h% N  Y; [* A2 i  S" ?* V' g
单个Sheet表格。' ^* P: {9 d, Y# M/ u% q9 ?
Range* J4 R# q8 ?! C2 _  p
CRange
8 C& l* {& w0 T" ~Range.h+ ~+ F  \. e# b- B+ O. p1 I$ A: F
一定数量的单元格,可对单元格进行单个或多个单元格进行操作。
! G, s  P; N( E+ h7 W  8 @6 Z9 n+ c& a. B% h4 [
3、导入Excel的整个类型库
/ E. ~8 l% e; y0 K接口对应类只是对接口的属性和方法进行了封装,而Excel中的数据类型,如枚举类型却并为并不能使用,因此,为了更方便的操作Excel,还需要导入Excel的数据类型。1 a- \5 Q4 d" s
通过查看导入接口对应的头文件可以发现,在所有导入接口的头文件中,都会有这么行:# b+ a9 G" {3 T7 J9 a
#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace
8 \, e0 `8 x5 e2 F: H这行代码的作用是导入Excel整个类型库到工程中。
' U: {; f4 A8 _% @/ g- l由VS2010自动产生的导入代码存在以下几个问题:" y; o0 M# ~6 U" U
(1)如果导入了多个接口,每个头文件都会把类型库导入一次,如果引用多个头文件,会导致类型库重复导入。) ]: f( H( H( ^8 s; u
(2)Excel类型库中有些类型会跟MFC类库的某些类型冲突。
+ q8 r7 ?; m% ~2 ~3 G! s(3)Excel类型库的某些类型跟其他Office和VB的某些库相关,如果不导入相关库,将导致这些类型无法使用。。
( |. }3 Y! a* n# j/ a8 {以上三点问题的解决方法如下:
3 {: e" C  |: ?- |(1)仅在_Application接口对应头文件中导入Excel类型库。7 q) S' f! j( B) [0 b' o7 V3 A
(2)对冲突的类型进行重命名。
0 p% J) Z0 a: k# X! T) N(3)在导入Excel类型库之前,先导入Office和VB的相关库。+ r) S4 e8 q& s4 E' Y$ A1 }% g
更改后的导入类型库的代码如下:7 x# Y( ~% ]: L' D: s- E. Z. J
  + |' d) q) p8 n2 {
/*导入Office的类型库*/
9 |& Z: S2 ~  r#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL" \6 h: `3 ], J. B) M3 x. H
rename("RGB", "MSORGB") \8 g$ {* t" {4 ^$ g
rename("DocumentProperties", "MSODocumentProperties")
- w: h6 R! u% g+ v3 qusing namespace Office;9 S- Y9 @, }% j- b: {
  
; [: B; l( f0 a7 a/ d6 G/*导入VB的类型库*/% @: i2 q/ V- A' q& z! y
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"
5 Q# [5 ^2 W2 wusing namespace VBIDE;# m, M1 C- q0 m3 A+ [
  
, i5 F, E% ?2 {  ^3 j, O1 {/*导入Excel的类型库*/
( y0 O4 A; |: A#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" \
; {3 m: ?7 [' B0 ^  t6 f* m' R# V( Mrename("DialogBox", "ExcelDialogBox") \( V- x' L7 q5 E, e. Q3 Z
rename("RGB", "ExcelRGB") \1 {$ H* Z4 E! q( ?8 ^% {
rename("CopyFile", "ExcelCopyFile") \
! I8 q8 I; ]$ ^: grename("ReplaceText", "ExcelReplaceText") \( c/ X# M0 N. J5 T% [
no_auto_exclude3 ?' t0 X' Y: x- [& n# t: G
Using namespace Excel;
& e$ J5 a6 S5 |  # P' B: r$ i2 E/ J, ?, l
编译程序后,会在DebUG或Release目录下生成三个文件mso.tlh、vbe6ext.tlh和excel.tlh。通过打开文件可知,该三个文件的命名空间分别是Office、VBIDE和Excel。导入了Excel的整个类型库后,就可以使用Excel中的所有类型了。# Y; d3 f" r7 T
  
! X: X& [6 X+ S8 Q9 _8 P/ M; Y# X; J4、操作Excel步骤
  {) r" [% e0 o: d& r# H2 W7 H) I操作Excel的主要步骤如下:
% h9 {6 g% ~( J. R3 I! V(1)创建一个Excel应用程序。
- w: N$ L: f, m" b- |& ~(2)得到Workbook的容器。  d3 k! Z$ B% T- j. S4 _; p8 e
(3)打开一个Workbook或者创建一个Workbook。
, d4 M& j6 O+ _7 v1 m/ x7 j(4)得到Workbook中的Worksheet的容器。  P" Y0 p, @& s
(5)打开一个Worksheet或者创建一个WorkSheet。, A5 {% T1 x- A7 Q; q2 u
(6)通过Range对WorkSheet中的单元格进行读写操作。  h) o; x, p/ }' R5 ~8 r5 I
(7)保存Excel。( y) G0 W3 I1 Q, [# c9 d* S& `
(8)释放资源。4 r9 m0 T8 m5 \, j
  
  }. {+ l0 k' Y( Q2 k5、批量处理Excel表格
% s; g# w- R9 I/ YVC通过OLE/COM操作Excel,是通过进程间的组件技术。因此,每次读写Excel中的单元格时,都要进行进程间的切换。当数据量大,如果一个单元格一个单元格的读取,主要的时间都花费在进程切换中。因此读取多个单元格,将可有效的提高程序的运行效率。
) j3 f+ M, e: {/ a) E# {9 l! Q对多个单元格的读写操作可以通过CRange中以下两个成员函数来完成。8 P: w7 w" P: A* v
VARIANT get_Value2();
4 ~; K2 _, A5 E1 O5 Gvoid put_Value2(VARIANT& newValue);( g. Z3 [8 {# Z$ B- ^
其中,输入参数newValue只要输入一个二维数组,即可实现向Excel中一次写入多个单元格的值。
/ G+ T+ R4 |) F: J2 C% ^! e其中,VARIANT中实现二维数据的方法可参考
/ E" w" S' p- R  T( K; D$ O% fhttp://www.cnblogs.com/xianyunhe/archive/2011/09/13/2174703.html' K1 e2 A! |' h/ h0 n
当然,在对CRange类进行操作之前,要设置CRange类对应的单元格。
6 y! k5 ^# Q  Y. b7 x1 m5 O  
0 s; f3 k" c, W6、Excel表格的保存1 O  e0 i* b5 ~; x( H! R
(1)如果要保存打开的工作簿,使用CWorkbook类的Save函数就可以保存工作簿,原文件将被覆盖。
+ s7 ]1 H2 H* D* b(2)如果是新创建的工作簿,或者是要另存为,可使用CWorkbook类的SaveAs函数。# F" x9 F4 l0 j/ Y' A
SaveAs的参数比较多。其中,第1个参数是设置要保存文件的路径;第2个参数是设置文件的格式,可在MSDN中查看枚举类型XlFileFormat来了解Excel的文件格式。经过测试,在本文所用的测试环境中,Excel2003的文件格式是xlExcel8,Excel2007的文件格式是xlExcel4。( m6 X1 ~; m/ _3 A
  
- A' p/ H2 }0 _( x$ f' k3 t: i0 A7、获取当前Excel的版本& p& d& T: {) w3 I
可以通过CApplication的get_Version函数来获得Excel的版本,其中,Excel2007的主版本号是12,Excel2003的主版本号是11。
6 h, B$ c0 E! f5 L& z7 i' @  
# c# g* h, T2 i! t+ Q& _8、示例源代码
2 Y7 Y4 \& j, B主要代码如下:
4 u2 D- |7 G. U7 b: F  . D) j/ A2 v0 b; n" c8 X- c
# `7 K0 o* [* W+ \) L8 [) V: U

* g( `4 [( y1 U( b, Q) H  Y    m_LisTCtrl.SetExtendedStyle(LVS_REPORT | LVS_EX_FULLROWSELECT);
! B- n$ q$ Y, T
1 [7 @2 Z) g( W8 @    CApplication ExcelApp;
& s  T% T! V$ u. \7 A  y    CWorkbooks books;
1 l: ~4 ~0 v4 v" C$ I1 _9 @, }3 |    CWorkbook book;
" g+ M7 a* y. I7 `6 b- P    CWorksheets sheets;2 `7 ^. Y5 N! q
    CWorksheet sheet;: w% h' ]. J% Y
    CRange range;
# t/ `# O# s" S0 G! x8 x8 O5 n6 ]    LPDISPATCH lpDisp = NULL;
7 R( V+ K+ H5 S: P. x! \# Y1 {/ c
& o+ A" |8 K4 s9 m. I" K# Q    //创建Excel 服务器(启动Excel)
' O0 n( v3 h& y' K% v. ]' y; f" ]1 ~    if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL)): J4 r. T# U- ?) o% q; G8 h
    {3 V  O  v+ t* ~" ?* l! Y
        AfxMessageBox(_T("启动Excel服务器失败!"));7 r$ A" K! ~* N( l" v+ d% J1 b, M
        return -1;
% {) {9 b+ `8 B) ~2 q$ `! N    }
  h4 t3 q# L! T9 `2 K8 r( v/ v3 P# ^: r# S2 j  X, D
    /*判断当前Excel的版本*/
2 H$ a+ z# L, f( ?$ B4 e# `    CString strExcelVersion = ExcelApp.get_Version();
( T" T5 V, u. `; L: d    int iStart = 0;
6 U4 R# w" n  W, e8 S3 K" i4 N7 T! e; ~    strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);
! G; m: z$ w# a, y0 \+ F1 G    if (_T("11") == strExcelVersion)" G/ m4 _; \! }( B, {% h
    {
) k3 ]% L7 n3 }2 y8 {1 U' F        AfxMessageBox(_T("当前Excel的版本是2003。"));; F) ]% s$ \: b6 s  n
    }
  G7 Q6 s6 N$ t7 w  M: b    else if (_T("12") == strExcelVersion)2 h# k( z0 K5 N( Y% v3 m5 w
    {& m; d- F, d  L& g6 e$ L
        AfxMessageBox(_T("当前Excel的版本是2007。"));; h8 u) p( a! g/ k+ a; z: d
    }8 h- J: S9 D0 R- Q2 k3 y1 h; N
    else% ?- a: z/ t# L" X1 W2 e5 s4 ?' U0 ^/ F
    {
, y  n* R! y) o2 A. c        AfxMessageBox(_T("当前Excel的版本是其他版本。"));
# C! G$ l2 y' ?0 G7 e8 [    }5 _. q4 f( G% |
! j5 ^# V$ f5 b5 d4 n* y
    ExcelApp.put_Visible(TRUE);6 l5 V* D2 T& m, a1 P
    ExcelApp.put_UserControl(FALSE);
4 b% v8 T: u: a# Y( b9 h
, J& {- e7 t. h. D5 S0 {" O9 f% _    /*得到工作簿容器*// \4 R2 s  @0 k4 F8 Q0 ~
    books.AttachDispatch(ExcelApp.get_Workbooks());% ]1 j4 g: M! k- z9 Y; d7 k

. Y/ b. [# M/ v3 e6 h    /*打开一个工作簿,如不存在,则新增一个工作簿*/
# K$ x. O  {" q7 o    CString strBookPath = _T("C:\\tmp.xls");* |  ^1 Q2 L/ s* \9 W' z1 Q4 K. j
    try5 ]# d+ f/ h. M! n. z
    {! Q$ a% y7 T" b% t- r2 N
        /*打开一个工作簿*/
* Z, E3 j5 ~' M9 R* f* T        lpDisp = books.Open(strBookPath,
3 d+ z0 |/ t% |: m; ~0 c& }            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,/ T9 i8 @0 N% ]4 V) U
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, ' Y' ^( a2 x4 u$ k" v
            vtMissing, vtMissing, vtMissing, vtMissing);0 t; K, |, Z. ]2 F6 J) T" p) X
        book.AttachDispatch(lpDisp);
, w+ Z( X- ]" r* _9 X& u    }$ ~% m0 C' r$ ^
    catch(...)% f* Y0 I7 k+ B% A3 `8 \
    {
* X( w) W& x: P6 O4 T6 g2 e* j        /*增加一个新的工作簿*/
5 c! J1 x" ~$ i! B5 {3 `+ c  X        lpDisp = books.Add(vtMissing);" z4 ?/ h/ @3 s+ i% _3 G
        book.AttachDispatch(lpDisp);7 U$ I9 |; [1 Q2 r" x
    }& B7 [2 b, b6 z
     
  ~# e7 q/ D( q/ ]5 C
* {" @( ?. |9 K( t    /*得到工作簿中的Sheet的容器*/
7 T) p6 I5 x& @3 f% R6 S& P1 |    sheets.AttachDispatch(book.get_Sheets());  _: M: B& ^+ N/ G6 J1 _

# y' e( g* r" l6 E/ ^0 P0 P4 V    /*打开一个Sheet,如不存在,就新增一个Sheet*/+ o8 j5 D# t2 y: `, T8 `9 U4 ^
    CString strSheetName = _T("NewSheet");# T/ w3 E8 I" v5 k4 \- @
    try" @0 n, O- V% W: d% g4 t
    {. |8 H$ H: |5 P3 z* x
        /*打开一个已有的Sheet*/
. c- w% X% N, w% ?        lpDisp = sheets.get_Item(_variant_t(strSheetName));" T8 m7 _, m$ M8 ]. A/ r
        sheet.AttachDispatch(lpDisp);
5 D4 O; m8 p2 G" l- Z& P; p6 a& j    }& n% X5 p7 e: u1 I
    catch(...)
/ H( F5 Y9 K& E; c0 ]5 @    {
" q( t1 Y. l8 Z, E2 `5 \; d# K4 D        /*创建一个新的Sheet*/- h  ?/ \3 C. a
        lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);  [! j9 ?" N" }1 U8 z
        sheet.AttachDispatch(lpDisp);
3 w- m# m& B% {) U1 j* H' O        sheet.put_Name(strSheetName);
8 j9 y9 W+ A. h* u" p; P, R- U/ z    }
& p( L9 d2 [* H" u  J  b) J7 P' C- E$ t! W0 C6 _" h
    system("pause");
' q% U' o" A/ _& K8 O
# M: M- ]$ H- j5 P  |, ?/ ]    /*向Sheet中写入多个单元格,规模为10*10 */
& ?1 G' T# p: G    lpDisp = sheet.get_Range(_variant_t("A1"), _variant_t("J10"));6 I  y$ \( a, c5 B; C- S
    range.AttachDispatch(lpDisp);
1 m% B2 v/ D/ r' V
* D2 {$ |" q7 A0 q    VARTYPE vt = VT_I4; /*数组元素的类型,long*/6 M* |4 b( O) x$ l5 ?# G) W: ]! T9 i" S
    SAFEARRAYBOUND sabWrite[2]; /*用于定义数组的维数和下标的起始值*/
3 p/ P# N0 _+ E. c    sabWrite[0].cElements = 10;
5 a9 N6 N( _" u9 v8 D8 s5 Z    sabWrite[0].lLbound = 0;8 i2 p" y4 d6 H- r7 A- N  {' ]
    sabWrite[1].cElements = 10;
' w; `# n' @) K+ B" z: Y    sabWrite[1].lLbound = 0;
) _5 q8 ?% Y5 Q% K
+ a' n- U. G- v    COleSafeArray olesaWrite;( w& b! p/ f, w( I6 ~2 j
    olesaWrite.Create(vt, sizeof(sabWrite)/sizeof(SAFEARRAYBOUND), sabWrite);
* O6 Q  C( @; r" s" Y: @) F$ H) s9 m- T+ r* t
    /*通过指向数组的指针来对二维数组的元素进行间接赋值*/
. j0 x0 F. x2 o! G% a6 i7 D& _    long (*pArray)[2] = NULL;
3 W+ u9 W5 r5 K# }4 C9 z    olesaWrite.AccessData((void **)&pArray);9 w) ]" m6 i" f1 H: {
    memset(pArray, 0, sabWrite[0].cElements * sabWrite[1].cElements * sizeof(long));8 R) f4 Z% {7 S& z  R( o

. I& w% T1 {5 F# `6 r9 R' [    /*释放指向数组的指针*/
# w( ?3 y  C9 G  h2 B    olesaWrite.UnaccessData();
; m3 d; c' t( r2 Q; J9 @    pArray = NULL;
; Z5 F7 I8 C. `" ~+ e
1 A  k( |7 y1 T1 e+ w2 o  F    /*对二维数组的元素进行逐个赋值*/# B* t& K& [" m! G% D, s2 O8 i
    long index[2] = {0, 0};
/ Q; N" f+ a5 f/ S    long lFirstLBound = 0;3 N0 O7 r5 v& G3 u8 p. t
    long lFirstUBound = 0;
* O' }4 e4 k2 A: z& Q0 a0 n    long lSecondLBound = 0;- G& o$ S7 {& Y8 N, c2 I
    long lSecondUBound = 0;+ q+ w% W  x0 H9 Q2 e9 w
    olesaWrite.GetLBound(1, &lFirstLBound);9 W8 w8 ~4 X5 `0 O, y  N
    olesaWrite.GetUBound(1, &lFirstUBound);
' H- s7 b& b! B) u    olesaWrite.GetLBound(2, &lSecondLBound);
) n7 y" y; z+ w    olesaWrite.GetUBound(2, &lSecondUBound);: V9 y+ X  W9 ?
    for (long i = lFirstLBound; i <= lFirstUBound; i++)
" h; c# i0 U! G9 h! u    {
  \% p; h- N# ?5 A3 D8 T        index[0] = i;6 S7 q; ~2 k$ O! z/ s" G
        for (long j = lSecondLBound; j <= lSecondUBound; j++)" F. y2 w9 t8 [, k5 E
        {5 X& I3 b. j2 x& S. n
            index[1] = j;
4 G: |% C6 z5 g' g9 P; ~; r9 T            long lElement = i * sabWrite[1].cElements + j; & M' E" f7 [) m
            olesaWrite.PutElement(index, &lElement);2 B& E- o7 d- r' X0 s, k
        }( P! g; X; X7 z8 W8 S: G; U5 ?. C
    }
$ \! J3 c2 k2 `2 S3 s+ T6 z8 w6 i2 P3 y# ]" R- u
    /*把ColesaWritefeArray变量转换为VARIANT,并写入到Excel表格中*/" Q+ v6 e. B& O- f* j! X$ g; z+ a5 z
    VARIANT varWrite = (VARIANT)olesaWrite;- G& `' C% `2 |) J4 X/ d! \/ F- R
    range.put_Value2(varWrite);
6 s! k( G/ V8 O# f) F- x" l' |- u, ~, B9 q; }. A
    system("pause");
: l2 z+ S1 G+ ~
4 ^( D7 X2 P2 ]! D& f    /*根据文件的后缀名选择保存文件的格式*/
! W2 \- a# x3 F6 o     CString strSaveAsName = _T("C:\\new.xlsx");
7 n1 I8 ~& d6 \6 r: D% u    CString strSuffix = strSaveAsName.Mid(strSaveAsName.ReverseFind(_T('.')));1 [" j1 o; E5 E$ S/ b
    XlFileFormat NewFileFormat = xlOpeNXMLWorkbook;6 s  Q; p" j& X3 I5 o
    if (0 == strSuffix.CompareNoCase(_T(".xls")))1 T6 }- f/ `6 d! \4 e1 h
    {2 ^  b5 t- A% m" s
        NewFileFormat = xlExcel8;! {8 ^( t! o& a4 i! {
    }
* `7 B# m6 e* ~/ X& I    book.SaveAs(_variant_t(strSaveAsName), _variant_t((long)NewFileFormat), vtMissing, vtMissing, vtMissing,   z' A" z' `, I1 `) A
        vtMissing, 0, vtMissing, vtMissing, vtMissing,
3 M) X3 A- G9 U0 w$ d2 C0 X$ Z        vtMissing, vtMissing);1 ?8 N9 T$ R$ t6 }: X2 t* q

; Z; |3 Y9 X2 |' U4 G    system("pause");: f8 B8 {' u: ^* F9 H" D4 q

9 F$ M( R1 I$ B, `5 C# J/ @1 z    /*读取Excel表中的多个单元格的值,在listctrl中显示*/
# ]  V( |; j% h6 p- a' y( d; U: T    VARIANT varRead = range.get_Value2();
& h; h) u" m# ]    COleSafeArray olesaRead(varRead);6 @& I4 J; s& L# h/ u$ c/ g
9 h! v1 \" p# S) Q% y0 @
    VARIANT varItem;# ]4 P, {% K& D+ I1 E
    CString strItem;
8 W" w) f, I& g9 a/ q    lFirstLBound = 0;& h' X0 P! ^: F, K0 W" J
    lFirstUBound = 0;
1 W8 \/ a* S' z& V$ h- G' ~( o* Q+ i$ W, b    lSecondLBound = 0;+ U0 D' d4 `- c( Z
    lSecondUBound = 0;
% G! T' y0 a- {% x4 G    olesaRead.GetLBound(1, &lFirstLBound);5 X0 J% Y" \  X% e" @" e) l
    olesaRead.GetUBound(1, &lFirstUBound);
  }. R& y9 A1 U9 @6 P    olesaRead.GetLBound(2, &lSecondLBound);
$ E" x% T9 H5 _4 ^4 f    olesaRead.GetUBound(2, &lSecondUBound);
( e$ @0 c- Z- A9 j8 Q0 V6 B    memset(index, 0, 2 * sizeof(long));. X; `/ o/ q# z" G4 I+ |/ l
    m_ListCtrl.InsertColumn(0, _T(""), 0, 100);! a8 L8 G8 q' Q6 x5 e1 E! B+ U. O( `
    for (long j = lSecondLBound; j<= lSecondUBound; j++)
2 I: r6 C" M* W6 P    {' z4 a  U7 M0 {) f# d/ O) [! V" H
        CString strColName = _T("");, I/ _1 ~3 P4 U6 p% t6 c! F+ E
        strColName.Format(_T("%d"), j);
5 G: U; b' Z* p) Y; C        m_ListCtrl.InsertColumn(j, strColName, 0, 100);" X! Z, m2 D" u, Q/ y
    }
' f# D; a4 p0 X% v. C2 q- \    for (long i = lFirstLBound; i <= lFirstUBound; i++)+ s4 }. \- P7 u, u/ L9 G
    {
0 o9 |" v  A5 L7 P1 l7 {5 L        CString strRowName = _T("");  K0 ?$ E0 T# B5 J4 s- o: O/ D0 |
        strRowName.Format(_T("%d"), i);
4 z$ C! J5 M1 x( G' v        m_ListCtrl.InsertItem(i-1, strRowName);2 D2 b' {& a7 X% Y' x6 ?2 `
8 Z: R7 |9 A# T% O" \4 T+ E
        index[0] = i;
5 V# T' w/ b1 K4 f7 w$ \5 z        for (long j = lSecondLBound; j <= lSecondUBound; j++)
6 r9 h1 k0 C; V$ K* q" \* d        {
$ M; \& t* m. N1 G2 I: ]% f8 W- }            index[1] = j;
: _' o* }" Z) c. v" q, n            olesaRead.GetElement(index, &varItem);- U. E* j2 l6 C8 E( V# J* [; m
+ @9 ^' T7 D: t; B. y4 B
            switch (varItem.vt)
8 F6 P$ v: {1 W) ]* S            {1 b* u6 e9 S: \. ]  C/ }8 G; O. p
            case VT_R8:
1 i! p/ ~$ X- Q2 K                {
3 y6 h: _* y( k0 M                    strItem.Format(_T("%d"), (int)varItem.dblVal);: e* {1 f3 Z. N8 l
                }3 ^! j" V# H9 J% r

. r! ^4 ?: F! b0 m& d. q! _5 a            case VT_BSTR:
- V# }* F3 V) i0 N- m9 }                {
$ I* i: s: d, M( V/ j                    strItem = varItem.bstrVal;
3 _, z- k, r9 `- d" X9 i+ W- E0 {                }. n# J5 _# d/ p. u  Y
) |: V! g" a3 i
            case VT_I4:
. ?" i8 K9 V+ f4 k$ z; P- m                {( ?! ?; D! ^: Y; h/ H: i/ L  m# R
                    strItem.Format(_T("%ld"), (int)varItem.lVal);9 c. D: b9 i' I" H8 M  U! b
                }
2 C+ `3 f% y% S' z$ f
+ b9 A9 r2 C5 d/ @! D            default:
  s* D& t1 m2 T9 `                {
: |% ~& U: I) z& E+ r" w& o  Z/ A
/ F, P' f* s" {; r, p                }# L; O9 C$ n8 S' H4 a
            }; ?) D) D) s/ {5 u

# Y5 i5 U! X6 Q            m_ListCtrl.SetItemText(i-1, j, strItem);
7 V6 f, G7 X+ z( a7 b- @2 w( P" G& Q7 X        }
3 j) b* n9 T2 [, _+ y/ d% Q    }8 C; n  ^4 X& V% z" b
6 P' A& n" I, I$ H- v

4 M, R! Y; O3 ~7 E
  H9 K* ?7 X6 a; R    /*释放资源*/& v$ f1 Z# q1 {0 l+ S
    sheet.ReleaseDispatch();3 A# y8 F/ c1 t* C% B
    sheets.ReleaseDispatch();0 s. A! m5 s0 s& j1 b: Z
    book.ReleaseDispatch();8 W2 V: o6 q5 l3 ^5 ]! _
    books.ReleaseDispatch();
6 G' g- a( o$ b. r" _. a# \    ExcelApp.Quit();
9 C4 t& J7 Z9 o2 @& T    ExcelApp.ReleaseDispatch();- _& _' ?3 f  S6 f" e2 U, K
* ?9 o" W3 Y" [' y( b
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了