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 6438 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表格的操作。9 h* d5 ^$ C4 d0 ^' y8 K/ q
  # Q( [7 u; n2 z8 a8 q2 l/ D) U
本文源码的应用环境说明:
0 f6 M) c8 Y; A$ JWindows XP SP34 m9 V) y' u& q& ?$ d
Microsoft Visual Studio 2010
8 }* R, h0 _$ LMicrosoft Office Excel 2007
+ |2 U- }& x- N5 g" v; z  5 ?* X' b, Y4 e  y; m* w; ?' ?5 x
1、添加OLE/COM支持。2 p! F, y2 n. C9 N# _
首先,应用程序必须添加对OLE/COM的支持,才能导入OLE/COM组件。
8 |% z; e$ C- c( F1 A/ [, W7 B8 I- V本文使用的是MFC对话框程序,在创建工程的向导中选中Automation选项即可为程序自动添加相应的头文件和OLE库初始化代码。: X- J6 b3 K  ?. n  ]  m5 j
通过查看源代码,可以知道在stdafx.h的头文件中,添加了OLE/COM很多类所需添加的头文件。4 [0 ~$ B, {$ A! D
#include <afxdisp.h>        // MFC 自动化类
3 J5 |: _7 ?, {同时,在应用程序类的InitInstance函数中,添加了OLE/COM的初始化代码,如下所示:$ ^! d7 C; g4 A. Z& U! k' _6 D0 T, e
// 初始化 OLE 库6 i4 N4 o0 s, M3 F; t
if (!AfxOleInit())& v' Y7 a; q( J& T2 _& F  K
{
& y, s9 G  Y* _& fAfxMessageBox(IDP_OLE_INIT_FAILED);7 P  c. ~0 c5 d& L$ @! J" ^; q$ D
return FALSE;
7 Y9 U4 z- f5 {9 y6 B# K/ L}% U( K; k8 K  j7 K) p! u2 _& ]4 p! M8 f
  
) p- `. r0 s. r/ U% S: o  H2、导入并封装Excel中的接口" B2 e( B* {1 A
Excel作为OLE/COM库插件,定义好了各类交互的接口,这些接口是跨语言的接口。VC可以通过导入这些接口,并通过接口来对Excel的操作。3 l6 y* c; L% q3 X0 O
由于本文只关心对Excel表格中的数据的读取,主要关注几个_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range等几个接口。Excel的各类接口的属性、方法可以通过MSDN的Office Development进行查询。* X7 C; c. e1 N- u% j& T7 |
VS2010导入OLE/COM组件的接口的步骤为:Project->Class Wizard->Add Class->MFC Class From TypeLib,先选择要导入的组件所在的路径,即Excel.exe所在的路径,然后再选择
% W* f. r6 ~5 R要导入的Excel类型库中的接口。. o" b1 i( E/ Z
在完成接口导入后,VS2010将自动为导入的接口创建相应的实现类,用于对接口属性和方法的实现。由于标准的C++没有属性访问器,只能添加一个两个存取函数来实现对属性的访问,通过在属性名称前加上get_和put_前缀分别实现对属性的读写操作。即,由VC自动完成C++类对接口的封装。
; j$ g: z- L0 `# R2 m; }  1 }- X* F% W! U8 ^7 l3 Y+ P  ?
本文所导入的接口对应的类和头文件的说明如下所示:
; R6 a( _9 J+ d: Z) t  
# P+ ]% v5 G8 f& `. L, X. MExcel接口4 V6 g1 c/ v$ y
导入类3 r' x( b. d, x% k: A3 S2 H9 t
头文件5 _1 ~2 A9 h! ^$ D6 u
说明
  R3 d7 n' k* }  S3 [6 z5 x* o_Application
) S9 Y5 N8 c# P2 D1 C2 DCApplicaton8 w* ?+ S9 o& c. p# u
Application.h' m8 O$ P" ?* E, j/ c% C
Excel应用程序。
- Z/ U9 v+ E/ g: _: e2 fWorkbooks0 A* D/ X# C  Z# p! ?2 B+ k0 g% i/ I
CWorkbooks6 w' B. a& r: z6 Q; t
Workbooks.h
) C7 w7 I9 e) [! y# {$ W1 H& O工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。
; d, A5 N6 S) p5 b1 l1 M/ B7 |! I_Workbook
# H- M- U! b+ V! P! e5 j7 [CWorkbook1 v/ U2 c" m" A# o/ l; Q) \. u: W
Workbook.h
: Q' u8 |- O% _. c- F单个工作簿。
( l: e5 U$ W, o" P: I0 eWorksheets$ k' l1 {/ A9 w: q
CWorksheets  j' F4 f- ~# c  K( `
Worksheets.h
7 @& x( h8 h: r7 i) k4 A- q6 {单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。
* h  E$ \$ ~- |1 Y. r$ D) ?_Worksheet+ \+ s7 Q0 N  k7 ^/ I
CWorksheet
) `" q# S/ N' q4 e" [Worksheet.h/ Z) {0 A) S8 N( {
单个Sheet表格。
* c( r, n0 r3 y& o( G! ?6 L4 wRange7 E  {' W2 o+ l9 j% l
CRange  X. V. J" @; X) c
Range.h% J, B4 `4 e# a. Q8 Z# T. L7 o
一定数量的单元格,可对单元格进行单个或多个单元格进行操作。
: B9 a! h8 k6 T1 K' W* u- m  5 @2 K  k7 n3 q9 V
3、导入Excel的整个类型库, ?( A4 d! E- N, C8 v  E
接口对应类只是对接口的属性和方法进行了封装,而Excel中的数据类型,如枚举类型却并为并不能使用,因此,为了更方便的操作Excel,还需要导入Excel的数据类型。4 e: }+ G9 Q& C9 x
通过查看导入接口对应的头文件可以发现,在所有导入接口的头文件中,都会有这么行:6 @2 c0 e4 z' s! ^% x
#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace
0 ^, Z/ E$ S2 h7 Y0 N) E这行代码的作用是导入Excel整个类型库到工程中。
  ?- A! J5 ]& T- e5 q由VS2010自动产生的导入代码存在以下几个问题:
