|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
* M% m% @7 K, Z; nnet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)
+ [: j4 h4 I' r, d+ z* m这里我用c# 生成 com 组件 让 c++ 调 2 ]- Y# s$ j9 v9 d3 ~, A
+ i, F, E" V5 C4 D' i& L8 y% |
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)
6 K9 B0 v; m9 `" h5 O/ UC++调用C#的COM组件(DLL)6 E+ q, W7 I, H7 c) {
3 C2 ^2 y% ~( m) ~* Q
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
% m$ h- K) X# z6 ?首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.0 h% b! T% H$ y; x, Y( J* B. i+ e2 }
3 y' H" @/ k+ w. s
- l4 T/ O/ n/ T
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom
, b! r! M5 ?# I0 ]$ }* B9 Z* Q& G8 D
2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数) T2 r( B/ Q8 H2 ^' Z
. B: g# k; [) P% v, j
具体代码:
# b4 K) V% ?% B6 ]/ @, A. w
3 x5 M" M9 F5 ~using System.Runtime.InteropServices; //记得加这个命名空间7 h7 T. u6 X6 }$ ^6 i3 \
$ j! d2 g2 ]" X) ?, n E+ L) _3 enamespace MEI_AddCom
/ J& E1 t3 m8 i) }! {# r- W$ K' I% [" B% a/ Q6 F
{
% j0 ~8 _- S7 }' T3 S. J4 b) J: U* `* H0 Q* N6 @7 c5 J" |
[Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.
3 i0 M% q. c/ O- O! [/ s' Y r+ t$ B. O7 J3 }
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
4 J5 l5 h/ f7 i& G
( j" h% ?- K+ p: K8 u [ComVisible(true)]5 L/ y h+ I; s
; k4 ~' Z* y- t& \ public interface MEI_COM //记得用修饰符public
+ Z( C' l; `! b7 H3 R. M- r, x: W" f$ X7 T l0 q6 s1 |8 I- ? p
{/ ^% x3 [. u2 Y' b9 o6 |7 r* g1 ?+ }
4 q, m0 X1 Q4 I1 F( L# b [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面
/ v+ X" Z' y' F* D! k9 l4 [% o* j" t9 |% J0 G& \1 ^8 p) P
int Plus(int one, int two);4 a0 ^) H) p9 i- g" S. g3 D
8 w+ z% u6 S0 i }% k0 [1 u3 L# S4 v" M/ a+ j
7 k5 R1 r. ~. M9 y
}) _7 f. j/ M6 X! D- e( }
# Q) I% I# x) O1 _: K/ [( N' u4 _! l9 @5 a5 S& ^1 ^4 E( m9 K8 D
+ y8 D. ]1 `' T @9 P& F4 Q
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码3 V; ]! A8 z! k. h
5 n8 ~0 E: F1 z5 M/ t7 x. Q
using System.Runtime.InteropServices;
# E7 j) M2 q: j/ C$ | p% _; i" S9 z' E6 X
namespace MEI_AddCom
7 N1 B; I4 u4 V4 ]0 X7 E% n! @
. T& H' E6 G9 h' m' K" f" p, W, v8 O{
- v0 F1 q: n" B! J0 s+ \- J( M4 o3 q' K, r) `0 d, g
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]
, U9 L9 n4 s* } ~4 T
# b( {1 N0 P% v [ClassInterface(ClassInterfaceType.None)]
+ p6 l( ]) c/ h" S9 D; D
: } g7 U6 W4 t8 F; j0 |: d public class MEI_COM_T : MEI_COM
0 h6 U& E) X( A- H, F" ~! B2 h
' x6 ~' A+ [5 r- k {
: T+ x& I9 k( X; P( d$ g# D
9 L; @! [$ z) l! Z2 V- t public int Plus(int a, int b) |( h/ r4 E: A/ p7 G1 d$ z
9 k( j9 L& X! J0 Q+ z
{
: P7 s+ p( T N. ~" T% r" P
! C6 W0 L# t+ X% ` return a + b ;7 X7 k% `4 \3 c. T
: Z" u4 @) _# t0 e+ L3 ^ }; G% G2 s3 m% r8 ~- I2 l' ^ L
/ n; J8 b& P& p- { }4 k; w2 m* c9 b
2 b u' ]0 u8 ]0 |}
: |9 _( J+ J# H- F3 }( T y4 ?; z( ^0 i
/ k& h# Q& x" Q+ {% u& }4 P5 o. [; B7 A/ T' b
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].
7 d4 A, j5 ?! R: X: H( k! v: k5 j( @9 t( s o/ m
右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册
8 ]( Q R4 |7 C z& D3 l% r7 s% v( f1 y4 R. L
- U# p4 w/ c' X5. 生成->生成解决方案
) ~& S' z" d; @: H( N0 ~6 \3 B 注意 这个时候 生成 非常缓慢
! L# P) U6 v% p* n& ~9 q 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
& q6 S. F5 m+ o2 m
5 A$ s+ J* |, `
; w1 F0 R( t- V---------------------------1 e" {2 g% j: [1 ^" Q6 ~+ `1 y' A; C
" y. M' ]: ^$ G8 g, c1.调用前要先把com组件注册才行.
: `% _) L! a* Q% @( r# y# [" `( f4 D n2 {! p
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。$ j9 j8 Z/ q$ B; ?
以下说明如何通过C# 注册、注销COM组件。
. d2 [8 J# L, s+ W# ` a2 h* F' p' c" r% Y" Z M
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
9 t% @: V' [* e8 [+ y打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
L2 V* j1 M0 P创建完成后COMLib项目中将出现后缀为.snk的签名文件。- K1 F) i0 E9 `0 \/ r0 d4 m) ^
最后,编译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文件。
' l, F' t0 e( f- B% w1 {卸载COM组件:
. I7 o1 {8 e* A, x/ P$ r9 D与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。% ?+ {% _& K+ b- y! ~# K; i" m
* b- H7 W \+ m* B2 J' j7 L3 Q/ Z
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序4 ]& F9 {# T$ G# P. K6 h
$ f5 q4 v! Q. I% K# w3 e3 z6 `
名字取MEI_UseCsharpCom,点完成) `7 |; Q- |, L' A
8 K& U2 a; F: c! w+ e6 E
把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.
& t! {8 a0 I K
* i3 m1 S6 k( o- F我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:0 d) e$ j0 @& g g
; P C6 ^* k' R# ~" W: g& g* N9 u1 U: D0 }4 m) |8 F
#include "stdafx.h"
+ @7 ^5 W; y2 T; x \$ l+ ~#include <windows.h>( _( N) \# o) h6 [' j% u
#include <string.h>, u* {. f$ @* z& ]' G4 g1 C
" M) y7 i# Q5 c
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only9 }5 } h& y: X3 J0 P u9 Z
6 d; K( g7 |; X
char* WcharToChar(const wchar_t* wp) //wchar_t转char*; q1 s. p' @8 e) s& F5 Z
{ , T1 s- e7 }# j# o
char *m_char;2 X' H* W' V1 L, M$ K0 y. H
int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); * D2 _4 b1 o o9 }
m_char=new char[len+1];
+ {" t6 e' R: V5 e( c1 l8 A; S5 w WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); , o. P V0 m2 S- }- d/ p6 v
m_char[len]='\0'; 0 p* f7 S# t* d# h' T; c2 a; T
return m_char;
9 u& \& k2 `2 v _}
- P% M9 c D# O; h& lwchar_t* CharToWchar(const char* c) //char*转wchar_t
7 i0 q2 r( _3 z Z' c/ l9 f{
( ]+ R7 C- u P* V6 n3 M wchar_t *m_wchar;
4 g8 ~2 s9 f- r |" d int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); - Y: [1 `+ S0 o4 \' o) W0 J1 _4 m
m_wchar=new wchar_t[len+1];
7 H+ O2 I' M9 _& m. q MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); ( w8 `/ f! W8 A3 T% c
m_wchar[len]='\0'; - U1 l+ L3 ?0 z5 I" y: |5 m
return m_wchar;
3 L$ o. h) l9 `8 Y: b} ; O6 f: b9 K) ^5 m/ |- y4 K2 u3 C
0 g+ d& |+ V! P; s" N
void _tmain(int argc, _TCHAR* argv[])
# u, h( K5 }4 s' L# l: Q( S# t& H: e% _ _# x/ {% ^
{
. {" ]; J. N) {/ H
& F; |8 @8 k' e6 K CoInitialize(NULL);
) Y: s% _* M" A! [/ {
' z2 v' T9 X0 u! L MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
! C4 }' W+ I% J g1 `7 ]9 ]+ a# b( D4 K& M' h8 ?4 i" Q
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名. ?' T* b8 Z% j& W
' Z, ~0 ]. E" r4 D( x% a //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
I. E/ `0 ~' f$ ]# d4 D9 x. u& B3 a" Z( V4 U
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
4 v3 [3 |4 R- h. U% f //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果- D; F. U' e% @( M
3 n, X) U7 b8 q, Y long a = 1;
& S/ h! R$ x3 p2 g( {
8 ~) c$ w! u$ Y long * lPtr = &a;
1 c9 l1 q2 j& c
6 n" h$ Z' @4 J" {& I ptr->Plus(1,2,lPtr);6 R" k! V- G5 l1 J
% L9 M5 W. m( L: @5 j+ D" k" D/ U char msg[132]=""; w0 |; i ~4 }! ~
sprintf(msg, "%d",lPtr[0]);2 c' M% m* l2 d" \
# [; ^5 \8 s( { M, @5 Y LPCWSTR str=CharToWchar(msg);
% ]0 ]7 K0 _* \9 U( m- @
( s, a$ u2 \ [/ h! w9 {" k! ^ MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
% ?$ k/ N/ v% G$ u2 u0 z) [" H7 F" d: H; A
$ s% t! d2 T! I l4 a3 h
}
5 d: w: P* V, o9 f: h H' i) P$ w- s9 O, _, v4 \6 R! {
此时就可以正确运行了.得到结果3: G) Q4 @6 b) w$ c" U
) @2 I9 w, Z; o/ V
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.3 q% ]- [/ ~# K1 R! k2 \
2 H6 C% Y- G' d7 M4 ?4 G7 E+ A- n8 i A& n9 v+ Z/ E' V. h; t1 E" d1 o
--------------------------------------------------------------
8 X0 e; T1 ^9 L3 XC# Npoi库 操作excel 的代码网上很多
+ a* @7 c9 R, D- ]+ A1 l. O+ t( |4 R8 l6 \5 D! [
// ----------------------------------------------------------------------% G, M) O& Z& |5 d2 [: a* g
// 使用Npoi创建一个简单的xls文件,写内容
+ r$ u4 T+ W* x* ]$ ?/ G U0 }3 a: ~! H6 E
using System;
' D# ?/ \' W- E% b z3 iusing System.Collections.Generic;
4 A% g. f( l4 s" z6 s4 C. S& F! [. Kusing System.Linq;
/ D* V0 O( d2 H" T, c! tusing System.Text;2 v9 |, T" u- Q- X' a
using NPOI.SS.UserModel;* v& t/ e9 h q8 n
using NPOI.XSSF.UserModel;
* M! j1 y$ R* {using NPOI.HSSF.UserModel;+ C+ r; \/ W4 ?5 k* j4 d2 K
using System.IO;
5 ~+ t! @3 E" D" X( Gusing System.Data;
1 t8 Q2 h2 @+ _
0 e, V) v& J( B, z+ P3 D R//using System.Windows.Forms; ( d! _9 o! I3 a( C' R. n
9 {# A. W7 q9 U& knamespace CC `( q( h8 m; r1 x9 x/ `
{) W) W$ q) b7 k. i! H- t4 j
. V: ?+ K5 N) H3 W; z; ?6 A2 X class Program
* d& D) ~) \2 x9 C6 W: ?* D& [, d {: ?3 Z, T' ^9 ^5 y9 O
4 B0 J" I S; j0 B+ u% @
( \/ n c5 L8 _2 p, N' v5 ]0 P static void Main(string[] args)
( X; f$ |3 T$ G I* k {
# C4 N6 H: I0 m5 E# k: }4 \0 E //创建工作薄/ O4 Q* }) X3 f7 V/ O
HSSFWorkbook wk = new HSSFWorkbook();
+ p- t/ ?/ r2 N% j% @ //创建一个名称为mySheet的表
1 c E' e& W0 `" B( _ ISheet tb = wk.CreateSheet("mySheet");1 M/ v& u8 e, H# ^
//创建一行,此行为第二行3 \, D/ O& ^3 E6 j' q* g4 x
IRow row = tb.CreateRow(1);
@9 X; a$ ~; G' K# H4 t# X for (int i = 0; i < 20; i++)
* N( B1 m: W9 {& s {1 Z V$ b: J/ f& Z
ICell cell = row.CreateCell(i); //在第二行中创建单元格
% t2 }4 m, C3 \3 A+ o% ?* u- V cell.SetCellValue(i);//循环往第二行的单元格中添加数据( T! ~" R6 ?9 X+ |0 l0 v5 Z. o
}
3 a# Z: f9 i1 f+ o _7 g! K using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!+ ?' R5 W- i9 C$ t! q/ ^. I9 j- B, w
{
8 A( k7 f; C& d! N wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
# I9 L' C* Y- w, o // MessageBox.Show("提示:创建成功!");
3 e- l; ]5 s3 Y$ d' W$ A }# Y. c8 X- n# [& L
u' v6 D! N# ~: K1 X- T }
# e4 w1 c I9 ?0 J
$ t: F% _' O4 I8 }2 Q0 U1 u/ h9 w- W; T5 I
}7 _6 h# B! x5 q/ O
! c0 x' V/ y' Y0 ^
$ F% v) \0 N8 `' I( b: E" C6 x0 e* ?
}
8 ?; \1 _/ Y) o: B6 q: _9 F. d3 e$ U Q, a0 `5 B0 f
// ----------------------------------------------------------------------, H1 B) S) G5 g* C' j
// 使用Npoi读一个简单的xls文件
" K$ s% f+ B& I8 Y t* V/ Y ?' q9 a$ U* h) y' }& t. w
using System;
5 L; b/ h" h5 _# B/ Ousing System.Collections.Generic;* Q! U3 ^0 p- A; w0 y0 j; x% I1 q) T8 ^. i
using System.Linq;6 D. Z. U+ p* ~
using System.Text;% Z# v8 H; [9 ~7 q0 Z; \6 ~* K
using NPOI.SS.UserModel;2 Q r" n% s! T5 B; @( \! e
using NPOI.XSSF.UserModel;
: J' ~) e9 k5 @using NPOI.HSSF.UserModel;
4 H( U- h3 g6 t8 J) k+ Uusing System.IO;
+ ~- [: v2 T9 o4 fusing System.Data;! U0 b$ S: w: t. e
. I- q( f4 e; Wnamespace CC8 V: f8 h) d* E1 h
{. `) ]0 G' Z8 E3 k- E
. Y8 U+ e9 k, F; T! @0 y! y
class Program
3 ?! \$ d* I* Z5 z+ s2 |+ T" E) Y: P {
' l5 t) `" \+ Q
8 D: e' j& C# q' R. d4 R9 }' B& ^5 a# O8 @& a' f
static void Main(string[] args)
2 C: q( Y" v0 E8 O, K# a6 i {8 G8 q. t0 X! h" U
StringBuilder sbr = new StringBuilder();1 ?7 C/ i7 ^+ J8 F* |* z
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
, O' \6 _) I! f- c; {$ F* l" g) l4 K {
, Y$ W( x4 \- P: h HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中6 y k+ J! q1 s0 Y7 N
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数8 C3 K$ J* v" Q$ R5 N( a' d- H- c
{0 W, l+ C8 B- X4 a
ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
0 u; L( r2 R& @" Z+ x for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数. x" [' X$ [, d- \
{
G0 w% @, ]8 ~ IRow row = sheet.GetRow(j); //读取当前行数据
' e( y# j# V1 @ if (row != null)
7 N: p: J8 ~( A r {
0 _1 ~* r9 _. @) o. e) |. q sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
+ N7 C3 t( H k [. k/ V* h( W% `, ] for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数. K5 i7 q! n: c
{
+ e8 o# t. G4 h' u, C% c G4 J ICell cell = row.GetCell(k); //当前表格
3 a, t% w' m7 p2 W' X3 s5 ? if (cell != null)
4 H, @9 ^- i1 H& i( {* O {/ O7 c9 g/ K( R% j+ I
sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型% V: q0 T; q& j* F, ~
}2 X( E' f+ z9 j
}
: c$ h3 M$ X7 D, x* l5 t- V }
9 {* C0 Z' C- S" F2 W }! f$ F0 n, H8 |: c
}
' r6 N6 x6 |: P, Y) v0 I9 j- s }
* }2 h- m$ _ z. r+ Q, Z sbr.ToString();
+ @1 |( C2 `* a0 W% } using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
1 Q5 ~2 o4 |" L {
k. M. {# X* o$ s( `9 C0 n wr.Write(sbr.ToString());
7 Z0 W5 U( Y- E% m wr.Flush();
0 D; {" [- {2 J) a8 A/ h1 K }( p. f9 R1 v& y; M
3 \: x' ?' {- R" R: O, S* b( o3 f1 ]
1 B1 `) b" Y$ r' c1 M0 { }
# L. ~8 F: {1 g1 p* ~- y! V- l; S& {: b) i8 P+ t, p2 C
4 z8 ~6 I5 B m$ h: C2 U" B
}
7 ~1 X+ l' T/ _1 K2 ?8 B
& u0 r; V+ i2 x) ~* g8 w
4 W1 M/ X5 D' v0 H0 k+ u" V9 D: u5 m/ }! d6 x3 q$ I
}( a/ ]) ^# b8 W/ y8 V
R: J# z' v9 W! r$ _' v/ x8 y u/ y7 T* Q' ]) c
然后 自己封装 给 c++用
- B+ r* \: i6 h8 [: f) ^: i( P2 G1 H+ H j- L) D
9 A6 T2 Q$ h) m& i
5 R' v8 z5 A' J0 v
0 p! B, D, }1 l) U% W8 ]) @" v, t! b
$ D) {) Y6 m; f+ \ D b, x1 I% B6 [
4 s& z( e* a& L4 ? |' Q7 H
* O5 Z( K V* U- \, e( Q
7 f9 Q& O7 [9 W0 b' E- I5 @5 t% ?( S& |& U$ r
6 [( Z: |0 ^. u( }$ l% f3 C% F ~- `( I2 o. z9 P9 {
( U% u2 V& X7 {4 e
1 j z3 C% c' b8 L9 s: i- V5 F
; c0 j7 p- g! H2 O* V* ^5 U1 o
" m' @! K ~9 b3 v7 [/ O; k1 ~) M4 `, _# Y
2 {+ P( g6 G' `) z' Z$ D
, G% W! z9 Z5 P- w
+ B$ A2 @; d* m) S7 K9 J% T6 q U. \
, J4 F2 d6 h! r
) i6 S: a$ z& q2 [4 F* b |
|