|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢5 o& b' ]$ l1 x7 Y. F8 c
net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)
* G2 o0 J' t; h0 K. h6 Y* Z这里我用c# 生成 com 组件 让 c++ 调 4 v0 _2 z* ~ P& c
# ^) m1 g! [' l首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)
) X. y3 v- |, eC++调用C#的COM组件(DLL)
$ `0 H$ p; B+ y: J5 w4 Q& Z8 ?8 d
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.! y1 {6 f) \) N, L) P
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
* r& h/ i) m7 o! h, o
0 m" R# ]$ N6 x1 h. a; y6 V* z8 t6 K
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom
4 V# q) ]3 H; ?& G) t% ]9 |
# z# {! k/ g S; t2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
& T2 U# F( y' K$ N3 R4 S5 a* l; u6 y( ?! n' p
具体代码:! n. G& U( ~9 h9 {* p) ~0 H
$ A$ W7 l- Y, z5 |2 yusing System.Runtime.InteropServices; //记得加这个命名空间- Z$ D4 h- y# J3 n0 e) i9 l
5 z" j/ [0 A6 Anamespace MEI_AddCom6 i* M9 I: l2 j5 O6 D; H
: _9 E1 U' Z& t" L* T{
# p; H' _2 }& [6 s/ ^0 J8 {
# a! r, i6 C: y4 r( O0 i [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.+ l' ^0 {6 @; S$ w4 W- j
& g$ m/ ]- n5 I6 P5 v1 D" L: v //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
8 Q, w3 i' d/ S( w
9 l( `- D- V0 J% E/ Z3 Y) m$ W* g6 u4 y' W [ComVisible(true)]% s: O V+ X |9 [7 Y, C
# A: C/ T$ i" U6 G
public interface MEI_COM //记得用修饰符public
1 i; E* W! R2 I3 G/ f1 {# K/ g7 R6 g" u
{" k) ]3 V8 I) u4 u% B
7 l* b: y. @) b. m [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面1 n" ]* V* i) w! }" {, o# J
. e3 ? @4 s0 W& x' C
int Plus(int one, int two);0 Y A& e6 l3 l
' M3 U) l* v& r X ` }
+ m0 n. T; U3 Z0 |3 J
4 Z/ P) V8 h! ?. r' u4 a, r}7 s2 ]6 c- ]4 q6 _, U
: I. u9 z& R3 L% m6 H2 D/ t1 H/ @; l; q% l* n: a% A
5 E# {* e( b; G. C3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码
z& s! n1 H. J6 @( X: A* U# ?# v D
using System.Runtime.InteropServices;
, o$ [+ c0 G. Q s2 K, e
" A b; J9 s, i$ \5 jnamespace MEI_AddCom |0 P& C6 R" F' m' X+ e3 d3 x$ u# t
N3 L* e, x2 k4 D* X3 y; `# P# G
{* j7 p0 Q% @# u0 S# A
1 t" X# P* O# w- t, Y" E3 q. u [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]
7 J9 H; z" k6 I. \( b- a( z' j* s; k- G
[ClassInterface(ClassInterfaceType.None)]
5 ^8 m: x. r% E) E1 C3 j0 ?& V/ ~# z7 m8 @8 z8 h: a9 o Q& F' B
public class MEI_COM_T : MEI_COM
1 {4 y# s0 m6 _4 ~5 g
7 p* G2 d3 _5 t8 W Q; C' r& ^0 p9 o( Z {
% T) m9 ?, u S' A5 d. z+ o2 t6 g( P' {/ l2 _2 d
public int Plus(int a, int b)
" R. f1 F Z& H; E' C* Z
8 S" }* Q6 N P {
! f6 E/ h9 H e8 V1 A, @4 O
) t5 l' P. b" T9 g) T3 d1 @- r5 e return a + b ;4 k1 |+ P7 G9 E. I* V
1 D i% A, K3 B }
7 g1 I6 [9 K/ A4 \/ `8 Y5 |9 [$ m8 j
}
$ x6 T! E+ O6 b! M
# y4 e( ^0 ^3 r4 ]" W0 M7 `- A' m/ P}( R$ @0 E4 v/ I* p. [& d; K( V9 z
+ u [5 X9 \/ s0 W7 m
1 C1 ?2 i% B' B3 Y# g7 L& k9 E N/ x7 i6 ^9 p) E% H
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].+ f1 h% f. B9 t* d& x
$ }& x0 t4 y3 b& R8 G
右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册 U; i1 F5 o8 t: m) e
) f+ B7 i/ Y! z9 Q Q5 G
1 T8 k8 D8 B2 n5. 生成->生成解决方案; c9 y R0 m0 ? x! E; Z
注意 这个时候 生成 非常缓慢
7 t# J: T6 H, o$ @/ Q% Z. r1 Y 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容7 a% {( P% d- ]) Y" I3 f1 Q- T
- i7 E+ x# Y5 E" @. r: T) X ^3 j ?2 X1 D( T" p- w
---------------------------
( M' @1 T) \- F; D8 R2 C! R
# g+ z9 d. u! c, G- _1.调用前要先把com组件注册才行.
0 E! `3 Q0 ^3 {3 P$ T3 p$ O, v/ j% g2 `& @) M- H+ t
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
; u6 Z; s4 \* I9 |' M- x以下说明如何通过C# 注册、注销COM组件。 & w3 T, N6 Q) _: c. }5 O
6 V4 z% H/ ]: o% y1 r. d w
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
9 }) ^" ~7 k& Y3 U2 S9 a% w5 e打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。. w! C/ _7 R$ V, g
创建完成后COMLib项目中将出现后缀为.snk的签名文件。1 S# s/ M0 E5 c# _
最后,编译COMLib项目,生成COMLib.dll文件,完成COM组件的制作。 注册COM组件: 如将COMLib.dll放置D盘根目录下,以管理员身份运行CMD,提示符切换至C:\Windows\Microsoft.NET\Framework\v2.0.50727,输入“RegAsm D:\ COMLib.dll /tlb: COMLib.tlb /codebase”,回车后得到如下图所示结果,表明注册成功。同时D盘根目录还会生成COMLib.tlb文件。
6 ]9 e( e6 F4 A$ F( _卸载COM组件: 6 V6 q/ G- G& _! x1 d
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。0 k% I0 g" d: Z9 `$ g0 `
( H! b! ?: h9 e6 s8 C/ Z
8 ^; _+ G5 y& ^1 }5 o5 ?. O
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序6 @5 e* T) J+ V- L' V) C( i
/ Z3 w/ Z9 J5 _( F2 @
名字取MEI_UseCsharpCom,点完成) W% b* X* d, t- c3 _
# a" a7 I, [' j" ^: v0 M1 d7 D F* p" o- z把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom. S/ I3 {0 b7 y( [7 j5 T1 \
W8 W+ U o) g( i' ]我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
# \/ K# U! p l: \. e c# L* o
: K% V' F+ u# P3 X/ |9 c* J. ^: {3 F/ n3 o: N* w
#include "stdafx.h"
2 y# @( j1 {" v5 j3 g! d9 {#include <windows.h>
, B! {* }" [2 W3 ?& |#include <string.h>2 u) F5 N& ?& h! N: c+ {
+ [! ?' g: o$ @2 Q, b) K$ m1 r, @#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
1 K/ q; M2 e g) L% V* w. w% @
8 E! m/ t6 ^ {( Schar* WcharToChar(const wchar_t* wp) //wchar_t转char* H# f) t' P6 c2 K
{
, M% M5 f* R. _7 E char *m_char;
9 D+ B) M. |4 j int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
; P0 n+ w6 Z/ ~7 R3 Q m_char=new char[len+1];
0 ]1 x5 C" T+ m8 Z, B9 [3 n WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
: [! d4 J% H: q9 z/ v/ M7 a m_char[len]='\0';
; Q2 i# [ P* Z) m0 n4 N, O/ [; v return m_char;
* J$ {6 j5 b1 d. j}
% @: c% S# E; q& k5 \wchar_t* CharToWchar(const char* c) //char*转wchar_t# \( Y( J, D% ^% O3 a
{ 2 p1 `) V: G. B' y. F* N, g
wchar_t *m_wchar;
& ]3 J! r: m3 }, _. r+ L int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0);
+ W4 \1 }, s9 A9 H m_wchar=new wchar_t[len+1];
5 u7 W( p7 J9 u' X5 g# ]7 M# A2 y' ~ MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len);
7 M- o) s) d p+ e/ ]0 w+ c m_wchar[len]='\0';
! w" B7 C: l. [7 Y return m_wchar;
4 R+ {/ n) ^, P V0 R} & ^/ _& \/ P9 b
( _$ I$ ~& [( Y) K( s7 {void _tmain(int argc, _TCHAR* argv[])5 z- Z8 _ } E& B1 P
# K; `. ~- X# n t; [( p$ {{7 C! U0 e# w; H5 G2 e
4 c- f8 n" w( \( ]7 ?
CoInitialize(NULL);- X0 x# \- ?) T+ X
' d" {5 b9 P0 G3 {. Z2 v
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针$ G1 X& q( L. `4 \+ {, Y$ r3 }# l: Q
) T! b7 `9 v" V ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
+ v, C7 {" } o5 D+ B! ^7 {3 b' m) ]& O2 L+ g& k& ] {
//这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
- S$ ^, L0 @/ z( ^% m
- Z8 c2 r5 N& M7 R# Z //来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.: ]7 v ]9 P, D4 g4 ^
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果. u9 v& ^% X- G4 P2 F) n' ^1 T
! ?0 h) P) W8 }' U" V0 c; R5 j long a = 1;2 G. }8 _5 x$ j! j
: N, b5 D( Z, {( e4 k long * lPtr = &a;* J+ H7 Z$ M6 I* ^% u
' {+ u8 w: [* n ptr->Plus(1,2,lPtr);! `9 I+ \; x. p+ O3 r
- ]( O: e/ }2 {. k, a
char msg[132]="";
+ H2 R- i! E1 [" r; U sprintf(msg, "%d",lPtr[0]);
& b5 p0 C7 R4 T/ g8 ?! `$ j
) w; U4 e4 d9 { LPCWSTR str=CharToWchar(msg);3 y9 z1 t8 s5 _2 c
# `, }0 Y A+ m* |
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
& ~+ s: ]3 d% }4 n7 |
' N/ V! ^& y9 V% W6 p
& l- N v1 j+ w f& L( c' U}
0 V |' m2 Z# l
" k' L2 I+ t- u, C6 G; {1 Z此时就可以正确运行了.得到结果3
9 ]" [" J. \+ I1 R1 ?& |2 ^' j9 F
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.+ c( y @* f {% F* \/ ]' t; Q
: i: ^* K9 }' e; b% P' [( Q A
& J( A4 ]; ]4 l7 b2 |# ?--------------------------------------------------------------
, T- @) F" S+ J* u, s) ]0 DC# Npoi库 操作excel 的代码网上很多' s* M1 W3 ]2 u9 }+ S
" w, G1 _5 Y0 ^+ @
// ----------------------------------------------------------------------6 Q, g' {8 R; u6 f1 F
// 使用Npoi创建一个简单的xls文件,写内容
j2 |$ \0 v: {6 r* D- V! @ \1 Y8 a2 g9 F# |. H
using System;
& |8 c1 l5 N6 o' F X0 Eusing System.Collections.Generic;
. K% M' s0 ^' Q" L' musing System.Linq;0 U- f/ S3 n0 P1 O& _1 R
using System.Text;
: N( ?8 w, k/ h6 b* q- Fusing NPOI.SS.UserModel;' m! @8 v! c' p" o+ h
using NPOI.XSSF.UserModel;
8 P- H2 a* Z2 u& b; vusing NPOI.HSSF.UserModel;
' s9 C: }3 Q3 \using System.IO;
( \9 w+ P: `3 \ K$ r D5 }using System.Data;8 L; F" ^. P3 T8 A7 t
7 x+ P" }$ t, K1 w$ p H) L
//using System.Windows.Forms; 6 ~ a) k' n: h
; ?& a4 B: V" [: U* O% o8 D; vnamespace CC
, O! C6 b$ c+ l{. H9 F8 _, r; Q' l+ g4 L( _2 d
+ M- H. W- _: K9 K1 G
class Program" y$ T+ D; c5 p2 }! R4 [/ x
{
7 d) P0 W7 b6 O7 B9 k0 K2 n* A6 P* f5 u2 \/ \
- x) E# P9 k, q4 i* ] D. ]& e6 d' Z static void Main(string[] args)4 O3 n3 h) R3 S5 h( ]
{7 |* o7 E: ]% K- a1 a# ~
//创建工作薄8 @# Z7 B! x. D: j
HSSFWorkbook wk = new HSSFWorkbook();
! C1 M) @, e+ [6 B" L //创建一个名称为mySheet的表* c, q8 _ x" r& I
ISheet tb = wk.CreateSheet("mySheet");
" l6 Q- y, y, R/ {; d; `, i) a //创建一行,此行为第二行
3 e0 \# R# e4 r7 ]- }$ X' w- z IRow row = tb.CreateRow(1);
- j! C9 }* `9 Z9 B for (int i = 0; i < 20; i++)
, t2 \1 W, ?+ X8 P& M; Z! w/ _! [. Z0 ~ {' @0 y# Y, @& V9 T2 |
ICell cell = row.CreateCell(i); //在第二行中创建单元格2 _9 C' \" W% |
cell.SetCellValue(i);//循环往第二行的单元格中添加数据
- ^% Y% p1 Y$ u, d3 A; Z }
! a: I2 L- ^, S* e using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!6 }% s8 C( U, M
{
, G2 p) c: `2 J wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
3 Z9 I* H3 y+ X // MessageBox.Show("提示:创建成功!");+ h: o& m* P$ P3 b/ t
}5 Q7 o, V( o) ~; |% Q* X! b
. I7 k/ t1 a& y9 ^
}6 V0 k4 `! ^6 r* T$ b
8 U" E# {# F& b
5 M& F7 n, o* Z( F/ I2 q# y: K
}
; P d* T: M% e$ \ k J! C
; n' r# q" Q8 K
; F+ H: Z" Y1 s5 J) u5 F% R" A) q* B, J
}+ H4 v; V/ q+ P; h8 G) g
! q+ K5 i1 x- W; A# m" F# F// ----------------------------------------------------------------------8 \$ ]5 \0 _- |. h5 `/ ~( I
// 使用Npoi读一个简单的xls文件$ X- r( y% r, r9 Q
/ C% }$ L, o. [# w( T1 W
using System;! m9 [/ @& D1 X) \- W
using System.Collections.Generic;
, j6 B+ x& [9 l2 gusing System.Linq;9 n! A `8 ]% E3 Q# G
using System.Text;
+ O& @8 ^; z: m: c; r' j% }8 busing NPOI.SS.UserModel;) l" o( z8 ~. G' d# o. g# t
using NPOI.XSSF.UserModel;3 K( U7 o; ^, p2 ~' t
using NPOI.HSSF.UserModel;
$ [. l# e/ ^ u% Z& kusing System.IO;) {$ k: f; J* W- A$ Y& t
using System.Data;
" [$ h# x9 u" N- [) M/ F7 Y2 L6 G- o! m
namespace CC' G; f: d7 E( I( G* E, y
{
$ T2 \: g$ ^6 P1 @
+ w6 C0 `2 j4 [ class Program U6 G. q) h' S' C9 B
{
/ l' K( A( o" p# v- ~3 z/ I
9 D/ \, g7 G, b; P9 \8 u+ S ~) o7 ^5 m8 i$ n$ X
static void Main(string[] args)
) ], Q9 d- w }( _' ` {/ c* S9 v! m& F3 }( z) B
StringBuilder sbr = new StringBuilder();
6 B1 c5 Z, M% }/ n. ?* E using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件4 E+ D& a2 ~0 `1 i0 P
{7 w4 q1 {+ _! @1 K
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
9 j1 A) \$ v5 i) D' \1 A2 d8 g for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
3 P8 l7 n2 g3 }. W+ L+ g o {2 [2 k; M7 `5 T0 p$ w. s
ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
4 I1 v, o1 Y( [9 L" l1 o for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
% w. c- O2 B. V4 M3 ^, B {$ B0 o8 p* ?* B
IRow row = sheet.GetRow(j); //读取当前行数据
$ O4 [3 h3 I8 a) l8 y& U4 H if (row != null)
/ X6 v0 S) ?0 |$ Z, D, S) o5 V {: c; j* B' T7 r, C" r) c
sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
$ P( \1 k+ W6 W. |: u for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
0 b0 c3 A6 \3 x E( |% m {+ r. b8 R9 H% t1 I+ A. }* F
ICell cell = row.GetCell(k); //当前表格
" P. j2 }9 t& E: @ if (cell != null)
% G/ ~/ D& A: M: W. j% j. z {
5 c1 s2 [1 ?5 u$ A sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型/ C" s) `2 }: S- r; ] {
}% V2 T8 ~/ L8 z6 v2 ~* J$ `
}4 Y5 ^. L1 Z* { r: V# `! R! |. N' n
}8 T1 \$ M: o1 \: }+ l
}
" r( _! v" l4 R; B \' S }
, w2 x" _5 _ z1 o6 B }2 Z" q' s, W- d- C6 V3 i+ m; Q6 r4 W
sbr.ToString();
, P0 P2 O6 k, W9 @$ C) S+ g7 U using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
& [+ Z/ P8 n0 F. _0 J( R5 a {: J, M1 e9 e/ b9 F! z
wr.Write(sbr.ToString());
" |: a T: v7 O8 q wr.Flush();$ X6 U& Q# F" S1 h' n1 Q N
}% {4 _9 U3 A. y/ y$ m+ w
5 D# j) @: E# W, w" A
$ {' a' a; C7 @$ ^0 `$ n }
+ {7 u* l: R. V6 M; F
9 \3 d$ D5 l" r2 F* W, p
" O* o2 \, k% e& K" E7 m' E5 ] }* K7 }# M. s' O: o$ |4 _
. E" x' `6 R0 s, n( M- f
& N j! f; x0 A; G/ h1 X6 c2 [; L
; I+ m1 D* u' J}+ T5 N7 {; J/ Q L, \
0 Z& E2 E7 x. b1 V# Y f3 q' ~9 ]/ y$ ?2 ` z- V4 g g6 b1 R
然后 自己封装 给 c++用
$ n& E- A7 n C* S5 _; L/ o- o0 ^5 n3 }7 b8 Y4 \6 n7 t
( Q) v9 I9 @: _& v; ?, R$ @" a- t
7 n$ K* f& B/ j7 y# N6 B
# x2 L6 W1 r* X: M8 C+ J
3 _# _8 R Z$ X( B) v. U1 b8 ?, Z8 D! u9 @/ R+ ?; f" {. V2 i
+ M) Y! B+ B8 ?7 u9 }
: t0 X9 X2 n7 f: v# C2 M% q! c0 S% I% _0 G
) _3 a9 F, t1 ?
* B7 h! C5 d$ }, x
9 f/ q I0 z: D3 B1 H3 l& a! e( o& x5 l2 J' E% K. t d$ Y& n; t/ X
p* [( A5 V e8 r* t! Z8 s
9 {* E+ p9 w9 ] C( q8 o* s" u6 e/ f9 @6 f0 V' S. K% \" ~3 q* x, n
& t* O' Y/ y" H, Q. i. r4 F
! D+ o U S- q
" p# I' q, \6 q6 a6 o1 R9 o& q
1 F+ j+ f" \/ F! q/ R+ K! l/ L6 s7 B
. V- l) Q5 l3 e# F0 B- g0 d. P" c7 z' c6 p6 h
: {& M- n6 H& M7 S3 q' ~ i; s
|
|