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 6444 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表格的操作。
) O! b) Z1 m1 c+ ]& j; t% a  
8 ~2 K# v7 h$ D9 p, j本文源码的应用环境说明:) T' C9 o, W+ y; W
Windows XP SP3) g0 E! U  S5 G# N7 q4 a
Microsoft Visual Studio 2010' A5 A( c1 {" u6 N+ c
Microsoft Office Excel 2007: L: i; H4 l$ b) d0 k5 c
  
1 d) g- U1 x  |! s" o  k1、添加OLE/COM支持。' w1 i. F' v3 m8 z/ X) z
首先,应用程序必须添加对OLE/COM的支持,才能导入OLE/COM组件。
* z' R. W, _7 V本文使用的是MFC对话框程序,在创建工程的向导中选中Automation选项即可为程序自动添加相应的头文件和OLE库初始化代码。
0 w, L, D, N& o4 r0 C通过查看源代码,可以知道在stdafx.h的头文件中,添加了OLE/COM很多类所需添加的头文件。  M, H' q" K8 b" r+ e* j
#include <afxdisp.h>        // MFC 自动化类
7 D$ c9 ~$ v& M5 y" V同时,在应用程序类的InitInstance函数中,添加了OLE/COM的初始化代码,如下所示:
3 t0 T9 m; E+ n9 ?# T! U6 U* |// 初始化 OLE 库" U2 z. J2 _' a- {/ t7 S
if (!AfxOleInit())# l4 Y6 x6 `- }
{
: w/ A3 b  |( t3 ?  @AfxMessageBox(IDP_OLE_INIT_FAILED);6 ~1 X9 L( c% f1 d) {$ w8 l
return FALSE;/ s9 y4 j1 `- a0 L. U4 I1 d
}6 g0 @7 U3 T" V( U( b" v
  
9 B# [1 n6 n6 W5 D; P2、导入并封装Excel中的接口6 `7 k, d# r$ T  G) O% l5 i0 Y- q
Excel作为OLE/COM库插件,定义好了各类交互的接口,这些接口是跨语言的接口。VC可以通过导入这些接口,并通过接口来对Excel的操作。% q2 {5 {/ N% h5 x2 f/ Y& [
由于本文只关心对Excel表格中的数据的读取,主要关注几个_Application、Workbooks、_Workbook、Worksheets、_Worksheet、Range等几个接口。Excel的各类接口的属性、方法可以通过MSDN的Office Development进行查询。
, W& O% `2 a2 X* f" K' AVS2010导入OLE/COM组件的接口的步骤为:Project->Class Wizard->Add Class->MFC Class From TypeLib,先选择要导入的组件所在的路径,即Excel.exe所在的路径,然后再选择
- f. {0 f, C# Z6 Q* V/ M要导入的Excel类型库中的接口。
  I" E) k& D+ V  Z! Q. _8 z6 f在完成接口导入后,VS2010将自动为导入的接口创建相应的实现类,用于对接口属性和方法的实现。由于标准的C++没有属性访问器,只能添加一个两个存取函数来实现对属性的访问,通过在属性名称前加上get_和put_前缀分别实现对属性的读写操作。即,由VC自动完成C++类对接口的封装。
; ]! Q' @  w) l( }% }( D  
5 m+ x1 Y7 g) u5 N本文所导入的接口对应的类和头文件的说明如下所示:' W) @7 e# C2 h7 ~- ?+ X( G
  
3 j3 k* I/ E& q3 U% a/ T5 s7 o, IExcel接口
9 t4 c4 @( P& Y$ L2 E: M# ?+ |导入类
' }9 D& r9 x, P# ~2 D头文件1 O7 p+ M, M3 e: E7 w( C9 ?
说明7 b6 m# N# E/ P9 o! q
_Application
' o  v# z2 s. iCApplicaton0 E8 [7 w% a4 l9 ?" n# D
Application.h
9 d/ k$ t" _& w" G. V, A& hExcel应用程序。
$ ?9 W5 X. s0 H; K0 EWorkbooks
- |# W2 M9 V0 UCWorkbooks
8 r$ f8 _' l$ p9 TWorkbooks.h+ O  ~' p! f4 @6 Q& f
工作簿的容器,里面包括了Excel应用程序打开的所有工作簿。
3 `  p# }$ M. b8 x5 h_Workbook5 w. C; e) }" d: }& v3 C
CWorkbook
7 E, M) z" o1 h( }) ?6 vWorkbook.h
2 J2 S$ L; A6 d  @; a+ ^8 \单个工作簿。
6 c3 b8 y8 j. wWorksheets
: Q% c/ x7 I$ J/ nCWorksheets
- t  W4 Z$ W* BWorksheets.h2 {/ H7 }. M" Q$ B) T
单个工作簿中的Sheet表格的容器,包括该工作簿中的所有Sheet。* \0 C: k1 s# `  J0 E+ X- R5 T
_Worksheet
+ J" t! `  m. J- tCWorksheet
" ]1 Y4 b/ j; a0 ]. F& N% ]Worksheet.h
% E7 t5 S$ |- m) w单个Sheet表格。
9 i# e% e$ L6 y+ g( ]Range. [* b% u9 X' g/ R% g1 T4 A6 x
CRange
5 {1 R& _' R$ I; L  eRange.h
; Q1 z% }6 i/ {' `9 I- Z+ s一定数量的单元格,可对单元格进行单个或多个单元格进行操作。; m5 m0 G+ Q, y* _: I) C% i$ I
  # b0 E$ r: Q9 D1 Z
3、导入Excel的整个类型库: H% W3 @; j( O5 G, z
接口对应类只是对接口的属性和方法进行了封装,而Excel中的数据类型,如枚举类型却并为并不能使用,因此,为了更方便的操作Excel,还需要导入Excel的数据类型。( y' Y' K3 E( ^/ q  K, ~
通过查看导入接口对应的头文件可以发现,在所有导入接口的头文件中,都会有这么行:3 m$ w( ?! N& y4 s: M$ |
#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace. e" |0 V$ j/ F" T* n
这行代码的作用是导入Excel整个类型库到工程中。% e; Y$ [  t3 L! b" W
由VS2010自动产生的导入代码存在以下几个问题:9 w4 _* d7 u) _
(1)如果导入了多个接口,每个头文件都会把类型库导入一次,如果引用多个头文件,会导致类型库重复导入。
- c1 d- j8 [( Q: e1 ^' ~: h9 L) w2 Q(2)Excel类型库中有些类型会跟MFC类库的某些类型冲突。
$ |4 U! N7 O2 o2 ?9 d" W5 X(3)Excel类型库的某些类型跟其他Office和VB的某些库相关,如果不导入相关库,将导致这些类型无法使用。。+ I2 V- u) K% L1 C) K% v, c8 j
以上三点问题的解决方法如下:) k: E5 g) b. D4 Q4 Y0 [7 e9 x
(1)仅在_Application接口对应头文件中导入Excel类型库。* v/ Y/ a# l" Q) x& ?4 j
(2)对冲突的类型进行重命名。4 W) v  p- z9 a7 _% C) S/ J
(3)在导入Excel类型库之前,先导入Office和VB的相关库。3 z$ O+ K: t. x9 |8 H. b7 t& z
更改后的导入类型库的代码如下:
5 y/ \+ u( G+ `8 i+ g" F3 n  & q: T( e1 G: t& u
/*导入Office的类型库*/
7 N3 _  e. m; Y* ?#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE12\\MSO.DLL" \
. z  K8 d- ?  i- ]rename("RGB", "MSORGB") \
$ A  D/ M5 u+ U! f+ d1 o* f: Hrename("DocumentProperties", "MSODocumentProperties")
* C6 L1 [/ x. [4 z4 Tusing namespace Office;
# |+ z6 p- o3 I$ N  # _) B; B  _2 Q6 S
/*导入VB的类型库*/
5 l; d) m8 Y- K5 \8 [#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.OLB"
: \, C0 }7 N5 G5 b) E2 Susing namespace VBIDE;" J, N  \; f/ {) ?& g+ w/ U- W
  / v7 B  H2 T5 Q* B6 |
/*导入Excel的类型库*/
3 h8 ]3 t# C( U5 H" @- m% X( ]#import "D:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" \
! N$ k, S! c* _) O( V5 y0 H! erename("DialogBox", "ExcelDialogBox") \- y9 f" e+ a! ~6 K4 V0 Z
rename("RGB", "ExcelRGB") \) ]' i. p' M: u  F" v  d6 \
rename("CopyFile", "ExcelCopyFile") \
0 n! a& C+ \) W3 f. nrename("ReplaceText", "ExcelReplaceText") \
2 n5 f" D! G, c) O  Qno_auto_exclude
$ x! |1 d6 m* _2 i" H/ D7 UUsing namespace Excel;, B) E7 p8 {; u3 G" n7 S# R, {' ]8 I
  
1 o. q: @2 H$ r) H" P! @# F. [编译程序后,会在DebUG或Release目录下生成三个文件mso.tlh、vbe6ext.tlh和excel.tlh。通过打开文件可知,该三个文件的命名空间分别是Office、VBIDE和Excel。导入了Excel的整个类型库后,就可以使用Excel中的所有类型了。
9 h( M* }2 m1 S2 @$ t6 U  % b) A8 N& U3 p+ U& @
4、操作Excel步骤
# [. i9 ?" {! Q! d9 ~4 y& g操作Excel的主要步骤如下:) m0 x; y7 e# r, \5 h- |. b
(1)创建一个Excel应用程序。
* w- {' w# H+ s/ y, X" Z" _(2)得到Workbook的容器。, d7 ^, N( P- A) T9 w' r
(3)打开一个Workbook或者创建一个Workbook。- Z7 U/ c2 v5 Z: G
(4)得到Workbook中的Worksheet的容器。
+ ?: u/ D8 \  `' }$ o* q3 k3 D(5)打开一个Worksheet或者创建一个WorkSheet。
+ W. N+ i) U9 a(6)通过Range对WorkSheet中的单元格进行读写操作。: m/ z* D5 ]2 e, P8 M. z
(7)保存Excel。
/ b$ K! i+ U& [' P9 u# k, l8 K9 a4 e(8)释放资源。- |7 V2 y+ {1 r
  ! A9 ?, O) D/ P9 P# ^- J
5、批量处理Excel表格
  f! b1 |5 o8 k9 pVC通过OLE/COM操作Excel,是通过进程间的组件技术。因此,每次读写Excel中的单元格时,都要进行进程间的切换。当数据量大,如果一个单元格一个单元格的读取,主要的时间都花费在进程切换中。因此读取多个单元格,将可有效的提高程序的运行效率。4 h) C$ B# i4 f# O; c& c! C+ x
对多个单元格的读写操作可以通过CRange中以下两个成员函数来完成。
1 X. I; w4 s; w4 h; L: f7 ]VARIANT get_Value2();
0 w9 _) h& `4 |- J/ ]# ivoid put_Value2(VARIANT& newValue);  G1 ^* v: R! `* o
其中,输入参数newValue只要输入一个二维数组,即可实现向Excel中一次写入多个单元格的值。+ _8 o+ {% w( ?5 f
其中,VARIANT中实现二维数据的方法可参考, D1 L* l2 _9 p
http://www.cnblogs.com/xianyunhe/archive/2011/09/13/2174703.html6 U* t* _( ?$ I/ `
当然,在对CRange类进行操作之前,要设置CRange类对应的单元格。  n% K( Z6 U0 G) Y8 x
  
; P4 m# E# R7 _, l2 h' e/ K6、Excel表格的保存. g- [+ S2 `2 S+ P
(1)如果要保存打开的工作簿,使用CWorkbook类的Save函数就可以保存工作簿,原文件将被覆盖。0 d( G/ a" C' k8 C# B/ D% E
(2)如果是新创建的工作簿,或者是要另存为,可使用CWorkbook类的SaveAs函数。
0 `  O7 ?8 |6 ?. U1 Q) T6 k1 ESaveAs的参数比较多。其中,第1个参数是设置要保存文件的路径;第2个参数是设置文件的格式,可在MSDN中查看枚举类型XlFileFormat来了解Excel的文件格式。经过测试,在本文所用的测试环境中,Excel2003的文件格式是xlExcel8,Excel2007的文件格式是xlExcel4。
- I5 p' b' X' r1 p& ^# O  % G. I7 R/ @8 w& _% Y
7、获取当前Excel的版本" U' @) Z  ~( _9 [: a- }* u
可以通过CApplication的get_Version函数来获得Excel的版本,其中,Excel2007的主版本号是12,Excel2003的主版本号是11。
  k6 u2 ]7 n: t' W& z: j  4 ^- u: g3 G7 r" e: S
8、示例源代码$ q& y* u  l& _
主要代码如下:7 @  {! V9 I0 \  Y% V, E7 D+ [
  & G/ N$ z5 Q9 x) o8 i0 A
7 I, Q3 `' F" g7 X
9 Y" ^7 c" U( n  c5 n
    m_LisTCtrl.SetExtendedStyle(LVS_REPORT | LVS_EX_FULLROWSELECT);, o$ s2 U3 q/ X7 q/ O/ `
! `; D; K. p* m" Z0 X/ Y+ m
    CApplication ExcelApp;
. X" B' u3 H. }+ A' j! ~/ Y& j: J    CWorkbooks books;# K2 E0 I/ O, f6 A2 ?; _  H3 ]- i) J1 Q( z1 \
    CWorkbook book;0 L) S/ g2 p) w3 ^; C3 D
    CWorksheets sheets;; K' Y$ U* R6 }! t/ h# ?
    CWorksheet sheet;
% i) r% F! H$ g    CRange range;
& q, e  V0 ]; \- V1 V; S: V    LPDISPATCH lpDisp = NULL;
2 \- d3 j$ v5 v7 o  T2 `7 l2 {) l0 t! o5 O4 a) k
    //创建Excel 服务器(启动Excel)
' [' H* j5 W# t  b/ a& j    if(!ExcelApp.CreateDispatch(_T("Excel.Application"),NULL))8 v8 L2 N+ E, {- p
    {
; s) r( {" V9 d2 W* |9 q        AfxMessageBox(_T("启动Excel服务器失败!"));
4 L+ E  A0 `* ~8 u" {: x        return -1;! R) i1 o/ V9 d  U3 M1 v/ ?( |
    }
+ m) r8 _& h$ N& I" f' N- S/ t! o; c" t# e  t
    /*判断当前Excel的版本*/7 k7 _% {) {7 L9 @
    CString strExcelVersion = ExcelApp.get_Version();$ F- y! Z2 A9 M- Y/ \& t
    int iStart = 0;" t) M) l# }- r5 w( W; z7 |& ^
    strExcelVersion = strExcelVersion.Tokenize(_T("."), iStart);& m6 Q9 e. B0 B3 t; L, ^3 |: v5 b  Q/ w
    if (_T("11") == strExcelVersion)
4 g/ a' G5 S' j    {
+ `& S" V5 Z; l2 _        AfxMessageBox(_T("当前Excel的版本是2003。"));8 A3 P+ E1 _/ n: p$ @
    }# b9 ^" P( S0 M! M& h' G9 d
    else if (_T("12") == strExcelVersion): e  G; A1 `+ ^9 V$ A7 N
    {
& K1 I' y2 x) Z) ?' n( o        AfxMessageBox(_T("当前Excel的版本是2007。"));5 X( O0 k; ?( S) \" k6 k
    }
. @) U( ?: v+ m# e) }5 z    else
# _2 R1 G# \# e5 V) s7 n    {0 ]2 u( Z! Q9 \" D3 z) o. c! \- `+ ?- O0 e
        AfxMessageBox(_T("当前Excel的版本是其他版本。"));
) ~6 K0 u- }2 q) n    }
& \5 ^. A9 h' y  I) G4 v) i( H7 T8 r, N( [, R6 h
    ExcelApp.put_Visible(TRUE);
5 c1 X! ^: m5 A% @* D2 U6 L    ExcelApp.put_UserControl(FALSE);
" `: @) Z7 `' l5 b& U7 T" J& m4 R. T
    /*得到工作簿容器*/6 `, {0 ?. x2 A; F* Y: M7 r9 ~# b
    books.AttachDispatch(ExcelApp.get_Workbooks());
8 f. J  a$ @% @: a8 z7 \( z
( z! R# }' d5 j( S* G8 u! V) s    /*打开一个工作簿,如不存在,则新增一个工作簿*/; Q* `+ ^) d: a0 b8 I) Z+ I
    CString strBookPath = _T("C:\\tmp.xls");$ K( G2 }# u6 D4 \% d
    try
- K% \! W5 X: S. }/ n! H    {8 l/ ]( k$ P$ _  f+ N; F. T
        /*打开一个工作簿*/# U6 V2 G  g, R" ~/ z/ {5 r
        lpDisp = books.Open(strBookPath,
' Z; G9 O8 ~# Q( ]  n: @/ R            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,2 B! D; H1 X" J1 m! S
            vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, : A) y+ k1 k5 O; s/ O+ F0 I; S
            vtMissing, vtMissing, vtMissing, vtMissing);
; s* A* l9 ?3 a/ [4 t/ P        book.AttachDispatch(lpDisp);, w3 P8 Y& C) R/ D' {3 E0 S. m+ V
    }/ i1 B% D! |% @7 A8 W( q
    catch(...)
; w+ m9 i4 T0 p; y% ~    {1 I( y# ]0 x$ H* `  J5 m
        /*增加一个新的工作簿*/
* t, d1 Z% |/ X' K; v5 a9 ^        lpDisp = books.Add(vtMissing);% Z  m: I  C9 B! ]
        book.AttachDispatch(lpDisp);" Q7 K# Z  H: M/ M
    }
5 G( M/ q" D7 p1 B( \6 ?1 U; b     4 J/ j% [5 ]# A+ ~4 ]4 ]4 V

4 }' }6 _5 d/ q4 v7 K# y+ ]% h$ R    /*得到工作簿中的Sheet的容器*/4 i4 i' G& K1 x% I
    sheets.AttachDispatch(book.get_Sheets());
0 ]7 L  z# y8 g4 H! M
+ p  [2 N  X+ k/ l/ j. i    /*打开一个Sheet,如不存在,就新增一个Sheet*/
# b, I, m1 F; j& ?  @    CString strSheetName = _T("NewSheet");
4 k- ^* ]) V1 m+ x. A    try0 Z5 }, R9 Z6 ?) }& T2 {) {: h$ P
    {
8 e, X% L) o* U2 k& y. [# r        /*打开一个已有的Sheet*/2 R) C2 o2 _7 H$ I
        lpDisp = sheets.get_Item(_variant_t(strSheetName));
$ p6 s  n5 e' v) _/ L        sheet.AttachDispatch(lpDisp);
! {) K7 U/ O5 m$ W) L) E3 M* e% M    }
* ]; R- K" f1 n' B/ Y/ S3 k    catch(...)
; b9 A8 j% i' t' H5 n    {5 ^  |: g, T0 p, t) O
        /*创建一个新的Sheet*/
