|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
4 e0 w6 |' y+ Q Gnet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)
, @# @5 G, d5 F8 ^1 {2 Q这里我用c# 生成 com 组件 让 c++ 调
R% l. U- l$ W: j, c6 k: M/ \, I6 M: l5 p" L2 S
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)8 A* j+ `1 Z" v: I
C++调用C#的COM组件(DLL)
$ ~# X1 _# N ~, v7 }0 A
# G0 h: z% M9 {- k! `, F& _: h下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
2 A: b" S. I4 _2 _$ n! o首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
; d6 p2 ]# n( E
! m+ l) l% f. T/ V2 q9 j6 P1 R8 J" d% U% }
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom
" f0 p) G% _9 {
: ]! X" G; g ^' L2 x. ?' F2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数" }7 B+ E# G8 }* o+ k2 p4 ]
& ~6 q; l& q& H% j6 d) a" c$ R- n具体代码:$ s1 o l# B1 C
7 `6 F0 A9 N; s8 H% gusing System.Runtime.InteropServices; //记得加这个命名空间
* x' [% W$ Y& X+ g1 |* y. d8 L _! {5 ]7 _
namespace MEI_AddCom
) O4 d s1 Z6 j5 G$ |
$ R0 c* M3 U! x, [6 b' P/ R{
. |/ n2 w1 S5 x4 E# ^; S# f# D' d: t
# l1 P, |/ {) C8 q8 N Z- P [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.! w" a+ T; T+ w3 j) k6 Z c3 q" d
) P1 x' o& O) Y
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
3 [( Z1 K# h; w/ P
3 b, e$ k; E. m( ]3 t. G# [ [ComVisible(true)]+ |! }: I5 w/ P
5 F$ d# J! p7 r# Y0 R. W/ @; k public interface MEI_COM //记得用修饰符public/ \& K; b! Q% V& F5 Z) w
# B! w; Y) L Z7 `' B" m
{
" S ^+ E x& n+ z! J3 K5 V
Z4 l0 C* v e; D7 {* R [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面- P' R# x. ^, \1 W4 O
\& p- H, ~, T% p$ x. u
int Plus(int one, int two); S1 m0 O) H+ A) n/ o' B% E% U* i
7 c. V, @+ _5 U- t2 x* H# e8 k4 A }
0 p/ C' a$ Y# B% r/ P8 N5 \3 o6 F
0 G- \" {7 L4 p3 r8 \. V" V2 c}$ f7 U6 k: [2 N8 E. G
4 ?! d; z6 D. C. ~2 @- f4 D* D1 d9 L0 U( f& B
2 f: R) F) V2 d' w- `" Z
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码& c' z* o2 N0 s1 s
" A8 z, O7 L! Y! \7 ?using System.Runtime.InteropServices;
4 D$ Y; E" _. X) M* B- Y! O/ f4 m% n8 K- F" Y: m6 [2 J* O1 w
namespace MEI_AddCom9 q' l9 P) W! X- s1 Y, O+ F9 p9 l
8 a3 k' D8 ?1 D
{! e, P/ }+ ?4 ?7 }, A
3 G9 W% e+ o1 ^* n8 X$ }2 |# H
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]; G4 C% @9 {/ F
, b6 B& o; O6 [) Q5 J
[ClassInterface(ClassInterfaceType.None)]' ]0 D! b, p: w
9 n3 l& U5 k2 v, p
public class MEI_COM_T : MEI_COM
* w; H% K8 J3 g ^% I: r- r- G' c, P
{& H/ z7 r2 A4 }) W$ }
. u4 K" F3 L' z
public int Plus(int a, int b)
, @: q) ^& _. H% m) ~6 ?0 d7 t5 u8 `0 Y1 T' p# `% k0 I
{6 P* w( U+ r6 t: _
9 T) p+ T; I, S: T return a + b ;
! B. f; b1 y& p$ E
6 F1 d+ m( ^6 ^- k, j }
$ C( U- Z0 x" W, A8 k& K, }
1 M, |0 E j( R& r8 x2 B% n' O }
% N# l7 X* ^2 A+ ]5 E- d" }9 X+ h3 U+ V3 q; `
}) _$ N7 V9 P% g/ c, O4 q2 K. Z
7 w% R6 E2 h6 i( c
+ B& V' t6 r5 x: b: D/ V: Z2 D: v3 F# B, I* d
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].& ~+ y, j+ G) E- i4 \; J! `
' ?- @2 V1 b0 ~8 F/ R
右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册
2 W8 |, V4 O- t$ I% H; U; d2 I' Q: I. m# C5 ^+ H9 {' c
1 l$ M$ K6 W# w8 ^
5. 生成->生成解决方案
9 z8 H# K. ? y3 V 注意 这个时候 生成 非常缓慢 % m5 J2 K1 X0 D0 F. b. C5 p
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
) o$ h) C* P i3 Z0 R
8 Y7 j$ U/ g2 f- H
5 w+ X* z* f+ l! B0 X---------------------------
6 L2 T/ w P m3 w i! c3 [" v8 v% I4 r+ Z4 l
1.调用前要先把com组件注册才行.
) W* @) m& |( _/ }3 S7 d; e3 B7 G" q0 l, h
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
. r' U/ x: f7 N# `7 C: s以下说明如何通过C# 注册、注销COM组件。
& B4 t8 r1 P2 g: F% T' |( Q: d3 }7 {5 N8 R. S3 @! C; s9 O8 L% d
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
( {5 N1 G& A D1 v打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
, H p" P1 I* N- i, H- s$ R1 c9 B创建完成后COMLib项目中将出现后缀为.snk的签名文件。
- d/ v8 p2 f# k: _: 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文件。
" ~3 {. |* `1 a6 h! v: V卸载COM组件:
9 @$ f5 w$ r4 |+ k9 _* Y" l与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。+ D; v$ N3 c4 W/ U6 P6 m: r
3 W% q* ]& i# S' I4 l: S5 d
$ @! p4 U( A0 H, o: t5 h2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
2 Z5 h, P) R! F! Q% ?7 ]/ A+ ~+ b L! |. T6 ^
名字取MEI_UseCsharpCom,点完成
0 e# n, q0 \+ F3 s; u& i( S5 H
) c* {' M) _0 Y# b把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.
% u( s3 n3 n/ c, Z& I* ~8 a! ]+ S, { c) ~7 d2 b4 {6 e# Q" W7 v- F
我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:0 D( n. [% _+ [) t3 @
) x3 `" o+ z& M- R% [2 L( L
. `% a% k$ Q$ y( B#include "stdafx.h"
j0 b3 ]1 y. K* t/ X#include <windows.h>5 D) Q: T/ h- l: U
#include <string.h>5 I1 |) ^, S" u2 h
! @+ n l4 \& Q+ D& K2 A' r9 F8 K( d
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
9 J& V8 U) K F% M2 q5 G' q
' [' m! N `, O! N' t* [char* WcharToChar(const wchar_t* wp) //wchar_t转char*4 C* ], `2 f8 k% }
{ ' J0 q% b, I, a0 Q
char *m_char;
$ M* f E J7 O* r2 i+ E int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
9 c+ \9 \2 Z- y! x5 _1 t+ a m_char=new char[len+1]; 2 q+ D$ e7 b; k( B. N! }
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); * c4 z( I5 Y( { e
m_char[len]='\0'; 8 M; M: B0 A6 A# m
return m_char;
- H% g3 l1 F9 L6 J}
) X% Z+ G. o+ S9 Uwchar_t* CharToWchar(const char* c) //char*转wchar_t6 P F3 l% d1 F# J; B8 h7 n
{
4 L' R$ }$ p6 R' L5 w wchar_t *m_wchar;
4 x3 K* A" [3 f, z! q1 @ int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); 6 [$ ]+ N$ d4 R q% X% ]
m_wchar=new wchar_t[len+1];
& N/ k9 V8 \# F MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); 7 l2 I6 w2 F0 {& r6 {6 f
m_wchar[len]='\0';
7 q' M9 F2 Q9 h- C6 b) w return m_wchar; - H e. D" u" i- y
} + g/ \ k: B3 O: o& V
, Y8 T3 E2 A' E/ d; }void _tmain(int argc, _TCHAR* argv[])! N$ c( n$ } V' F5 z6 x0 D8 @, A
! N9 [+ g$ n. u5 k" f{
7 j! o. _7 m/ C7 \; p1 ]# k$ i! Q+ |1 ~8 ~. s4 K" x
CoInitialize(NULL);
5 o" R( v. {3 G8 J& ^4 i9 M2 J$ e! \& |: i$ n
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针' c+ a7 S, Z% s% C2 f. P5 S: @' \
$ W/ k' ^" q, Q2 M% g) H/ B, w# V
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
6 L( |# I% r, {# B' i* x; W/ T! P7 ]0 A P. d
//这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接5 x' F s$ F$ P1 y ~
3 r& A5 b2 _: [ //来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
" I' w5 S2 W( i/ D! C7 F //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
! [% N( c! s$ j( d; r
* a1 v. K( K% M+ P) k long a = 1;
$ ]: V& G" `! ~" h3 e1 z8 l! j
6 B- u: T, } n9 M; n0 J% w long * lPtr = &a;; E5 P9 k" V8 k! H( ]
W: z1 x1 ^, h; Z* t) y5 v, @ ptr->Plus(1,2,lPtr);1 ^1 q F9 M) N1 B; s* w
; _3 @5 \0 ?1 T
char msg[132]="";) Q% y% c5 d: I: q1 l/ b' K+ R
sprintf(msg, "%d",lPtr[0]);* j% y6 x7 [- s, K& B
8 k2 d1 c0 c* R0 N& s8 ]. ^0 Z
LPCWSTR str=CharToWchar(msg);
I" S) A: ~4 b+ `" B6 z9 p. D2 W
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);$ ~, G+ b, i/ i2 {
/ m$ |; k) V* N {3 O" U8 _5 e. P# w; e/ y5 h9 A
}
! A" T: B& |/ ^& ^" r& A! n u# R
2 F% k. x5 R6 o此时就可以正确运行了.得到结果3
, e; F9 E+ C7 y% }) J. b1 P: V2 c; w. w }( M, t
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
9 \$ l7 P4 b, k9 {" h+ G
- `9 l, f# J% W* ?+ [$ c) ?& Y9 x- M+ G% _
--------------------------------------------------------------4 k) [3 P& h# Z: q, A1 D
C# Npoi库 操作excel 的代码网上很多! K3 W6 X J. z d
7 R. l, c8 y( K1 F
// ----------------------------------------------------------------------5 Q! Y( b0 w, p4 p2 m7 d
// 使用Npoi创建一个简单的xls文件,写内容
' i$ p- l' Q0 P( b
) p5 Z$ X$ `' k9 rusing System;
4 t- D3 O: ~9 y6 a. qusing System.Collections.Generic;, W) ? {& G% y) C/ [
using System.Linq;
5 A' a+ m$ H R% t3 R* qusing System.Text;1 j6 d2 H& x) x# t7 } G1 H
using NPOI.SS.UserModel;& t* R* E- T' ~, G' p- R" P! d
using NPOI.XSSF.UserModel;/ O) N8 M- z2 G2 z l: A+ e
using NPOI.HSSF.UserModel;4 P8 n4 j' @1 @/ L$ C
using System.IO;3 o1 k \1 B; r: I7 I3 m; c
using System.Data;
, ^' s, }7 z3 t$ V( e, b$ W/ m. ~6 v0 N+ n0 N" ?, {
//using System.Windows.Forms; & l; Q* Y9 c' p+ f, M
. G3 C1 N# l# W) l9 Snamespace CC
- [. D2 R2 O, @* Y8 b{
. a" J) X9 a2 U2 j5 z$ c) b! J6 K% Y* e& o* H' H
class Program. L4 R. \$ _0 r: o
{& R; S3 p% p6 ?* |
, z; w8 m$ D% Z; t1 z0 _9 x0 j7 ] B
static void Main(string[] args)5 g) I0 W) h% k
{+ Q- ^- m% H& M3 C8 | e
//创建工作薄: }/ x" N, P/ F% K) w
HSSFWorkbook wk = new HSSFWorkbook();9 \4 `7 G/ _, ], m2 s
//创建一个名称为mySheet的表) o$ Q% O5 `, J$ c2 {6 a; @
ISheet tb = wk.CreateSheet("mySheet");: _6 p5 [4 U. K% e# |8 d/ f1 A0 D
//创建一行,此行为第二行
; ^ R( R& B8 m% s. k IRow row = tb.CreateRow(1);0 \" r, p9 ^ w7 g
for (int i = 0; i < 20; i++)
$ Y" j/ X" c, v2 P8 V/ V {
2 O1 D# D$ y* F ICell cell = row.CreateCell(i); //在第二行中创建单元格
* `! x' D/ b+ m/ ?6 ]8 x* @6 S( h% y cell.SetCellValue(i);//循环往第二行的单元格中添加数据& g- ~9 L; K3 A) h( h: G
}8 }' r& n8 ^& a+ ]* g
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!) q9 N0 d0 O, a
{
( z7 H1 N7 m e7 V' J6 g, W wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
9 z) _' }, ^- Q8 b/ E // MessageBox.Show("提示:创建成功!");
( P) z% U, u* H4 ^, ^$ D; @# ]( r }7 R! @1 y! k0 i# Y; V+ }6 D5 f
1 m. s* x {! ~2 K" Y- k: X% P Z } R' o2 ?/ _% { P, g7 c& E1 L o
/ b! g G/ i8 \% k5 V' ~: l! R
}
$ Q! ?0 y3 G4 v
2 T3 ]6 c. `% A8 Y7 G: c1 l/ `6 J$ S b( ~; l
& k0 P+ M! b/ p; ?3 I! e
}; m2 S; _4 o2 k8 P- _
, b8 X" ^) C. b( y: v) i// ----------------------------------------------------------------------
l4 [9 F$ ^, t3 o3 g// 使用Npoi读一个简单的xls文件
2 i! C* Y* X' a1 X: z
]/ V3 Z( O! Q& n7 z! Nusing System;" W: p- I0 L" `, u/ X
using System.Collections.Generic;
( Q% v' J) n6 q8 b6 ~5 B5 lusing System.Linq;
/ z/ {! T9 w( ^/ zusing System.Text;. g- r- r2 B* i) q( Y# H
using NPOI.SS.UserModel;
% ]8 a; c. w; o4 X7 kusing NPOI.XSSF.UserModel;
' v2 w/ E' a& N' [- d+ `' J3 ~using NPOI.HSSF.UserModel;
7 m4 x& X+ V% z$ d5 Xusing System.IO;
6 g/ o# U3 m& t- {) [- C& K$ Yusing System.Data;& `' M4 C" g- }! [7 M( e
5 [! d" |" ^7 U* {: x5 lnamespace CC. _. W( K' S9 B, H; t
{
: w; R& I. K @6 o
3 ^& d& l3 l" p& R4 ^' e class Program3 M% o! ?( K' L- S5 Q, O2 r0 ~7 ?) G
{$ V/ ~1 A# Q' n- x; h
' G8 x6 e. s5 j& I1 T
$ t0 {5 [3 u% t9 |3 Q: [8 i
static void Main(string[] args)
* j% H9 k9 N( t9 T- l, q h {, ^% t" u& M0 T5 W' U
StringBuilder sbr = new StringBuilder();+ Y" c. e( h8 ?+ i
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件1 P) Q; ?) l0 }1 Z/ {$ L3 @; s
{ v; E* \% F! F. [ N# _6 D) S
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中* l# c9 t' |/ B& r) M* V+ D
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数; n+ M* [+ j" p" s2 d* [" l& u/ \
{
8 b, i2 k5 ? t ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
5 ~; S" h+ ~ i# ]3 t# y* `5 k6 o for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
# F1 _+ S) H7 g, c f6 c {. I2 ~, D; X$ Y( Z
IRow row = sheet.GetRow(j); //读取当前行数据
) S- a) o& P3 _0 M- j* @7 x4 d if (row != null)
+ c1 O! n, @2 V {- n7 }# Q% E) T/ }$ R- Y. k& l" w
sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
% @$ `# m* Y8 g: Y9 v6 x for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
$ F5 i; P4 R' D {$ {1 F) j- r* Y4 z
ICell cell = row.GetCell(k); //当前表格) `) H: k. G4 Q% v+ ~7 I" J2 M: K
if (cell != null)
, _) {9 d L& C2 ~& X0 I {" l0 h- S7 B! `9 R
sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型
& e& v: C: S3 } T }
) L& M: h. c. a6 r# V8 M }3 n. ~6 K, n2 j4 r
}
* K7 }3 e. M3 P } ]: k# j5 |* B: U, E7 [
}) P3 {0 c2 o# E& H9 e' _) Z' e" P
}+ Q2 Y0 N- _, E' J
sbr.ToString();
' b7 R# Q! ?* H! s1 Q/ K2 U2 M using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
& {, ^/ h9 c2 n# e {
2 R( v9 _- p- R; ~2 x l wr.Write(sbr.ToString());
* d, t: z6 G* @# }0 O wr.Flush();
+ g) Q3 w) I: s1 N. y5 a4 v. m( } }4 x" K r5 _) h( T, T3 E
( v; w% y# l3 O2 N6 ~* u3 e/ M' B. M Y& C3 W2 n; ^8 p
}
; S' v t5 \1 z( D9 O! n5 p& o8 _8 A
4 r' c' X1 B0 T
?3 H8 | C+ o! R }6 b# `9 J! w3 Q. `) z3 L+ B
( V U) ]8 d9 q# V0 H$ Q6 W
2 Y" G8 [2 K. _4 Q
u& g, z2 u, O! a
}7 i4 d* G. n( ^ [8 \) E" k6 K& M
$ a" H' c( ^, G0 j8 x# L/ t B8 n
# Q0 }9 F+ Q3 E7 {
然后 自己封装 给 c++用
' y4 k- V; e) h/ q q4 V% X" b
# G, S7 N. E+ i& V
/ J- Q" o# y5 f/ m0 s3 D
& P9 \/ B: K$ Y; C
9 C5 O; {7 Z+ [2 u* v0 e) s% h) D" M) U/ b6 A$ S+ i4 R) ~& n
6 `4 N$ K0 @- |7 u: [( M$ o
# X, P# z6 ^0 Z0 E7 N) z
# g% v0 ^/ g) P4 n* `, r0 a" G
7 v! g8 {: c+ z9 p! V8 ?8 C% r; N! X: ]) R" A. O& ^. d" F8 Y( I: z8 `7 A9 r
/ R3 [" H" } b3 Q% m
: s; w+ i9 n) F7 a0 s8 s4 Y1 L: R v7 E0 z: M9 X% R5 k# H
/ m/ Q1 k+ t, n+ A
0 { Z* t* o" `( i$ l5 d/ f
* ]6 ^7 M- ^* I4 _! H0 P7 e; J& a! p9 C* E% E( I
* H. k2 |# T6 k% Y0 s' t i
b0 d" Y; W. s- [3 K, o) m; ]9 D2 m3 E' o" N
9 C7 o! V* r1 Q7 i
% @! D: I; p2 O% b |
|