8 f9 Q. z0 A3 Y(1)如果导入了多个接口,每个头文件都会把类型库导入一次,如果引用多个头文件,会导致类型库重复导入。) [6 m' y) n2 D1 g
(2)Excel类型库中有些类型会跟MFC类库的某些类型冲突。2 Z: Y& u& ~: D
(3)Excel类型库的某些类型跟其他Office和VB的某些库相关,如果不导入相关库,将导致这些类型无法使用。。
* n* w& e7 h0 ~$ h以上三点问题的解决方法如下:1 A1 j0 y4 I. f: d2 A' Z
(1)仅在_Application接口对应头文件中导入Excel类型库。
' x' h3 _3 I0 ^& r(2)对冲突的类型进行重命名。
5 u8 h4 z6 K* C% Y( G! R/ J(3)在导入Excel类型库之前,先导入Office和VB的相关库。- u3 z8 K$ x/ a: O
更改后的导入类型库的代码如下:9 k- k7 J& _1 s
  7 r8 m4 ]7 |0 _- {4 ^' c2 R7 E7 k
/*导入Office的类型库*/3 F3 H$ H" {' K  p
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL" \
4 x3 p2 b- C6 ]' X; `% lrename("RGB", "MSORGB") \% V) t& V4 j' ]+ ^0 t( B
rename("DocumentProperties", "MSODocumentProperties")* ?, u! a' C! e$ `
using namespace Office;8 Q; }% K# H# J, Q5 k- c2 v
  
' F& x/ A- v. n4 q/*导入VB的类型库*/( m6 _0 L1 U  b: S7 c5 Q) t
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"
) ]+ ?( J5 C) T# _, F; w4 m4 Musing namespace VBIDE;
* m4 R6 [; k  e" R" w& g! N3 G: @  
0 P& A; G( @# R, z. I/*导入Excel的类型库*/
5 k/ E9 x! s/ C9 T! @0 `9 k: {5 T  f1 T#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" \$ r2 m& t$ o$ v% W
rename("DialogBox", "ExcelDialogBox") \# ~+ g$ i5 Y$ _" x4 _- r
rename("RGB", "ExcelRGB") \
5 `) z' d5 b- n0 H0 Lrename("CopyFile", "ExcelCopyFile") \
. x3 f* `; p, j: M0 Z) b. srename("ReplaceText", "ExcelReplaceText") \
/ _5 Z" [5 j# {" X1 E; c3 Xno_auto_exclude
, I% Q( s" E) K4 zUsing namespace Excel;  _+ O* f6 p/ b% @! Y
  
6 Z* h3 l, D- S; s编译程序后,会在DebUG或Release目录下生成三个文件mso.tlh、vbe6ext.tlh和excel.tlh。通过打开文件可知,该三个文件的命名空间分别是Office、VBIDE和Excel。导入了Excel的整个类型库后,就可以使用Excel中的所有类型了。
( e/ l% F# D2 q7 g0 N( r  + ^+ D' K6 c% O+ h, M. `
4、操作Excel步骤
7 L: o* ^4 \- @% o操作Excel的主要步骤如下:6 j) Y0 s& G* v6 \3 h
(1)创建一个Excel应用程序。& r3 E. B: g) l, c: V. l1 f/ d
(2)得到Workbook的容器。/ f4 Q& c7 |9 ~1 Q9 T
(3)打开一个Workbook或者创建一个Workbook。. {8 G6 p/ w. j
(4)得到Workbook中的Worksheet的容器。
% u( E3 M, ?; z7 t2 ?* [  ](5)打开一个Worksheet或者创建一个WorkSheet。3 L& v7 L# ?. t; z. X
(6)通过Range对WorkSheet中的单元格进行读写操作。
: f6 m0 i% r$ L: r(7)保存Excel。
6 N6 n& N1 E% r1 O% T' W(8)释放资源。6 i; f6 U7 ^, I- Z$ {/ W7 _
  
- ^& i/ a* X9 C- O7 D5、批量处理Excel表格
; K+ m) f1 P  w; D  c& _VC通过OLE/COM操作Excel,是通过进程间的组件技术。因此,每次读写Excel中的单元格时,都要进行进程间的切换。当数据量大,如果一个单元格一个单元格的读取,主要的时间都花费在进程切换中。因此读取多个单元格,将可有效的提高程序的运行效率。0 P0 x) f7 r* O
对多个单元格的读写操作可以通过CRange中以下两个成员函数来完成。+ d: }6 {& @' L% P
VARIANT get_Value2();7 G, v+ T7 [* J* h
void put_Value2(VARIANT& newValue);0 _; H/ ~" T3 N4 C" |5 e
其中,输入参数newValue只要输入一个二维数组,即可实现向Excel中一次写入多个单元格的值。
% e7 i' X2 f2 i0 F' i$ x其中,VARIANT中实现二维数据的方法可参考) [# c6 a) Z/ U! ~# D% \; \0 a
http://www.cnblogs.com/xianyunhe/archive/2011/09/13/2174703.html1 n7 k9 a8 R! R6 W+ m; Q5 K% Q
当然,在对CRange类进行操作之前,要设置CRange类对应的单元格。
4 Y+ W. b! k$ B7 D: U  / b1 c# g. x, G! G
6、Excel表格的保存
4 j2 @4 q9 [( F$ d  n8 K(1)如果要保存打开的工作簿,使用CWorkbook类的Save函数就可以保存工作簿,原文件将被覆盖。: w" h; ]4 @% e  ^9 u
(2)如果是新创建的工作簿,或者是要另存为,可使用CWorkbook类的SaveAs函数。/ A! K7 X5 n- {- [
SaveAs的参数比较多。其中,第1个参数是设置要保存文件的路径;第2个参数是设置文件的格式,可在MSDN中查看枚举类型XlFileFormat来了解Excel的文件格式。经过测试,在本文所用的测试环境中,Excel2003的文件格式是xlExcel8,Excel2007的文件格式是xlExcel4。
3 V# q3 d; h! X9 z  
* @5 r9 _" m- M$ r1 _# S# r7、获取当前Excel的版本2 Q( q- {& z0 D& h# U
可以通过CApplication的get_Version函数来获得Excel的版本,其中,Excel2007的主版本号是12,Excel2003的主版本号是11。
# Q0 C- x3 q% K* f& y  
* Z4 G: q; T: S9 F8、示例源代码9 x- a, H0 j/ T1 S
主要代码如下:
; C& a) c; N* @) g8 G6 d. |+ M6 I  , l6 v2 S1 y  {% D' s/ R
' b1 H- Z) _  A8 n& b) u

+ T4 c% X0 B  z( i    m_LisTCtrl.SetExtendedStyle(LVS_REPORT | LVS_EX_FULLROWSELECT);
# p0 Q1 p+ i. @0 [- G" @0 P1 x
6 E. v/ @9 x. }$ L' G( k  f6 S    CApplication ExcelApp;
/ \" D/ Z3 ?) J, x: ]2 G    CWorkbooks books;  C0 K: z3 z. P0 k
    CWorkbook book;- w, d; ~! t1 d' f4 h* I
    CWorksheets sheets;
' P! E. q0 f& L- y! c    CWorksheet sheet;
6 A4 n" \  w6 Q. \- y$ B    CRange range;
1 n6 ?8 V' i% V* h$ Y    LPDISPATCH lpDisp = NULL;+ S$ T- `% @# d3 P: w/ Z

0 a; a! Z% i: Z& e: b    //创建Excel 服务器(启动Excel)
! h* ^  H; ^& W9 O    if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL))
) R- T# ^; `, E! A    {( C: V" |2 ?. K/ z1 q' G1 O$ Q8 c2 I3 u
        AfxMessageBox(_T("启动Excel服务器失败!"));
, c7 {5 ~9 ]6 B7 E" {        return -1;
$ P$ b# Y5 I9 x- A; A    }
; a! m4 O# [1 O; g4 n7 Q/ B. B5 ^7 \8 [7 j6 ?8 ~* Y8 j
    /*判断当前Excel的版本*/
$ g% U# L  H2 U2 B! u    CString strExcelVersion = ExcelApp.get_Version();* r9 O1 R$ F. O9 p! M
    int iStart = 0;. `- {4 C8 ]/ t* v  i% [  M6 f
    strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);6 y. Q. @1 M% \3 N
    if (_T("11") == strExcelVersion)
3 K  w! N. {" P4 d  X    {3 B5 ^" K( x0 \! R% V4 d2 x
        AfxMessageBox(_T("当前Excel的版本是2003。"));
" {( H( f1 m8 y: J    }
( |" ^' ~3 g- U- x3 e* A: m% l    else if (_T("12") == strExcelVersion)4 l9 m3 t* r/ d  t) h
    {: x- M! s; w8 h+ x# _: ^/ o8 _1 u
        AfxMessageBox(_T("当前Excel的版本是2007。"));# v2 A$ L% X) R* m& [6 ?, _
    }
4 p5 R: n7 O4 G0 P0 R    else: t/ `! f2 b+ _' j+ ?0 U& _1 d
    {
, ]3 K3 N' m, q8 x        AfxMessageBox(_T("当前Excel的版本是其他版本。"));
# r& k& B3 L. e5 D$ r$ k. t8 x    }$ A; H- ?/ h; q; H& R9 o( ~
2 g- {0 {! Q. {/ l; n' w
    ExcelApp.put_Visible(TRUE);
' c- n5 G, K( q1 v3 K; h* ~; N    ExcelApp.put_UserControl(FALSE);# W6 V( N( N7 D

/ ]) K# p8 m4 t3 p4 z( Q    /*得到工作簿容器*/
" U" V  T( K1 J8 ~1 a    books.AttachDispatch(ExcelApp.get_Workbooks());
3 F( F; _+ ~6 {, f
- @9 `4 T6 ~' J  D" ?    /*打开一个工作簿,如不存在,则新增一个工作簿*/
  f( W" P, M0 L$ t/ r2 P    CString strBookPath = _T("C:\\tmp.xls");
* x4 F+ k: G& ]9 A    try' M" o& ?2 J* E" p7 N! V9 j
    {
9 X& \3 ^0 D0 J) {        /*打开一个工作簿*/& X# T1 n1 _' B- F+ u4 B+ Y/ P
        lpDisp = books.Open(strBookPath, / B% A5 e/ ]& E2 N
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,, J: P, r& c" M% i
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
* Q+ C  q% M3 J# J            vtMissing, vtMissing, vtMissing, vtMissing);
' N! q: Z2 i, @( B3 K# @) }1 i' v        book.AttachDispatch(lpDisp);4 M1 l, Q" D8 _: [$ X$ E) z% O
    }' Z3 Y1 F& @, T. R) I$ y6 x  a0 c# O
    catch(...)- C" ?' f4 D% F! S! `1 t
    {% b1 L% ^+ V# x7 Z! u0 \' {
        /*增加一个新的工作簿*/' D7 d, s8 m$ x7 S  q1 G) r2 t$ o
        lpDisp = books.Add(vtMissing);7 c9 D$ z  }5 s
        book.AttachDispatch(lpDisp);
; \2 p$ O4 z  Z0 o, t' S    }
6 H& S& C5 A3 `, A/ o! s/ k     
9 \4 Q8 o; X. V& F# n  D- ~* m1 x  E! L- q8 x* W8 s* ~  s0 R
    /*得到工作簿中的Sheet的容器*/9 j2 r2 M' C8 \& T" O6 e! o
    sheets.AttachDispatch(book.get_Sheets());
  h" _+ \" Q5 h1 i6 ~
' F7 C6 w5 ]+ ?. X( t    /*打开一个Sheet,如不存在,就新增一个Sheet*/
: y+ w5 v& b0 h9 E7 [+ }6 r$ D    CString strSheetName = _T("NewSheet");' P9 N0 Y& [( C  \2 I! o* _- B9 h
    try# V/ J* k+ X6 b% d& W2 R. I
    {) m9 ~/ v) v$ R$ E: ~4 S* d! M7 M
        /*打开一个已有的Sheet*/  b1 }, \% K* M2 {
        lpDisp = sheets.get_Item(_variant_t(strSheetName));
) l2 u: v$ @# Y# x! k0 \7 H* V! d        sheet.AttachDispatch(lpDisp);
% _* C6 s! k" p5 h1 Y& G    }, r. w8 l9 n& }
    catch(...)* p6 a5 r0 A, Q5 }
    {
' r- Z$ t+ [% p/ W  g9 z7 _% z. X, E        /*创建一个新的Sheet*/% T4 i' k2 c- b
        lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);
% v. b3 j# k# A) O! O! T( A        sheet.AttachDispatch(lpDisp);
  X9 K* J* L  }* U- _6 ?; Z( X+ J        sheet.put_Name(strSheetName);
% \/ H& B# l1 ?    }
2 ^" t3 x* L1 X* f5 w8 l+ W2 D5 Z5 ^
    system("pause");- N% @) B  Q7 A

1 U6 q. }% `: F. F: C    /*向Sheet中写入多个单元格,规模为10*10 */
; o# e- `5 q+ Z. c$ H0 ?    lpDisp = sheet.get_Range(_variant_t("A1"), _variant_t("J10"));
5 N: `: y! r1 G7 Q1 }1 k# S    range.AttachDispatch(lpDisp);
! U6 x" A* o+ L( M4 p) j$ s0 G! B- X  H2 _# A% G9 y
    VARTYPE vt = VT_I4; /*数组元素的类型,long*/1 i1 y  b, [& J  ]& R% i
    SAFEARRAYBOUND sabWrite[2]; /*用于定义数组的维数和下标的起始值*/1 d- {2 x5 F1 W% y% {
    sabWrite[0].cElements = 10;
7 M5 \0 |, @" K    sabWrite[0].lLbound = 0;( c4 j: f* Q2 F& s$ X2 T
    sabWrite[1].cElements = 10;
6 x) y- M3 s2 t  _, g0 a    sabWrite[1].lLbound = 0;
8 B# Q4 ^. q3 X9 ^: i1 t
( T5 L4 H% q: ]+ w, e0 T) `1 A    COleSafeArray olesaWrite;: t! F8 W- A1 i2 N/ U: I. q& l
    olesaWrite.Create(vt, sizeof(sabWrite)/sizeof(SAFEARRAYBOUND), sabWrite);+ F$ O* p. {; q# T) u" r5 W0 T7 w9 F

/ Y6 z- \: F6 a" L2 i* B' X* ^  x    /*通过指向数组的指针来对二维数组的元素进行间接赋值*// o7 _5 z$ v6 }# |5 ?0 i
    long (*pArray)[2] = NULL;  O+ [, \( K5 N! t1 L& W8 V
    olesaWrite.AccessData((void **)&pArray);
# z% u. R3 _- e# r, n2 a4 J    memset(pArray, 0, sabWrite[0].cElements * sabWrite[1].cElements * sizeof(long));
1 F8 \$ L+ n4 x( {- Z/ I" g: a% z$ G7 K( U: b; \) A
    /*释放指向数组的指针*/8 }* z( d6 m; O( q8 R$ v+ ]
    olesaWrite.UnaccessData();% v  `" A: s# m# ?8 c- [; R, Q
    pArray = NULL;- Z: k3 D0 |" i  ?+ y3 j$ v
: V, H' f5 u0 ?7 h# c
    /*对二维数组的元素进行逐个赋值*/" B# w/ D( x$ b1 x4 E# C
    long index[2] = {0, 0};2 w: R* q" a' `6 a. m
    long lFirstLBound = 0;- I4 n& U6 \; u, |7 p" l
    long lFirstUBound = 0;- M. J* O% `+ w- M6 d7 i! R+ n9 e
    long lSecondLBound = 0;$ Q7 T7 L8 a  Y
    long lSecondUBound = 0;! L7 r3 S: \6 P2 z4 X  G! N2 `! ~
    olesaWrite.GetLBound(1, &lFirstLBound);
/ b& K+ l: p) q6 h, M$ H, L9 ~9 e9 J0 \    olesaWrite.GetUBound(1, &lFirstUBound);
8 Y0 G9 k. p; z+ m3 F    olesaWrite.GetLBound(2, &lSecondLBound);
: T: |# k$ ?" ~  X! h    olesaWrite.GetUBound(2, &lSecondUBound);6 w# r8 X2 u8 E* H  E. P) `; F3 F
    for (long i = lFirstLBound; i <= lFirstUBound; i++); Z8 w. o* `, O! n! p
    {  t  y6 Q' @; Y# e2 v1 O' }
        index[0] = i;
9 F" n8 E) w9 V$ v! s) X        for (long j = lSecondLBound; j <= lSecondUBound; j++)+ r* u4 h0 R! R4 L5 E6 @' s: P
        {& P+ N  b  w3 ^  p3 z, t4 [
            index[1] = j;
5 v' a: _; u+ u" ?; q) g            long lElement = i * sabWrite[1].cElements + j; 6 R- i% {" O  k5 J5 A; M2 A
            olesaWrite.PutElement(index, &lElement);- ]9 a, U  Q" E9 ^
        }
/ A% u$ F9 F7 G9 h7 ]    }: n3 a) ~, u- ?
3 u# K3 u' ]) d
    /*把ColesaWritefeArray变量转换为VARIANT,并写入到Excel表格中*/! ?) m5 |9 x) Y0 A' ]# m
    VARIANT varWrite = (VARIANT)olesaWrite;
+ e3 b. P, i4 v    range.put_Value2(varWrite);) f" m4 j) d4 |+ x- h1 r, P# y& r

. y; E* c- ^$ V& O) _6 `+ q  T) v; H    system("pause");7 W( m: M2 y; i+ R- n* y  G
6 K2 o% h8 Z! J! ]- [8 `) h
    /*根据文件的后缀名选择保存文件的格式*/4 i# P5 ]& l- M. b
     CString strSaveAsName = _T("C:\\new.xlsx");: K# ?% s# t- l- c2 M1 k" h
    CString strSuffix = strSaveAsName.Mid(strSaveAsName.ReverseFind(_T('.')));
/ G: T# o9 ?2 Q4 r' U# V' w0 }    XlFileFormat NewFileFormat = xlOpeNXMLWorkbook;
) v8 C% t" Q* p3 _    if (0 == strSuffix.CompareNoCase(_T(".xls")))
: j, r% J# q# W1 p    {- l2 X2 g3 _0 X. Q; b+ F" @6 g. k
        NewFileFormat = xlExcel8;
$ j/ z: @2 e& A    }; ]$ h- w5 m$ I! {  B3 r$ `
    book.SaveAs(_variant_t(strSaveAsName), _variant_t((long)NewFileFormat), vtMissing, vtMissing, vtMissing, , p, T' O2 ]3 L, r, r
        vtMissing, 0, vtMissing, vtMissing, vtMissing,
6 f- p# A  [! v# g  R; a        vtMissing, vtMissing);
* x2 \# p$ F) @1 D$ p6 X
, W, c. \0 O! e7 @. ?% e3 r$ \! ~    system("pause");
% t5 y! ~5 o% j" J, M5 n
3 P& J# G$ V0 u; l# |    /*读取Excel表中的多个单元格的值,在listctrl中显示*/
  ^6 |; X3 b( k3 _0 F2 g* E    VARIANT varRead = range.get_Value2();
+ w" I# _5 {2 G    COleSafeArray olesaRead(varRead);
! `% K" Q: ?) ]$ w
. ^7 M& p, Z9 Y9 ?! _4 k4 N, b" ]+ H9 `    VARIANT varItem;# F; x7 a0 C! q
    CString strItem;$ j% Q0 X) Z) ]4 C( A! F5 ^
    lFirstLBound = 0;
3 \! m& _0 V: B    lFirstUBound = 0;7 N2 H" l5 e8 l/ t( x
    lSecondLBound = 0;( t# n0 y/ W' A) B9 Y, O
    lSecondUBound = 0;$ S- O) V) @% B& g3 k: o& Q
    olesaRead.GetLBound(1, &lFirstLBound);
- }# u4 b4 W; _3 ]    olesaRead.GetUBound(1, &lFirstUBound);) `: o0 \9 G6 Z. r, G3 r& ?
    olesaRead.GetLBound(2, &lSecondLBound);
" y: g: m( p* O* i    olesaRead.GetUBound(2, &lSecondUBound);
; D) ?' j) i  X% \; I, m    memset(index, 0, 2 * sizeof(long));
9 D! t3 ?* ?2 F# z$ ~  u2 G/ E    m_ListCtrl.InsertColumn(0, _T(""), 0, 100);
3 \# ~* M. _& I! x( C    for (long j = lSecondLBound; j<= lSecondUBound; j++)
5 J# m' T2 }4 A2 t9 g; {) J# s) c    {( _, A9 p5 Z# ~3 ~7 w  |
        CString strColName = _T("");3 U3 K; {/ T2 q6 A9 |2 P8 [; J- Y
        strColName.Format(_T("%d"), j);
+ Z8 @1 K  \7 R* F$ y        m_ListCtrl.InsertColumn(j, strColName, 0, 100);8 y) M; }) n9 ?" L2 r2 i7 x
    }0 ~& Q7 [5 s1 K
    for (long i = lFirstLBound; i <= lFirstUBound; i++)% W9 F" G; p& a% P8 b
    {
5 v4 m4 x! S+ I% Y* e2 r        CString strRowName = _T("");0 ?% E# U) w4 E5 G; M/ \+ m
        strRowName.Format(_T("%d"), i);8 Z. c- r- q. M3 M
        m_ListCtrl.InsertItem(i-1, strRowName);% y8 z6 w( O" J! H8 U, `

3 @. W. q# J9 u6 _" t/ w$ u1 g& V        index[0] = i;  G& R4 r8 q2 m* L
        for (long j = lSecondLBound; j <= lSecondUBound; j++)! p3 X6 J, Z; O/ N1 j
        {
5 E7 t" m8 G; d5 B* d            index[1] = j;
7 B' {6 J) ]% V. \  Z& H9 V( o            olesaRead.GetElement(index, &varItem);7 {9 B& I' b$ E) G8 Y

7 }+ E$ m- _2 D3 \' `" F' x            switch (varItem.vt)
( E$ s. n/ i/ J            {& x0 d7 b# R7 o- e0 m
            case VT_R8:, |7 V9 P5 u  g7 G2 K
                {
/ F! M$ G) i% e                    strItem.Format(_T("%d"), (int)varItem.dblVal);
: w3 y# S/ b4 o  z/ l1 }) F2 s# G                }) Q4 t" J' B% e1 I! b$ A6 V- h8 I" D* {
1 B- m# r3 q& u; Y. O
            case VT_BSTR:% o' H8 y  ]  T- u* [6 q8 P- z
                {3 A9 @& z) k' e1 a2 D
                    strItem = varItem.bstrVal;
; ]+ k1 N: h* |* |, _7 B# W                }
' W1 @5 B2 c% }
+ U9 x3 {& S5 A* ^; M            case VT_I4:
$ K4 W& [( U/ D  F2 k                {6 ]; r% A; M$ O; F7 D
                    strItem.Format(_T("%ld"), (int)varItem.lVal);$ N; t. @7 M( T
                }
. u. O4 o3 n  R; K
1 _$ k# E$ o" g: H! a5 ], f            default:3 z. Z! [- g& M; F9 @) U  @
                {+ I6 g% x+ T7 j$ Z' h
' p/ v; z8 m9 ^+ A/ h
                }8 p% _) ~, B' [9 E7 H
            }
5 z& f; [1 I2 r# l( j( o; x. U: |0 \
2 h, m' W# j0 c* w$ I            m_ListCtrl.SetItemText(i-1, j, strItem);
% s4 t- l' E' X4 N6 G. v        }
9 g: K" J% n7 Y' `: ~( U    }( B- r$ e7 o0 M: {- ~

7 h2 H' N' U: D0 _! o- z/ t. F5 X5 O% J& Y3 m& e2 j/ R

# _9 e* e0 n- i- I    /*释放资源*/4 n# m0 R, M2 Z) F/ U" [
    sheet.ReleaseDispatch();
0 B# Z0 |! f; N) J1 Z    sheets.ReleaseDispatch();3 u* C2 H# E. d% t' G; d5 D% S
    book.ReleaseDispatch();$ H: |! d% ~4 ?; j: ?4 ^
    books.ReleaseDispatch();
7 {2 c6 C* C; p+ [# h    ExcelApp.Quit();
  d0 ?. v5 U3 N7 m    ExcelApp.ReleaseDispatch();
$ q# e- ^+ q2 ^7 n, G; s8 E: F9 X+ |# A
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了