|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
×
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢1 R! U8 G7 t% i: i: _
net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言); C- b* l1 ?, A; P7 t1 Z/ Q% s
这里我用c# 生成 com 组件 让 c++ 调 ' g( W5 q( n c$ b |! C1 h0 r) u
+ V7 x# ?7 U8 D# K; @
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法): |) ^8 |& D" k. E
C++调用C#的COM组件(DLL)
2 c' W6 q4 R' w; e% ~( e1 |$ [* w' K$ a0 h6 k/ {$ A+ i
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
6 y9 m M7 @6 l& a; n7 {" m首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和. x$ T1 o3 U- J" g
2 w% ? ~, Z k% K* B" D0 G* p+ N5 t
0 x9 r9 W4 P2 c! z1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom" ?7 A3 ?, a5 ?! e' @
4 b s/ M' L. t0 e3 o2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数" W" }* @ v, B. _ d3 r- M+ G
* p( N, U6 t# t具体代码:
+ Q# y6 R# N, c+ D% u
' j5 p' i) D" W! O3 ~: u$ ^! lusing System.Runtime.InteropServices; //记得加这个命名空间
0 v& v$ c% C+ x; c8 \
; @( Z' P" j& C& j' onamespace MEI_AddCom
/ Q; L. g- y1 N- R* P F2 k3 R# @4 L. A/ H. G* ], \% D1 t7 F
{
0 F- U3 R8 Z7 H
# N) x! |8 N9 J' ~ [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.' I k$ q- N5 o& V0 @3 P% D
4 W; {; r+ w, h$ G: i
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
' ~3 |5 B1 h% `7 o
! ^' O! _. C8 C( F( `1 h2 S [ComVisible(true)]) D8 `2 P0 _, _) h0 w7 x9 @
# f8 h1 [: I4 }/ p
public interface MEI_COM //记得用修饰符public9 g: X+ Q3 Z8 C$ G8 ?; _
6 w8 A% s- L6 |% V+ o {& c; z7 c( j. v9 t+ U9 c
: |1 b" T0 q$ y8 d1 d% n U# Q
[DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面
$ x) k+ G! o* _: N* G& t
! a: m. m# c# e int Plus(int one, int two);
1 b6 m9 d, c+ t1 T6 V+ ~3 U6 ~
- \! J9 h% E$ o! _+ H }6 Q/ ]0 D3 ^( `7 P
# A' V# @' J4 W2 ]' i7 g5 Y}! k- J8 n, ^% i
: g- p8 Y1 H& z5 k$ p7 E) D) W6 e- ]6 g# {
$ Y0 j0 N0 y2 c% [3 C( ~# Z
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码
/ {" m5 H2 X9 ?! d3 j$ x% s8 ]& p! G5 }& @' P& P' y m7 a3 Y
using System.Runtime.InteropServices;+ ?1 f# m/ Y, Z% J. `
! {( w. H( v: {: S8 L0 }! `namespace MEI_AddCom
* G' l& w) k2 z$ w. ^! m J1 x+ `3 f0 r
{
& q- L, `3 S# n8 ~: K
9 F# L( I/ A9 N; e' u- t5 d! g/ |; m! Y [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")] I7 Z7 k% s J! P. U
! ?% G- g; F; s$ q: k, P, d' Q [ClassInterface(ClassInterfaceType.None)]( |' y8 I' [* ?! j
, |3 D; v/ `* k, c7 D" T2 @
public class MEI_COM_T : MEI_COM
# [7 ^0 G- a- H9 \: @7 G
) {7 ]$ q7 l4 m0 q {! x: M m, h% o# t& A
* {8 J0 z9 ?- O3 R+ L+ t; r: Y public int Plus(int a, int b)
' N: ]0 r) c/ h2 }& u7 n, q0 T$ N% V1 ]4 {
{; n* t& n: R' H+ i
3 T& O% u: U& n- g; e! t: B
return a + b ;1 r. V# j- H7 |3 z0 _
. F. f* k; D) b0 f }) R2 ?( ?# ^) E E
# |" |. ]; C3 A
}
2 ~2 A$ {3 E' N# d3 x7 f' j. Y/ A Y' o6 {7 r
}
4 J/ W1 O' ^( @5 ^3 p
3 H5 Z2 |# I5 y2 B7 L/ X$ {6 f0 U( h8 j, @" y! c
. l+ O; V0 _9 R8 r' ~, Y& v
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].
& y& {' L0 q. R4 A& X
; }$ S6 n1 p0 p8 w$ |# |右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册7 |2 p z2 C. u2 g
7 E7 G; ]3 L: q8 K% `+ Q% u
9 D/ ~- U/ g% `: K
5. 生成->生成解决方案4 g0 P8 X0 b2 S! a* H2 Y
注意 这个时候 生成 非常缓慢
; Z0 [3 i6 C0 t 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容1 R4 s( F# \+ A- Q. u
1 o. w" r! M4 S& b% e2 s. w9 b+ l+ C0 u2 v8 K f$ {9 N9 P9 ^
---------------------------& n+ R* u& O" x' w
+ h' W0 I0 L/ ^# @; Y4 E
1.调用前要先把com组件注册才行.! j2 W# f' o0 Z7 J
, \, t& ~) M2 Q+ i
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
; J) Q/ `- N* }* b以下说明如何通过C# 注册、注销COM组件。
: K7 A1 d0 P; Z& l. A& e( A5 L3 D F# {/ [3 s+ }9 g/ @9 h
为了能让生成的DLL能够进行COM注册,需要进行强名称签名. ^0 P8 z* e3 L! ?( h3 [6 o
打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
- C& V" w- m% `; g6 R# J创建完成后COMLib项目中将出现后缀为.snk的签名文件。" d$ D1 |. i2 C/ M! b0 `: R; e
最后,编译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文件。
! ~# j+ R" u+ ]: ?+ A- O卸载COM组件:
/ G/ H; y2 ~$ ^ \与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。) q6 o+ } v2 t5 a% b" Z1 k! Q
+ H& k2 b0 r# N$ A2 M
$ q5 ~- w6 W5 |& h2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
5 W* z/ |( d+ J/ J: z* p" F# u) Y5 @
+ C9 X/ \' ]( I2 N% l名字取MEI_UseCsharpCom,点完成( m: `( y2 _# M% \0 ?, l
2 a6 L4 h6 C6 ]% }3 m' J) F
把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.8 b& K$ E% C: F2 \ h: P
: [3 I. K4 A$ f) U我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
* L3 L4 g/ D5 p4 a8 c& y v4 f8 R$ N% |7 E ?# l; m8 z
, M6 P2 B7 D# ]9 p
#include "stdafx.h"% \) ^# h1 D7 k, B
#include <windows.h>' P" @9 ] F: b G* y
#include <string.h>
% J ]+ y, e$ y1 H
( q H- O5 T' D3 v5 x#import "MEI_AddCom.tlb" named_guids raw_interfaces_only z ?2 n. n2 E+ ^1 ~) R! @$ h
+ @! \" I. A& [) X/ i( A/ t
char* WcharToChar(const wchar_t* wp) //wchar_t转char*3 g4 l3 o2 N: H5 S+ X- v: w5 p
{ / j y" W5 b7 T
char *m_char;, f2 F! h8 T. a5 u9 f, ] H
int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
}* z9 a1 I* H0 }, q9 ] m_char=new char[len+1]; . m( V* b. W e
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); % R! y/ `9 o0 O+ K+ H8 i. P
m_char[len]='\0';
3 }+ B1 i* n3 i return m_char; & \$ k5 }& ~ P( b
}
4 P% w' E- O5 ~wchar_t* CharToWchar(const char* c) //char*转wchar_t
[+ j. P* b- g& l- I% ~{ : }# ?2 n2 L+ _+ o; I
wchar_t *m_wchar;: A" b7 H& \ a7 H
int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); . x1 K3 Q8 P, k8 i7 E6 Q' J. W
m_wchar=new wchar_t[len+1];
: k5 A% j3 X0 \4 N MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len);
4 ^$ ^6 r9 x6 x1 g4 v% A2 g m_wchar[len]='\0'; 7 m: X; F2 V. T, J0 g( v- Z
return m_wchar;
% V. |+ R; g) k8 L}
/ b/ u* `, x8 C7 S. W- a$ b) ?, y9 W3 g6 o
void _tmain(int argc, _TCHAR* argv[])
4 O2 i5 k8 n# a: { _# t2 }' z9 X5 o1 A2 ]0 v( q# ?
{0 m- ]% G1 E# V" A' J& R0 i% o( H
_) d" [& F5 b/ B4 A, V+ c CoInitialize(NULL);
! H- ~5 g/ Z0 S0 v8 e5 Y$ e+ s1 l, m9 [, G5 P4 d
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针9 T. _' i( c( F& G9 M/ t9 A" b0 X
! d0 k7 q9 I0 [' O" Y. F& R7 s' P6 B+ L
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名! S7 S4 L$ D+ J7 a0 R0 C; y7 W9 }
# i& _( z/ f( K* U //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接 j# |( V$ @6 L
7 u' s" b, @8 H' v4 O //来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
5 L0 ~4 H# r, w! Z. p //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果; Z* a p$ ?1 m& E/ x% K
' x$ e$ G0 o; _' j long a = 1;/ @! m( V( r5 W3 r8 R
E& c5 E7 }; D! _# D6 c
long * lPtr = &a;" l; l; _1 @6 _. U! R1 g! k
& r g$ T/ S- Y; g; N1 m ptr->Plus(1,2,lPtr);
5 ^2 a. {# x* [' |, o/ Q0 W6 i$ c0 @ w) O3 U) m! D
char msg[132]="";1 p+ a1 M1 R# }( H5 x
sprintf(msg, "%d",lPtr[0]);5 \) |0 g; N8 M5 X4 w3 f* m2 u5 s; S
! k! u( p+ B9 K) B; o: Q4 d6 Z) e" D LPCWSTR str=CharToWchar(msg);
B6 F9 |. n3 y9 [1 _3 J
& `8 d3 K. ^' q3 `0 X MessageBox(NULL,str,_T("123"),MB_ICONWARNING);. w8 t: ^* v3 A1 L) l1 F
% C. ~3 _. y7 ?1 X
; Y# c' k2 j8 J
}" g/ [/ k) H% C F
3 R* |2 i l& ?2 ~ r# }$ b4 m
此时就可以正确运行了.得到结果35 C6 Q0 J1 O! i# A4 x6 @
" O$ J; c6 P; x如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
5 e9 E* q$ c r. Y7 ^6 H' x- I' I( n4 k5 u, n$ ~ |9 a
+ k3 B% e6 w8 }- c- B9 _--------------------------------------------------------------
0 {1 D# e; C) H7 N3 d n4 T4 K- I0 HC# Npoi库 操作excel 的代码网上很多
- B( ]8 P+ r' f' R! U ?. H* l& B7 G( X
// ----------------------------------------------------------------------2 O4 r0 \4 A6 @, Z
// 使用Npoi创建一个简单的xls文件,写内容
0 A2 ~6 p1 W# t+ T
- K9 j# R. \8 X! E# `7 [7 o5 ausing System;: c: J% W" S/ B5 Y. ], i" s
using System.Collections.Generic;% U' n3 c d& {1 m3 `
using System.Linq;. o& a1 g3 Q9 ^* z/ B, }
using System.Text;: o0 h! w2 y9 E4 _2 [' l
using NPOI.SS.UserModel;
, L# y: c/ D5 Z# a; Xusing NPOI.XSSF.UserModel;
1 P- {: y4 P. P: d: Q/ [- R- rusing NPOI.HSSF.UserModel;
5 D& z: b, U8 Kusing System.IO;
) N8 R, Q/ N8 C, W! yusing System.Data;
9 x4 X$ m4 p" F( f% }) V
8 j$ B1 D: c; k2 q ?( @% M9 X6 H" t//using System.Windows.Forms; ; R7 m+ G- D! N
+ `! |/ S8 s% w8 e
namespace CC
9 D" z* O* {4 d% P{+ a# X; z; q" v. e/ m7 V I
0 W# F- s1 f- c! R G3 f. h- X/ v
class Program+ W* D$ s* R, L) w- m
{) |+ `/ M: k4 b# G d4 q
3 j( b& ~3 `3 v) o
c) i- q7 E8 c3 k2 j! r$ M4 O
static void Main(string[] args)
+ `$ \4 e ]$ [' @8 U1 ] {
/ P+ }9 v: y& P4 Z! L //创建工作薄% j I7 X* I3 Z
HSSFWorkbook wk = new HSSFWorkbook();
. ^7 ]% C8 O1 W3 C1 g //创建一个名称为mySheet的表
4 @0 } d& {, x8 O' e# H* ?/ y7 e+ ^ ISheet tb = wk.CreateSheet("mySheet");
5 K R: p* |6 F/ m# s ~ //创建一行,此行为第二行
5 |0 ] O' K2 _& s IRow row = tb.CreateRow(1);/ c" o. u! @" Q1 j' q" o6 P" l! v
for (int i = 0; i < 20; i++)' G& m% P5 x* x' w9 x
{. b8 W$ `1 k0 G( H0 I3 l
ICell cell = row.CreateCell(i); //在第二行中创建单元格
) D$ u0 x2 Z5 }) \( X6 w( a cell.SetCellValue(i);//循环往第二行的单元格中添加数据
, m# C0 @7 `4 \' h0 C$ X2 a j) D( S }) i3 G4 \, H; n) C- `0 n% k
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!0 [+ h) ]& q8 y+ W
{
; v* A( c9 `8 v2 _' V# x' ?4 s# B+ I wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。( c2 o2 U* s; L5 W: k4 L/ Z
// MessageBox.Show("提示:创建成功!");- d- `9 X& {1 q# _* N4 A+ R
}; t4 K( v/ }5 u$ e$ I7 K- t4 l5 S
% j, Y9 J5 B1 o2 T }; ?9 w+ a' Q. _& q4 j
4 b4 i" V. X5 N& @; D! g* E) u/ @/ ^& ]) `3 R$ I
}
& v6 z- q7 z1 P c0 s3 x1 `1 _1 Q9 R; n( d6 r
" w u) b! H$ t" l" |
4 t4 | R$ k2 u5 ~4 y; v! D2 z}8 O8 j$ q3 T2 M" S4 w6 R
/ ?# H3 j8 ~& H- K// ----------------------------------------------------------------------
/ N# a" o8 R# q9 O u// 使用Npoi读一个简单的xls文件8 _% Y& Q" M# Y4 r' ^: L
$ `- M9 i4 k" K. X# {" I1 kusing System;
" l+ U# l3 W) x1 `! _8 Gusing System.Collections.Generic;
9 l- [/ v0 b; ^8 E" Z5 Kusing System.Linq;
& G6 Y. f0 O1 H7 v- H1 }using System.Text;$ }6 B6 j) i/ R# Q
using NPOI.SS.UserModel;) z2 b& E9 [& c
using NPOI.XSSF.UserModel;
" l2 U& M7 y0 L3 A6 qusing NPOI.HSSF.UserModel;
0 ~3 {" R1 ]% [( V1 b5 Z2 h! wusing System.IO;
2 T% }7 K* G& h0 M' r/ Jusing System.Data;
# ^+ c: \1 t) t5 a6 X
" w8 `1 R' Z( ^9 j* Dnamespace CC
$ F* }6 a4 B; G0 j: q{, m9 H6 U- o. y. }6 p) x
F4 e3 D7 M! A6 c
class Program" u5 ^: g6 O$ }) n; ]
{5 _5 b0 K# G+ u% H
1 \/ b2 D" V' G- N9 d
' t$ D1 N4 T4 ~" f1 ]
static void Main(string[] args)' D9 K5 u7 ^9 ~
{
/ A: a' g; V% z" d StringBuilder sbr = new StringBuilder();
0 E2 B7 H+ c5 U9 r Q7 C6 Y% {& U using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
; ~- }" \) F- A, O/ G {
% p2 P" d- w: I6 b HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中: |% q9 c( c Z. q
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数 n( A! v; `* K' _1 @
{6 G" Q* Z* Y! R! [# [7 O
ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
. J2 K8 D& ]1 a0 q3 T6 [. i for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数$ r( P- B! h8 Q8 o$ c1 H k
{
9 Q& W& f/ O$ A IRow row = sheet.GetRow(j); //读取当前行数据7 W# Y( u* \4 f7 F6 F
if (row != null)
l! H) j9 D5 u: w {% ?8 T( P2 Y9 [6 o, I+ ^
sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限) P! x. I4 {8 L" |, k: h& m
for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
: m( ~0 S/ \& |% T {1 f; I& f i7 H( ~
ICell cell = row.GetCell(k); //当前表格% i, }0 ] m/ P, w& {( Z
if (cell != null); O# F+ Y% ?4 L6 A
{
( z: }/ R, w8 w: E sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型3 k! M: O# P9 w4 [" T9 Q/ o( @
}" f% }, C3 n9 ?+ ?8 i7 S
}
, `& p7 @ h o0 g/ z- x+ @ }
( z. P: G/ k) k% l* R, D% j( m. L }) I) A# c! k0 l* X1 o- b- n0 R
}) \" j% P" k* s/ C% L4 L* j2 d
}! l" G4 P3 U3 H, p5 [2 u, \, N
sbr.ToString();$ o+ I8 J( @- C8 A @
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
4 `1 v% ? \: k3 ^- J/ w% B) f {
4 \2 `7 P" T* j wr.Write(sbr.ToString());
& }( T! ~( _' @- N' U4 t wr.Flush();' q0 S1 t, m$ n' P6 `9 O' d8 h
}) g) o1 Y; G# R2 Y
+ y+ ^, ~ `. r- K! j
" K& y) i$ P, Y; J5 i9 ^3 X6 C# b {: @ }+ x* I* c7 L/ j, C- K! ^
3 s: ^6 b* y7 t2 R0 l+ |2 @% P7 e; |; I# j% n7 j4 m9 ^# E0 t
}* a& T, _. O1 L
8 R& w" Z2 B, o6 ^3 e
! p4 | g2 |0 m; s
9 Q% |- p( ` i! D# x$ Q' y
}
1 K6 Q/ O0 K6 n1 \1 w$ E Z+ q
2 m4 v# A3 ]' c0 }
- B6 y3 L& j# c. N然后 自己封装 给 c++用& E$ u% z8 G4 c) Q# E2 K/ J/ [( e
5 V8 h9 s1 \2 L' c" O2 T% `1 J% P* g" a
# B N. w; z& W4 a
* J: |: Z3 N6 c* v0 C _0 [- e. t% L0 K, v# m
! a/ |5 d ^5 ^! V
% X+ O7 u- H0 N. u
9 u2 t; i: a# ^9 o+ o* [0 q6 e! X+ M t
# F+ \% {5 V# C% h5 e
2 \# O. v. Y1 a, @4 F c3 {' Y, h
0 U T) z1 D) X, w4 u: M
/ B" T$ d: T l" J x9 _- e6 [* E
; r z& C4 ?2 P; e
u3 V3 z5 R3 H1 A
2 _2 z, U3 x& U0 F+ R
/ s W/ B- f, Y7 l8 x
1 E- Y% M: ~( \2 g$ K+ C4 T
2 P. @" S. e$ ?3 g. U
3 J, \. G8 F1 x' P6 ?0 u5 Q; J7 u7 X1 n, D' A* F3 V
& x- R! Y: a( v2 ^
: o& \: T" w* t2 P0 k
|
|