' n0 j- A1 I- P1 w+ x7 E        lpDisp = sheets.Add(vtMissing, vtMissing, _variant_t((long)1), vtMissing);! y. l. ?8 H0 ~" e8 R
        sheet.AttachDispatch(lpDisp);
' y5 k6 w( l; e' M# ]& ^* e* X/ c        sheet.put_Name(strSheetName);
& H/ p# d  K1 b, D    }4 r  L% ^, B4 }9 g5 x; `! e9 ^
* T- Q  ?& Y0 ]7 V/ W
    system("pause");. f' a+ e* R$ {2 C7 `( z! P7 D- b

+ k( R2 `: s; i( ]/ r    /*向Sheet中写入多个单元格,规模为10*10 */
+ \4 I) t! [! ?' o9 S& q, J3 p    lpDisp = sheet.get_Range(_variant_t("A1"), _variant_t("J10"));
4 O! |7 [- U2 w* l7 Z% Z/ ]! b    range.AttachDispatch(lpDisp);
8 k! I& ^/ i" p; B# S6 `, y
) `1 f% X3 K, w% P5 W    VARTYPE vt = VT_I4; /*数组元素的类型,long*/
9 m( g& ?' b5 W* J# U0 U1 t    SAFEARRAYBOUND sabWrite[2]; /*用于定义数组的维数和下标的起始值*/9 V$ Z0 r. G* q# q+ I
    sabWrite[0].cElements = 10;4 N* |* C  f! g4 S+ t! `
    sabWrite[0].lLbound = 0;; F1 H6 D4 r5 ]+ N
    sabWrite[1].cElements = 10;# T. b: m6 p6 Z' G1 o% H
    sabWrite[1].lLbound = 0;
