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 6315 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表格的操作。
! y4 k6 L: q  J/ x  
* N+ X2 T- F* g# U1 ?$ V本文源码的应用环境说明:' B8 `# G$ p) i3 `4 e4 P' B
Windows XP SP3. ^5 ^# J+ z) o" j
Microsoft Visual Studio 2010+ w# s3 F* ]) B) ~9 u9 i: J$ c
Microsoft Office Excel 2007
5 Y* t* O( u4 q  $ Q, ]# e0 l4 Y  a7 h/ y& v9 `( o
1、添加OLE/COM支持。
" f, x/ H1 _& O# E! X8 p" W( k首先,应用程序必须添加对OLE/COM的支持,才能导入OLE/COM组件。0 J, j) X9 I3 s$ k; e8 E0 \
本文使用的是MFC对话框程序,在创建工程的向导中选中Automation选项即可为程序自动添加相应的头文件和OLE库初始化代码。
( M* F6 @, Y8 U0 p通过查看源代码,可以知道在stdafx.h的头文件中,添加了OLE/COM很多类所需添加的头文件。) S. T1 H7 R1 l, [8 F$ C( }8 N1 O
#include <afxdisp.h>        // MFC 自动化类
# W( V, w. ~# Y7 @% U$ R同时,在应用程序类的InitInstance函数中,添加了OLE/COM的初始化代码,如下所示:
  ~0 k+ T7 ^  T% K6 h// 初始化 OLE 库7 l0 B9 R" k3 t! h  m8 t
if (!AfxOleInit())
2 o( ~3 y! L9 _' J7 @/ f{3 d) h/ P/ F& a3 D/ B* C, O
AfxMessageBox(IDP_OLE_INIT_FAILED);( W. _+ R/ N: N1 U0 w
return FALSE;" t* Q: c4 \( S$ p7 I7 k( w, ?$ E( ?
}  u5 H; z" u  f( F" t8 }
    j: C3 z; q' ^+ g0 K. R
2、导入并封装Excel中的接口
1 |$ {$ F5 Z% H8 eExcel作为OLE/COM库插件,定义好了各类交互的接口,这些接口是跨语言的接口。VC可以通过导入这些接口,并通过接口来对Excel的操作。
$ q, T: e) s3 \3 [+ ]# U由于本文只关心对Excel表格中的数据的读取,主要关注几个_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range等几个接口。Excel的各类接口的属性、方法可以通过MSDN的Office Development进行查询。
: @$ z& ~( i6 V5 lVS2010导入OLE/COM组件的接口的步骤为:Project->Class Wizard->Add Class->MFC Class From TypeLib,先选择要导入的组件所在的路径,即Excel.exe所在的路径,然后再选择$ {+ P, x) F: N/ L5 q7 ]
要导入的Excel类型库中的接口。) n( X# q, B! l) V
在完成接口导入后,VS2010将自动为导入的接口创建相应的实现类,用于对接口属性和方法的实现。由于标准的C++没有属性访问器,只能添加一个两个存取函数来实现对属性的访问,通过在属性名称前加上get_和put_前缀分别实现对属性的读写操作。即,由VC自动完成C++类对接口的封装。
$ r: H0 t+ f8 l2 W  j7 r6 }  
" Y) j7 j0 p5 m% T本文所导入的接口对应的类和头文件的说明如下所示:
0 B9 g, X2 d" {4 {( y" e6 O9 n  8 i" e. W% i- w5 M1 N: _
Excel接口$ a0 L, F8 C/ d- U3 ]
导入类3 I( b" `  j: R3 ]5 `- a, H
头文件
& ]' M1 g1 K# b3 p0 L7 t( A9 r说明+ x5 [( {8 H0 s* e# y
_Application
) ^( f; c: k+ I1 T& W; O% TCApplicaton: P* e+ g; H0 T- c5 Z
Application.h
& }1 i# ]: y: `& u, }Excel应用程序。. R$ E& n8 h5 f$ h3 [6 B6 k
Workbooks  L* j% T  S  Q* a& Z
CWorkbooks( {* Z' L: {9 P
Workbooks.h1 B6 y6 t; y0 L) k1 ^
工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。
. Z0 p2 L8 s! D9 ^_Workbook" S5 V  _# K% ?* q% Z8 K6 e7 v
CWorkbook
3 R4 A, y8 u' h. }. T. h& F; dWorkbook.h$ V9 k7 C9 X8 ~4 w5 Q
单个工作簿。% k8 e( x2 ^  k3 v) b9 C0 s
Worksheets, p# ~, o8 V; _- e& |% E6 {
CWorksheets3 S/ p! T4 X+ A* |; a& O* `
Worksheets.h
  _3 e$ Q0 r& \) w" r) u' T/ _单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。
" i* F9 C( N# U7 J_Worksheet! C  O) M3 y; d9 b8 m
CWorksheet
* }3 i2 ~* e( MWorksheet.h
# Q$ c4 r  g, j/ G" i单个Sheet表格。4 Z5 S0 }1 ]( ^: C
Range
! K3 O# t% i5 @! N2 aCRange
' T. O' e7 E! F9 K8 BRange.h, z/ N& K. r4 }- P6 S& l7 z0 J
一定数量的单元格,可对单元格进行单个或多个单元格进行操作。7 W* g( d- j' g
  
2 o9 l- ~% t3 q! w2 e3、导入Excel的整个类型库
2 }9 \, J; \/ H. w% y接口对应类只是对接口的属性和方法进行了封装,而Excel中的数据类型,如枚举类型却并为并不能使用,因此,为了更方便的操作Excel,还需要导入Excel的数据类型。( }3 @! W6 b7 _. o1 U4 `8 a( I0 L
通过查看导入接口对应的头文件可以发现,在所有导入接口的头文件中,都会有这么行:! `2 Q' o& z$ _, k* z  E: x$ f& @
#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace
% A0 `. c4 D- F* y/ v% {这行代码的作用是导入Excel整个类型库到工程中。
1 w& R5 c" i# t: D由VS2010自动产生的导入代码存在以下几个问题:
+ v) t- O: i) q4 l$ ](1)如果导入了多个接口,每个头文件都会把类型库导入一次,如果引用多个头文件,会导致类型库重复导入。0 R) p; C. M& C
(2)Excel类型库中有些类型会跟MFC类库的某些类型冲突。4 L" M1 w3 l6 k& O  Z4 m& o
(3)Excel类型库的某些类型跟其他Office和VB的某些库相关,如果不导入相关库,将导致这些类型无法使用。。' r+ H# U1 a8 x* T9 \) r
以上三点问题的解决方法如下:
" o1 K% U  Y6 L2 v6 B" D% X(1)仅在_Application接口对应头文件中导入Excel类型库。- ?8 {* {+ \3 Z9 \4 d
(2)对冲突的类型进行重命名。- v7 e' H% [- I/ q( X
(3)在导入Excel类型库之前,先导入Office和VB的相关库。1 [! M: F( y9 z! U( F3 o
更改后的导入类型库的代码如下:9 D7 E) s6 @* N6 c6 p5 u+ H, [
  
- [' l. z1 d7 f) J+ |) p& ?/*导入Office的类型库*/8 J  k" Y6 ^; M1 R2 q
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL" \4 n9 l+ o0 r' S9 h% n
rename("RGB", "MSORGB") \
. D" N6 J) J& b$ R; @# y5 w/ H: F: irename("DocumentProperties", "MSODocumentProperties")
- h( Y/ v0 r) C* C, @9 \using namespace Office;% `* \4 c/ A5 v9 X
  6 B" |: t) {" p$ @
/*导入VB的类型库*/8 m" D- Z6 v. `* J
#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"7 M* w3 H; |3 Y; u4 C8 A) O
using namespace VBIDE;
; \7 s7 \( _( b  
+ U) M2 e8 ~; g! h% z+ F/*导入Excel的类型库*/" e1 C( T$ J# V; ?
#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" \
/ t9 ~8 x: S" {' T+ H/ E) m% @rename("DialogBox", "ExcelDialogBox") \( Z* D% ~' s6 v! C$ t- G- ]$ J
rename("RGB", "ExcelRGB") \- N, B& F( s1 v+ J
rename("CopyFile", "ExcelCopyFile") \
( Y, p' |' Z' s- ?/ b# Frename("ReplaceText", "ExcelReplaceText") \
  E1 D. L3 G% S1 w5 Jno_auto_exclude
. b' u9 F1 H$ N  ~' pUsing namespace Excel;! V) W/ ?; N" R! R  v
  
5 R4 K) D. y% W6 \0 o+ T( W编译程序后,会在DebUG或Release目录下生成三个文件mso.tlh、vbe6ext.tlh和excel.tlh。通过打开文件可知,该三个文件的命名空间分别是Office、VBIDE和Excel。导入了Excel的整个类型库后,就可以使用Excel中的所有类型了。
$ a. u5 }9 h' E9 o9 N: Q- X  / c* x  z, h& a3 |$ Y, U
4、操作Excel步骤
% P& U( X" X* i7 ]/ ~操作Excel的主要步骤如下:
/ z( _- m! [3 A) G(1)创建一个Excel应用程序。( _2 e3 d/ ^/ S* C' I7 t& z- ^
(2)得到Workbook的容器。
7 ~2 ]6 t, M' N. j& e(3)打开一个Workbook或者创建一个Workbook。) `2 C9 \/ v9 J6 n
(4)得到Workbook中的Worksheet的容器。
3 g) e6 L. y# T) g( U(5)打开一个Worksheet或者创建一个WorkSheet。
3 g/ C8 Y) }, U  w(6)通过Range对WorkSheet中的单元格进行读写操作。& g8 L: I5 d  n& R& {3 X
(7)保存Excel。" j+ F4 ~- l. l- j+ r- |2 i
(8)释放资源。, o7 B& [% ]; }- w
  * q. }: i% g5 {( B! ~% W3 g( u$ q
5、批量处理Excel表格6 R, j8 R5 H1 g& e
VC通过OLE/COM操作Excel,是通过进程间的组件技术。因此,每次读写Excel中的单元格时,都要进行进程间的切换。当数据量大,如果一个单元格一个单元格的读取,主要的时间都花费在进程切换中。因此读取多个单元格,将可有效的提高程序的运行效率。- `7 I5 z, ^- l' N- V' H- W1 t
对多个单元格的读写操作可以通过CRange中以下两个成员函数来完成。
/ t# g9 Q$ Z: ^/ [1 _/ J* z  PVARIANT get_Value2();, b% X+ W  S/ B  y5 d" T
void put_Value2(VARIANT& newValue);7 A2 c2 R) O% B: N: K
其中,输入参数newValue只要输入一个二维数组,即可实现向Excel中一次写入多个单元格的值。* C, m2 N( [/ g; H) b
其中,VARIANT中实现二维数据的方法可参考  Y+ L- {1 m( k! Q/ J
http://www.cnblogs.com/xianyunhe/archive/2011/09/13/2174703.html* r( r3 C; @' A" j& u: t
当然,在对CRange类进行操作之前,要设置CRange类对应的单元格。5 A% R5 O4 [+ L) ^: y
  
' n% G& v& a% q- ~6 }2 c. e. I6、Excel表格的保存
# K% I9 X( K5 E1 ~$ x0 ~& I(1)如果要保存打开的工作簿,使用CWorkbook类的Save函数就可以保存工作簿,原文件将被覆盖。0 z: [% O% D# l- i$ l/ ~. h
(2)如果是新创建的工作簿,或者是要另存为,可使用CWorkbook类的SaveAs函数。5 C- N) e! Y: u& X$ a
SaveAs的参数比较多。其中,第1个参数是设置要保存文件的路径;第2个参数是设置文件的格式,可在MSDN中查看枚举类型XlFileFormat来了解Excel的文件格式。经过测试,在本文所用的测试环境中,Excel2003的文件格式是xlExcel8,Excel2007的文件格式是xlExcel4。
* z# p+ m$ x8 F  m- P' n; E3 O  # k+ c7 E5 D) W# n  e
7、获取当前Excel的版本* Z; M! y7 F# z/ M3 \! U
可以通过CApplication的get_Version函数来获得Excel的版本,其中,Excel2007的主版本号是12,Excel2003的主版本号是11。9 g' G) _6 z: ~6 b
  4 k1 G9 q. ^, ?. P9 p' o' f" a
8、示例源代码% s9 b% o3 b  W2 k2 K
主要代码如下:& q/ G# g! q- x% |1 R
  
2 l7 b7 D6 {: V& g: Y) M- S( @4 h5 A  ]: \) B
& y9 r) O6 W# D: i& [: Y9 _
    m_LisTCtrl.SetExtendedStyle(LVS_REPORT | LVS_EX_FULLROWSELECT);/ e2 {4 Q# p/ Q; Y! i6 \
; w" @8 U6 b- {
    CApplication ExcelApp;& c% K+ ?8 E, C- c0 S$ X* ?; [
    CWorkbooks books;
% d2 H: L* r) _    CWorkbook book;
! a& m  l- R# H4 V  i+ L; r    CWorksheets sheets;$ d' Z' @" u% R- {4 H; I" P
    CWorksheet sheet;* w7 n' i! ^; `" v7 Y
    CRange range;* E. O, w! `' a% q
    LPDISPATCH lpDisp = NULL;
$ c- W9 L6 K$ _) [! z3 U4 V% k7 U* n, K4 Y$ g6 D. E
    //创建Excel 服务器(启动Excel)* I$ y5 n; J7 `9 o- W" W+ q
    if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL))
  S' \# K7 z* Z$ n    {
- w2 i0 J1 |  C" q8 Q& i        AfxMessageBox(_T("启动Excel服务器失败!"));
  I; U0 F  y& {% e1 R7 A( M        return -1;
6 b) `8 N" M1 H9 r    }
/ G8 D3 l+ J  X  ?) e0 e
: P* }" Q- H2 N, a    /*判断当前Excel的版本*/
- h  s: y+ e' i. F    CString strExcelVersion = ExcelApp.get_Version();& d( {$ A" ?& f: U
    int iStart = 0;
; @' d% j& [( g7 |    strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);; X' N% Z& r3 f' Z5 E! K
    if (_T("11") == strExcelVersion): ]8 p/ i: u0 u$ R
    {
8 Q0 a1 `" |* x/ Z4 {$ K' c        AfxMessageBox(_T("当前Excel的版本是2003。"));6 h1 @" H5 F5 Q. K- A  H! \4 |3 L
    }
* h& i, v. M( e    else if (_T("12") == strExcelVersion)
$ d- u; p* c  d5 S( e( X    {9 `- g; P0 w" O* G6 \
        AfxMessageBox(_T("当前Excel的版本是2007。"));
  G! i. |: z* d& J9 ~    }$ ?" |! X. o% O/ p7 n9 n+ m
    else
2 Y# U; n: ^& f5 H    {
0 c; L% o8 f* W! R! V- u7 v- D        AfxMessageBox(_T("当前Excel的版本是其他版本。"));
* v9 Q( F$ |6 c; [; a9 f* h    }
4 R- L5 G9 x( n0 J
# q' H& O4 T5 f  ^1 |0 U    ExcelApp.put_Visible(TRUE);+ M; L- w+ A1 F6 L+ u; c
    ExcelApp.put_UserControl(FALSE);
7 n# g% E5 _2 F0 _8 S
2 h$ |8 I! y& B" @# A3 `. _( M    /*得到工作簿容器*/6 s$ Q& D; {( W3 f6 i$ c
    books.AttachDispatch(ExcelApp.get_Workbooks());# K' @+ f; v  h; u* @1 a: P( y

5 \, K3 S- i9 k    /*打开一个工作簿,如不存在,则新增一个工作簿*/
- P: s% b5 Z6 c8 s5 ~# [0 ?" U% e. K  [    CString strBookPath = _T("C:\\tmp.xls");8 |3 O% R" a$ m: Q4 l4 L4 ^
    try
6 u8 Q8 w3 ]+ M9 N& C8 q' z    {2 c' N( z) ~- \) z4 W# e
        /*打开一个工作簿*/
/ \) f, E4 D3 F& {        lpDisp = books.Open(strBookPath,
! y# x, T4 S' L% }            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,3 I! b5 o, N) |1 d
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
+ s* J$ h( x3 z+ i- _5 h$ {            vtMissing, vtMissing, vtMissing, vtMissing);
* Y+ f" J$ B5 M        book.AttachDispatch(lpDisp);  G% r3 k* s5 H
    }5 J, G" K2 j! n# E8 X+ K( P' t4 T
    catch(...)  A+ X; ^7 m; K/ u
    {) O& @  C1 U* h" _+ B/ K# A% U3 a3 |
        /*增加一个新的工作簿*/
8 X2 C9 X" g6 S        lpDisp = books.Add(vtMissing);
/ z; F, S* ~2 T. N        book.AttachDispatch(lpDisp);
8 L( K* M, O& t7 m* ]/ L) I    }: }# V. t" X5 O* V$ N
     
6 g: ]6 e! E2 k; A; g4 t( t0 \% ?  N+ O& u
    /*得到工作簿中的Sheet的容器*/; j4 `- h6 n8 G, M2 M* w# @4 [
    sheets.AttachDispatch(book.get_Sheets());  g# _+ X' h: \- y

5 z' s/ F" t& h  }$ K7 S    /*打开一个Sheet,如不存在,就新增一个Sheet*/
& j6 _2 i1 p) q. w, h' M    CString strSheetName = _T("NewSheet");
7 ^: G+ E1 l+ U: p; A  S    try
! ?1 w/ o) D' O$ J8 q% ?    {7 Y/ s0 {4 X4 ~- @( f
        /*打开一个已有的Sheet*/
  u$ v: f$ X/ m' a/ O. B        lpDisp = sheets.get_Item(_variant_t(strSheetName));! O3 Q; W: i% H& d# _
        sheet.AttachDispatch(lpDisp);
  ^1 ~0 [& i, c; ~$ d) }    }8 L5 Z2 j( d6 `$ x1 b+ i8 v
    catch(...); n# k- w( z7 @  v2 D' _9 f
    {, `: f5 C& G; p9 v. ]9 d
        /*创建一个新的Sheet*/
) X" `( E  P& y! K' U5 f        lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);+ |# _6 k" r/ M) [6 Q
        sheet.AttachDispatch(lpDisp);
. v- B' V/ p9 |! K, n* f* V        sheet.put_Name(strSheetName);
  f$ `& w" @& ]3 @. M    }' _% I/ P9 u9 M& D
4 @% `' S: r; m1 e  B2 V
    system("pause");
9 k; a7 Y: W1 a( i' b& g( H" s1 X
+ _9 K1 u4 C, _0 m    /*向Sheet中写入多个单元格,规模为10*10 */
6 s% c% H/ G. U& D    lpDisp = sheet.get_Range(_variant_t("A1"), _variant_t("J10"));7 c0 u" i$ E: h
    range.AttachDispatch(lpDisp);
4 I  q7 a) u1 C( l0 W
1 @0 V- [' E- g$ Y" C    VARTYPE vt = VT_I4; /*数组元素的类型,long*/
/ L% c( ]4 f; X1 M4 x* a+ s    SAFEARRAYBOUND sabWrite[2]; /*用于定义数组的维数和下标的起始值*/1 N6 d7 `8 y2 f  d( _2 i$ }. Z  X
    sabWrite[0].cElements = 10;" q$ d4 H8 Q/ a2 |3 l) v
    sabWrite[0].lLbound = 0;9 ?* W, e$ W2 N/ P. ]
    sabWrite[1].cElements = 10;) l6 F- r3 @% g7 `7 X) ]
    sabWrite[1].lLbound = 0;
% @! P" o3 g" q! x5 ?: @) S! e9 R6 u  E, W* i5 N
    COleSafeArray olesaWrite;
5 u: o; U4 K7 W" G    olesaWrite.Create(vt, sizeof(sabWrite)/sizeof(SAFEARRAYBOUND), sabWrite);$ D  `$ G( L0 a

+ v' I% L2 V3 A! V! z' T# A    /*通过指向数组的指针来对二维数组的元素进行间接赋值*/; T& d6 L7 c( A7 w" k- }
    long (*pArray)[2] = NULL;1 E. Q. m* R% U9 I7 w
    olesaWrite.AccessData((void **)&pArray);
' q; N& w& b9 R# U    memset(pArray, 0, sabWrite[0].cElements * sabWrite[1].cElements * sizeof(long));
0 N# E  @& y$ T0 N  ~* G, D6 G7 [
    /*释放指向数组的指针*/; M3 Y9 Q0 c1 F: e. ]0 O/ E  a
    olesaWrite.UnaccessData();7 Y5 a4 K' N; @6 r$ S0 A7 T
    pArray = NULL;& \* W. d% x; I- y5 ~' y7 I, n

- k/ {+ x1 I' M    /*对二维数组的元素进行逐个赋值*/
& U, O0 F. y1 J    long index[2] = {0, 0};
1 c9 l% F- B- |" U( {+ T; y    long lFirstLBound = 0;
/ X' Z4 q8 h: V& Q* k' `* b    long lFirstUBound = 0;3 ^- Y. i. ]/ e1 e
    long lSecondLBound = 0;4 Q% v, c8 B7 W
    long lSecondUBound = 0;
4 x. R6 N! f1 L: ]6 a    olesaWrite.GetLBound(1, &lFirstLBound);
( b5 [  |- D1 _    olesaWrite.GetUBound(1, &lFirstUBound);9 Z/ X8 K3 {! s4 @* b! L; N, R) K
    olesaWrite.GetLBound(2, &lSecondLBound);
) z9 z% v3 F/ T/ R  I    olesaWrite.GetUBound(2, &lSecondUBound);' p& d0 ~8 b- b5 |# ^1 z7 Y# ~, l
    for (long i = lFirstLBound; i <= lFirstUBound; i++)
5 m$ ]6 {7 e! }" @    {
( \" m  @3 {) x  }$ s        index[0] = i;
" ?) b* l! d" f  M  b( s! i' r  z+ g        for (long j = lSecondLBound; j <= lSecondUBound; j++)
9 @& U# ]  d7 l& O8 ^        {
1 f" T1 r% S& f" n5 L& d$ H            index[1] = j;
: N1 [$ }* ~9 l6 Y9 X8 C            long lElement = i * sabWrite[1].cElements + j; ( Y* i* Q6 j# w- P
            olesaWrite.PutElement(index, &lElement);
& L, W) y; @, L5 n+ }& j- F# x        }2 a  @2 l! n+ S% f8 f
    }7 o/ f: x% N, Q3 @+ O

& j: Q) E4 J2 [5 _! ~7 Z' d    /*把ColesaWritefeArray变量转换为VARIANT,并写入到Excel表格中*/" ]- l0 L) g) v0 S2 s2 F  x( X
    VARIANT varWrite = (VARIANT)olesaWrite;
! |  E5 F2 W4 u1 q    range.put_Value2(varWrite);
6 Y$ Y7 I+ L: X5 B& _$ \; u* U4 b, B& l; J) `
    system("pause");/ v- Y) {9 V- ]- d0 G
/ W8 B% I. z& a3 L- X
    /*根据文件的后缀名选择保存文件的格式*/
# `& W/ ]. w1 L, }% R7 O     CString strSaveAsName = _T("C:\\new.xlsx");- X& \2 i" ?7 E! J9 B! Q3 R
    CString strSuffix = strSaveAsName.Mid(strSaveAsName.ReverseFind(_T('.')));* p/ N3 |' x/ p. ?
    XlFileFormat NewFileFormat = xlOpeNXMLWorkbook;5 y* \7 ~3 m/ S# `9 @8 @
    if (0 == strSuffix.CompareNoCase(_T(".xls")))0 w6 R; g4 B- L- E4 \/ I
    {5 X3 n! k8 w% w& P3 h
        NewFileFormat = xlExcel8;  m/ Z+ k. D6 u* ?( T! t' T. H
    }
9 H; C. ~1 a8 d' n$ ^! ^; z4 h' A    book.SaveAs(_variant_t(strSaveAsName), _variant_t((long)NewFileFormat), vtMissing, vtMissing, vtMissing,
* g& I" e( X  t& W0 @. P        vtMissing, 0, vtMissing, vtMissing, vtMissing,
& P' ?( z) R" T7 i& Y5 x8 A        vtMissing, vtMissing);8 g/ v) p) n" r# O' d
+ l7 Z* x: F% R$ t
    system("pause");: t. Z5 x" d% [+ S0 Q+ F& L
' ~/ C5 I, ^  k. z) [
    /*读取Excel表中的多个单元格的值,在listctrl中显示*/
2 @: q' ]& s  s0 T* b    VARIANT varRead = range.get_Value2();# ]. [( |& u7 @7 ^, u$ B  m$ p
    COleSafeArray olesaRead(varRead);2 A' U, H+ `5 [7 u# T+ z

, M4 C5 n6 c; m    VARIANT varItem;
  v  f0 ^- N4 N! ?; C/ D    CString strItem;% T2 L+ ?8 G. I4 a
    lFirstLBound = 0;' ?) H4 L6 t3 l9 v) y
    lFirstUBound = 0;
: U) Y* x8 l9 d7 }    lSecondLBound = 0;+ }  `# L2 K* u6 s* H8 s+ Z( ?5 n9 B; X
    lSecondUBound = 0;
2 m- k1 h6 O! }. a! Z6 W- w, f, s7 v    olesaRead.GetLBound(1, &lFirstLBound);
/ V! a/ e1 z- a% f7 L4 C7 v* n- H    olesaRead.GetUBound(1, &lFirstUBound);& Q2 l/ k5 W" M; y5 \
    olesaRead.GetLBound(2, &lSecondLBound);
' g4 M8 ?; [' V  W1 ]/ D    olesaRead.GetUBound(2, &lSecondUBound);" X% }! Q# G6 o2 Z
    memset(index, 0, 2 * sizeof(long));
  c4 n* `# c7 `' c; U    m_ListCtrl.InsertColumn(0, _T(""), 0, 100);6 A$ B2 \9 v( d$ {
    for (long j = lSecondLBound; j<= lSecondUBound; j++)' _+ i; R" ~1 }$ x
    {
' m. d5 A! z1 L2 u- j5 O        CString strColName = _T("");
4 ^4 D5 t+ r' V# s        strColName.Format(_T("%d"), j);
+ i6 d, X1 \. B" p: }7 \        m_ListCtrl.InsertColumn(j, strColName, 0, 100);
4 [7 D  f7 L6 L( a3 r: f- p% [    }2 k9 W6 h5 T% u, o7 u+ `( V( j7 z3 S
    for (long i = lFirstLBound; i <= lFirstUBound; i++)1 z/ L, r/ ^# H& t! K( `1 A
    {; [+ c. @" Y3 U3 f  T
        CString strRowName = _T("");; r( k3 H0 E4 G) a# U5 v, B+ d
        strRowName.Format(_T("%d"), i);
) S3 m+ B' l" F        m_ListCtrl.InsertItem(i-1, strRowName);
- Z- E7 Y  e; c/ m) p/ E! R3 f! r. `( J* X7 i1 I# _1 C
        index[0] = i;& P- {% E6 q9 x6 c! G: H
        for (long j = lSecondLBound; j <= lSecondUBound; j++)
: O) N2 w& g) T  @0 r$ |        {
4 }' r& E% q( R. E5 u) l/ c& h            index[1] = j;) @- u6 o5 W+ ^) ^
            olesaRead.GetElement(index, &varItem);7 E& A  E  s. c

3 O% C8 t- P% [2 k            switch (varItem.vt)
* x5 V* n1 b6 N- Y3 P            {) ~* i7 C" n0 p1 F$ h2 f- x
            case VT_R8:+ v/ w/ z. k, A
                {
! g7 _! T- ]3 R" I* l                    strItem.Format(_T("%d"), (int)varItem.dblVal);
8 I% b! n0 C% \& }+ M3 \  r4 g                }
3 @9 b( w5 j$ H3 C% U# m4 X
! M/ V8 L8 B) m' L/ D2 z" v3 g6 y            case VT_BSTR:
! F9 R8 D$ |/ R( l! d$ |                {5 P( y) M  u* j5 r
                    strItem = varItem.bstrVal;
* s- d' P1 t4 r9 S5 T' l                }0 n2 Z- z* }( |$ S; n* G+ Q3 y
, x; z! r9 j" C0 `% l
            case VT_I4:5 Q. ^! E8 K% d
                {+ l# @3 r" K) Y2 }& N
                    strItem.Format(_T("%ld"), (int)varItem.lVal);
8 s6 H$ E/ Z8 b+ ^1 A! r( V                }
% f; ]8 E5 B* ~0 f. y
' X1 X# G* W' F  r$ p            default:
- w' r. C( s- Q5 W8 s0 r' K. a                {
9 `& E& @( S: ^3 O' o( n9 m/ p3 D2 _! f0 X4 Q7 X& q
                }
/ h8 V4 v3 d) T! P; W) s            }
+ ?9 q6 z" T) @- k, R. A, o
) i4 ~: C5 L8 A: a            m_ListCtrl.SetItemText(i-1, j, strItem);
# o2 e; a* H! T8 e) _        }
' Y8 X- I. B: t; F' q  v    }  F1 f0 m& @% h6 g* F% A

7 x$ `8 j+ w, O
! y$ y& D, M+ e
6 r% c( H. B7 d, H" o& k    /*释放资源*/
3 O2 Y+ r+ b6 e( x8 p5 Q/ ~% ]- C    sheet.ReleaseDispatch();( _5 \+ G0 M0 [: p# p  ]
    sheets.ReleaseDispatch();
' `3 V; D8 `  f+ z4 o/ W3 B    book.ReleaseDispatch();
5 g% Y* L( S' A5 G- Q1 r    books.ReleaseDispatch();9 ~* G. E0 h7 E* K3 J# a/ y
    ExcelApp.Quit();9 _0 |; ^2 r# f+ C% m) ~
    ExcelApp.ReleaseDispatch();- x/ X6 P8 [4 g& Z

  a& w- n8 s# j3 T- H7 c
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了