- o4 R# f8 h3 N& I) K4 R  P
: A$ S( E5 q: K2 v9 ]7 U    COleSafeArray olesaWrite;
5 O: O. H& N: R* b1 @    olesaWrite.Create(vt, sizeof(sabWrite)/sizeof(SAFEARRAYBOUND), sabWrite);
. S! @# ~1 J- i8 X- `6 i3 _* L  G# h  U1 M% y
    /*通过指向数组的指针来对二维数组的元素进行间接赋值*/! R2 g" `' P! X
    long (*pArray)[2] = NULL;
; l1 z% L& m  @4 x7 |    olesaWrite.AccessData((void **)&pArray);; v" @" ^: R" u9 k7 B
    memset(pArray, 0, sabWrite[0].cElements * sabWrite[1].cElements * sizeof(long));9 @0 B* {% O( Q4 B3 @
; S7 a( Y( H. n! b. g% M" d
    /*释放指向数组的指针*/
3 B- d( M% G/ I0 y" J    olesaWrite.UnaccessData();
: f. C8 ?2 `- F2 w) L    pArray = NULL;
, U* G* c  B; [4 j9 I) Q! w" W- k, A8 N; Z9 E3 f9 G+ R! S" Z
    /*对二维数组的元素进行逐个赋值*/
$ |/ J9 D" f- W+ D    long index[2] = {0, 0};* Y  m3 r; k! _% E1 i+ `6 t0 \
    long lFirstLBound = 0;$ u' _/ }" i6 n8 |5 @* K
    long lFirstUBound = 0;: U2 T: l  Q: E! y
    long lSecondLBound = 0;
* [$ I( M) x( Z0 N* B# D) M    long lSecondUBound = 0;
# k. X; V& {, ]$ d& j2 f0 K    olesaWrite.GetLBound(1, &lFirstLBound);
+ y  @1 v* w$ [9 F    olesaWrite.GetUBound(1, &lFirstUBound);
! K! W) t2 @- k% _$ ^    olesaWrite.GetLBound(2, &lSecondLBound);
% R" I2 a% ]1 _' t    olesaWrite.GetUBound(2, &lSecondUBound);& l2 ?5 m- t) z) B; \, W* f9 L% ^
    for (long i = lFirstLBound; i <= lFirstUBound; i++)
6 P. I  E( S+ v$ ~& z) ]    {
( U9 V3 f( M9 b- K        index[0] = i;
% P. g$ c+ x+ }/ T+ S        for (long j = lSecondLBound; j <= lSecondUBound; j++)
8 D; Z# A4 O6 @) H: J" U, C$ O        {: s4 a. b, w- {% m1 \
            index[1] = j;
' ?4 A6 S; B: _4 _: k, o- Q$ U$ w            long lElement = i * sabWrite[1].cElements + j;
" g6 H9 R) ?2 d* _            olesaWrite.PutElement(index, &lElement);" I. S, }) D4 p  _! |. V
        }( ~- J' k( J# q5 M: O; v( z6 K: q
    }
; W- G) u7 y* T5 P- |+ v: A
7 u0 _! `( J7 V) e8 z    /*把ColesaWritefeArray变量转换为VARIANT,并写入到Excel表格中*/% s! D/ E7 |5 A, x/ o: c( y
    VARIANT varWrite = (VARIANT)olesaWrite;
1 A: P' u  I: S' g    range.put_Value2(varWrite);
& x( J* ~4 [- a$ P' ]3 o) y) L  t6 n) Z6 F
    system("pause");& c- L- K3 E: @: M! b" C  u

) K3 {0 }9 e$ _, K    /*根据文件的后缀名选择保存文件的格式*/
+ \3 U4 L; A. W) }     CString strSaveAsName = _T("C:\\new.xlsx");  q* h5 v7 b% i+ w
    CString strSuffix = strSaveAsName.Mid(strSaveAsName.ReverseFind(_T('.')));% X7 O& A! |: f% x3 a2 D0 Z( \$ R
    XlFileFormat NewFileFormat = xlOpeNXMLWorkbook;
; i& P- F0 p4 p' a    if (0 == strSuffix.CompareNoCase(_T(".xls")))
% r! ~9 ^, i9 n. x* s* g7 _7 E  m    {9 ~2 X) R; H6 {* x) x2 Q
        NewFileFormat = xlExcel8;; Y: s/ B6 I0 v
    }
' i  C2 Z! {. V: M+ u9 I; V    book.SaveAs(_variant_t(strSaveAsName), _variant_t((long)NewFileFormat), vtMissing, vtMissing, vtMissing, ' f) \6 }( i' X+ G* Y: I- B
        vtMissing, 0, vtMissing, vtMissing, vtMissing,
# O$ W! u6 R6 t$ z. ^        vtMissing, vtMissing);& ^* U, l- R' k5 J! F4 e$ ^! t4 b

1 j' \( s, |$ A- s    system("pause");
5 k- U' F9 z: A* D: s% f
* n7 [% s& w# r    /*读取Excel表中的多个单元格的值,在listctrl中显示*/
6 P% Q6 I! e/ p% l    VARIANT varRead = range.get_Value2();
6 Z$ W! `& p* n! N! E    COleSafeArray olesaRead(varRead);
5 t) k+ J' a7 X& W* g
: H! y. G% T3 {; S9 u. N* x    VARIANT varItem;
# W! U6 Q1 k7 u& u    CString strItem;- D* I! D0 _/ j# Q) t1 a+ Y
    lFirstLBound = 0;
! X. @/ a4 ^6 p7 ]8 o3 G    lFirstUBound = 0;
4 O# j/ [9 X; G5 m    lSecondLBound = 0;
  _7 F8 M) o; D. s3 i# E+ H- ?    lSecondUBound = 0;, D# h' }; F2 V; R
    olesaRead.GetLBound(1, &lFirstLBound);# C7 g# h/ J5 h6 t: g5 Z
    olesaRead.GetUBound(1, &lFirstUBound);2 Q% {* s! X" D8 _
    olesaRead.GetLBound(2, &lSecondLBound);
9 G3 G& `5 m# |1 |/ I' N% F, w. h7 k    olesaRead.GetUBound(2, &lSecondUBound);
" j: h# O8 l. q' D$ J% \* X    memset(index, 0, 2 * sizeof(long));9 h6 X6 f' L" l3 ^( ~+ r7 ?7 w
    m_ListCtrl.InsertColumn(0, _T(""), 0, 100);
; a: o* I, x1 |- t6 }    for (long j = lSecondLBound; j<= lSecondUBound; j++)
' F7 a3 H4 @0 g0 B/ J2 t    {
, M- g: m1 S1 M  t1 j        CString strColName = _T("");. _5 f) c( i/ J) l: f9 H- ^, U
        strColName.Format(_T("%d"), j);
% w1 @# _7 R. [! s9 i        m_ListCtrl.InsertColumn(j, strColName, 0, 100);
) x8 a4 V3 t8 e, ?# b4 b# L" s3 e    }
& S4 _6 Q# j5 T    for (long i = lFirstLBound; i <= lFirstUBound; i++)! j0 z, H  S7 m" A# |7 |
    {% {8 Z4 g) J5 j% |. @- d
        CString strRowName = _T("");
. C0 Z( V$ G  K2 u3 S+ a$ Y        strRowName.Format(_T("%d"), i);  y+ p" H: ~/ x: }  D# i
        m_ListCtrl.InsertItem(i-1, strRowName);9 M9 u( ?4 M2 Y4 h4 G

' Q4 V9 {& m$ r2 e5 ]3 t        index[0] = i;) R+ J* S* ~; s
        for (long j = lSecondLBound; j <= lSecondUBound; j++)" j$ u1 i$ ], H( B# L
        {
4 ?# W/ d$ c* Y3 o; s8 X  r            index[1] = j;
* Q( p" R9 |' S* p            olesaRead.GetElement(index, &varItem);9 j3 O* d& ?6 \6 X

6 F' z* f3 k3 u: j$ B1 x! I- y            switch (varItem.vt)
: Z3 U7 N1 F3 l0 {0 h            {8 l1 ]( h! r6 L4 c% A& M: W5 [
            case VT_R8:3 S; l' k& Y- X6 q( ~
                {( A. Q' p7 [, y0 f5 r  G3 s
                    strItem.Format(_T("%d"), (int)varItem.dblVal);3 ?/ T3 j' \" A: l! p! v2 I
                }
2 g% z- j1 C' G: ?- U: \3 f) k& I. o# S5 \+ z3 \( z' Q
            case VT_BSTR:2 _" m) j3 j) g
                {! Q  w4 T$ G( \  {/ p9 O0 e
                    strItem = varItem.bstrVal;+ V: r" ?# v$ E9 q8 |
                }
( h, x: e! x6 Z, ]" [, ^9 z' H+ u) e' M% ]) J
            case VT_I4:
2 X7 n: Y7 O/ `4 b- d  ~1 `                {; p" N. P+ A9 {8 M5 q/ R
                    strItem.Format(_T("%ld"), (int)varItem.lVal);: N1 q2 z% \3 C7 C# e
                }
( j9 g, [# r- x; R0 C0 w
: b* T$ U" ?7 w            default:& s1 Q7 B1 ]: N8 I0 A" p4 R
                {
! Z5 B! }6 [; G2 N
. v$ x: Q- P1 K/ e                }
( l, }" x2 ]1 _0 y6 v; ]5 @$ v( X            }
' G$ R" {: }9 B+ d  @7 n
3 L; F' y# |/ ~; N3 M8 m            m_ListCtrl.SetItemText(i-1, j, strItem);
) f$ G  M  I; Y7 Y        }
& s& l  X7 t& f, @0 m# C    }
  s# L9 Y7 ?; @2 d6 k
  f. A& W& I2 N, A* F- b' O0 i% N( d- U" H9 |3 R* |8 A

7 l' s  |* X6 a4 }% J  v    /*释放资源*/8 h/ t  E2 O9 X" n% l% u: {
    sheet.ReleaseDispatch();
6 r; h/ p- C- ?2 J3 v1 y( j    sheets.ReleaseDispatch();* M8 y; G3 }! S
    book.ReleaseDispatch();& o* f* N: s  [1 }4 o" A* e+ t" e
    books.ReleaseDispatch();6 K( v4 x$ {/ A' J3 k5 y0 l7 C
    ExcelApp.Quit();+ f" L1 s( D4 ]5 h* T
    ExcelApp.ReleaseDispatch();7 L- \9 j! O7 V/ y
5 w/ {3 G" i3 ~( X5 {2 B7 u
上海点团信息科技有限公司,承接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二次开发专题模块培训报名开始啦

    我知道了