|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
' {. r# ^8 M4 ?# f% ~2 o% Y8 bnet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)& p& p+ j* G: C- R u z D
这里我用c# 生成 com 组件 让 c++ 调 1 e7 T# R$ X `; \* u. r+ u+ Z
9 P8 x+ A- J p% Z首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)( F; }1 r7 |6 T7 ?2 E
C++调用C#的COM组件(DLL)
0 Z7 r7 O( z, o) P D5 J9 D# S* F, E1 k( I6 n
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
/ v' B# [) }$ v Q5 Y3 ~2 @首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
^* @ [# n# ^ O# N7 {
3 S K7 y, ^6 u! w; a2 i" o
F& D2 P* l: U3 X% q1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom) e& J* x& d) _$ F7 A1 I2 P
+ f6 }/ Q: f' o+ z4 W6 q2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数! c) M7 s3 p1 r3 S. \
+ Q) L9 h4 O1 Y; K7 L具体代码:
6 {2 v+ f) V1 `. m: A" i* i7 s- _% e' l, F \
using System.Runtime.InteropServices; //记得加这个命名空间9 S1 i2 X$ X( { o! b- g. p% z( Z4 K
% z u% F; Q8 c2 mnamespace MEI_AddCom d9 f0 m; v" L
4 F- V3 O8 ]( y{6 ~2 N( T& g: S+ x( M
. [2 t# G" ~& U$ M" l7 R. v" _
[Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.
. M, O S' h9 c7 @$ e x2 M0 h+ p3 p" _6 l3 ^& ~% m/ t
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
4 E( Q, e6 A; d; f( G9 B' n! H7 N# y0 O4 x, P$ u2 w
[ComVisible(true)]
- L3 i2 r3 A: E# W- e+ a, V) c# y! F! c2 p) D+ C( B, X
public interface MEI_COM //记得用修饰符public5 @* `9 y4 X$ S$ r! s
; I: e) o% q6 v- E7 w2 e7 o H {- j) y3 W+ ~7 A! @! J+ J( |
7 y5 e7 d. k/ s
[DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面7 N6 T) h" O) S
0 C1 D& e6 r {1 Y
int Plus(int one, int two);2 q1 V# N, H/ c4 D- {
2 B0 |% S: j7 k( _! s, \5 | }1 z' P6 D6 G7 A" Q- o. o
2 n' |5 u5 Z, Y0 ?. Q+ O5 Y
}3 y: V$ F9 g J i$ i* @, L
8 s6 c! a$ z9 _. h; Y: S: |& f0 M8 Z7 `- R& e
; A" \$ K: `! d% j0 W( @ j
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码+ }4 z, a0 D% b6 r& Y/ w9 H: c
( ^9 r1 g7 D/ T5 X, i$ ` A) e- D
using System.Runtime.InteropServices;
$ W. p- R Z& W: z* |3 Y. j1 H5 x% V+ u( S9 S9 O5 \0 p
namespace MEI_AddCom9 C _$ c) h: G( a3 J
/ F- y t" d% J) N+ i& ]{( z0 |" ^ c. f; b' P5 V( O$ W
6 y: M; i! T3 W) |5 q; T3 X: I [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]
' p; ]7 l1 T. y$ e. u+ r( `' N3 r+ H: q3 W
[ClassInterface(ClassInterfaceType.None)]1 u4 {; z; H" ?
# `2 C# L. S+ Z+ K3 O public class MEI_COM_T : MEI_COM9 b8 a8 k: u3 ^4 y
S) \1 E! i B. \( X- Q- Q
{
0 g6 j( [4 _/ }, _( l6 O2 t0 Z4 {- f" |5 \0 ?' K
public int Plus(int a, int b)/ Q0 r- ~4 B& z& q. p
. p/ c4 H8 l8 m7 v9 p6 v2 m
{+ s8 S/ R; p, V0 W" w6 L
- s3 s" E( r/ U* k; c O return a + b ;2 b3 v6 v% ~: J o7 P( w
5 l- T+ u( t: S; H$ G
}
3 ]9 Y! O+ E6 I: |; E. `; m G) b4 ?; u7 k# C4 Y l ]" m
}4 O/ B2 j' \5 f
3 }6 t6 y: u/ p5 \6 A8 x
}5 x/ J. e1 c8 {. s: ^2 S
, S3 | M( J" p0 j) p2 b; u
& w s' _4 z" \, K) D' a
4 c: N* O5 o7 a! a' V4 c; ]& f/ } o4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].. W: S. R5 s1 u6 F
0 V! O4 E# L* y3 D' ~& p' z2 w
右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册* X; x% ?( A) A+ D
1 p( k1 G' ^/ e
- W/ q; d6 E, F' a' C
5. 生成->生成解决方案9 ]' w, C- x5 z, M) U" O
注意 这个时候 生成 非常缓慢 1 i0 O% u: J! C% Q V" A! _$ ~
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
0 ?$ N, \' K& w: A! a$ W7 F% I2 e! r2 ?) Y: p7 G" \) n. @
1 \, A6 S- w; s) X---------------------------# G4 d M9 _0 G
) W B# t% v" z, U! m, [- m1.调用前要先把com组件注册才行.
; g0 n6 z6 i: P; N) X0 _0 [
, m4 L; V1 n' a1 U* Q9 g使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
$ m* K0 T8 x) D7 O. l% D& `以下说明如何通过C# 注册、注销COM组件。
a! j; C* b4 P
! B V1 L2 `6 U8 T4 l( K2 y为了能让生成的DLL能够进行COM注册,需要进行强名称签名0 C z. ~+ b+ H! u
打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
1 F. T5 q/ _& g4 h- v创建完成后COMLib项目中将出现后缀为.snk的签名文件。4 l4 ?+ ^/ o7 @+ T' s
最后,编译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文件。4 b) V; J3 f" G4 ?- k1 c
卸载COM组件:
& G# h9 e! z, y" @4 b与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
& C& N+ R/ u. |) P; C
7 S/ ~( i' G3 J( g9 E, F; k2 [. {, Y* p, ^" F: g
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序( c# Q- a, w1 M9 s
9 H9 X7 K8 [+ t8 B. H) h4 B名字取MEI_UseCsharpCom,点完成
0 e6 ]8 y& p' ^. L/ H* E
/ d! f- I! }* o9 k4 a8 g把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.1 Y6 o3 p6 _+ B
; ~, q2 E: v3 g
我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
* S* w' n- a1 e* a
9 i+ E" a" U! H) K' e, Z* O4 n5 k
( A/ t; U& r5 Y#include "stdafx.h"
% w* u1 F- _: g1 u' l% O( f6 l#include <windows.h>
' c) d. H I9 C5 S7 z- F- t#include <string.h>
6 _1 L/ u2 ]' q8 F" J( V3 m' X$ i( V# j
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only/ u: N2 g: j0 L
9 D$ k, Z9 g& J
char* WcharToChar(const wchar_t* wp) //wchar_t转char*% f, i) j! {7 I! c9 Q( Q0 r& H
{ 5 L- S2 g2 f; j4 Q5 q9 S
char *m_char;$ K; N+ J( ~. ?
int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); " p2 a$ d8 O- U) `* Q; E
m_char=new char[len+1]; ) d0 X3 R! P5 T! K: [1 ~
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); 2 V5 l% k' |# p! a: n) E% h& B
m_char[len]='\0'; ! x) N1 b- M0 V' S: m
return m_char;
8 d7 h- S- m7 m, c}
7 p" t R7 M0 ]" a6 u- dwchar_t* CharToWchar(const char* c) //char*转wchar_t
9 E$ d) W# H9 J3 w; L{
- L w# W, j0 q0 N I( m wchar_t *m_wchar;
' ^; A3 j* z+ g# K6 E E int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); 2 K7 ]" _5 j% {5 O5 W. D6 f
m_wchar=new wchar_t[len+1]; , L$ _0 d* U( a' g& H+ e) z* S- h
MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); * W+ S0 q' ~& {9 s
m_wchar[len]='\0';
5 H3 ^' C. S2 i5 f* N return m_wchar; + Q1 M. Q1 }8 T: E7 C% p1 C
}
( q( R4 Y0 r; R' a( X+ w" m6 b& Z- ^
void _tmain(int argc, _TCHAR* argv[])9 ~' {2 n" x7 W, o
" @2 ~9 I( \& l v4 M, M
{4 i7 s4 ^/ } T( ?4 Q. u0 Z, ^) d
. z9 N" ^5 A2 p5 H' ]+ E
CoInitialize(NULL);
8 G2 s b: g1 D( ?- m# f# h3 e
3 w# Y7 F; |- G) b) j1 c MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
. g5 ]) e0 Q( J- ], q; Z+ C, E. @" X1 }0 g4 P! S: n
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
5 u$ a/ f4 [7 X3 r
: k& I' u# u" N! ~8 Y# t9 i //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
( q( R0 c4 a1 A! j# U
, i2 r1 ?* [. g2 @% l //来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
( M+ S! `' L2 o. O* P7 V+ L //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果$ a ?& [* Y$ ^4 O; D
' v, G3 {5 M, m1 N7 m long a = 1;
, `& e/ g9 j! a6 }; u% e
: D' e! o/ M4 G9 D6 G long * lPtr = &a;
& M. ]* Z& j! ]. t$ V- B
) P0 D" c: X" F ptr->Plus(1,2,lPtr);
/ j( ^5 [" h* O7 ?
+ Y3 D5 [+ T, @6 _. z3 T* ?4 @ char msg[132]="";$ f; H% j' ?$ ?2 [/ {3 b5 T
sprintf(msg, "%d",lPtr[0]);' c$ w! l) |; t/ Q
4 G7 K% \& c: D$ z: @, j LPCWSTR str=CharToWchar(msg);2 k$ P/ J! M5 v% a3 F
# ?; \, P% k3 _: ]$ W4 R7 V
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
2 k K! ~: ^' O& f# z
, N( b; c: F! f, ~& `
# M$ N' b; r6 I- ]- i}% x X- N4 e4 {9 {0 j
% y4 r& A1 U0 Z+ k3 q% w4 R
此时就可以正确运行了.得到结果3
2 |- v; ~( e% V6 R m0 q/ J* G
5 s0 t- V2 Q" [" {7 R# Z4 [' d如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.5 { `6 x/ S! m
# J* V" u0 ~6 y6 u
8 X( b5 V, p- X7 y8 c7 y--------------------------------------------------------------
# C n* o9 _- H% s, x7 {C# Npoi库 操作excel 的代码网上很多/ V* w# I: g0 i n
# [9 j V$ Q, W* r, `// ----------------------------------------------------------------------! F* X+ ^! m* c8 f, R4 d
// 使用Npoi创建一个简单的xls文件,写内容, ~: v& ]) D, y5 e
# y8 ^. t, H! P( S. r& `% U+ f `using System;* C& B# _9 e& V" ] q& h1 i9 F0 u
using System.Collections.Generic;/ a- `6 Y( y4 p2 [4 @
using System.Linq;
* f& l4 Y8 b+ D; l7 y, nusing System.Text;1 Y- k1 x6 @; K" T1 B
using NPOI.SS.UserModel; f/ R' W! L( r+ w9 U z
using NPOI.XSSF.UserModel;
- g& _3 b9 Z( o! S H6 G, e+ l7 husing NPOI.HSSF.UserModel;
2 J, ?- I v6 S8 ?' L( c* O8 pusing System.IO;
. F+ b' N3 |1 D9 D. {/ Kusing System.Data;- Y' L0 k. P+ b! F5 k
) t2 c4 Z: k/ d, u) ^
//using System.Windows.Forms;
$ H7 Z% t7 ~' i* [" z0 U& Q2 V, ?; p4 i
namespace CC" O2 D7 P+ y) f8 f
{$ ]/ _2 S8 f5 n [7 l& k; T
. U0 I' _- {/ h( D, [
class Program1 |% j5 g! |. p& W
{1 T, u6 @+ W& m3 A2 V/ e; t8 z
: l. c/ H( v9 s2 [
4 W( k$ [ ^$ J# L6 O1 W static void Main(string[] args)8 d2 @7 h8 ]6 n/ t" u
{
/ D( M4 N" w# ~ //创建工作薄9 X! M- x) d/ A- Y7 W: }7 p3 x, n
HSSFWorkbook wk = new HSSFWorkbook();8 w: s& t: _. x9 A0 a
//创建一个名称为mySheet的表6 y; f' j% c& }4 J$ c# P
ISheet tb = wk.CreateSheet("mySheet");
+ D( F7 ^0 D) \) U" p/ P //创建一行,此行为第二行
: x- `: Y( N" ` ^3 C) @# j& B& { IRow row = tb.CreateRow(1);0 @$ L' t8 u- _" }
for (int i = 0; i < 20; i++)- Y e6 P' p- @2 V' `
{! ^' E& \- S7 M# w5 k3 K
ICell cell = row.CreateCell(i); //在第二行中创建单元格/ _! d0 L& \5 z1 w) N
cell.SetCellValue(i);//循环往第二行的单元格中添加数据
4 c. F0 l/ }: z6 y2 m8 |9 S }
$ q! V4 L% ?3 u- V1 r using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
0 Y) F1 ?( h+ S. n5 F- J9 k {, r; o# D' F( z# z5 I F. Q' s
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。6 v# W; ? P+ w
// MessageBox.Show("提示:创建成功!");
/ h$ S4 W4 G, f }7 K5 _' ^( V8 G/ k" }
2 a2 h; B2 r; q6 N- C/ x: B; h) w3 Q
}' X; F; ~3 _$ w( N6 w: S: v7 K$ o9 B
& x9 m( k+ l& x m, O! `$ I
* I- ^7 N% ^+ {: v6 \
}
0 v; g5 [) O. A* L* x
) _' n e3 t3 A, ^ ~8 b
8 F' ]( q6 a. x6 O/ P; J
# G Z3 R- f, Q5 F; n}8 r! `6 W% m+ `6 \5 i- j1 L
9 B4 U9 M8 F. A) S/ E$ a2 ^
// ----------------------------------------------------------------------6 X" F/ O- F# m# c4 I6 V! P
// 使用Npoi读一个简单的xls文件. b ^: Q, s: {1 h) Y* _
8 ]% j5 F( t0 t q
using System;
; u( D+ z7 W( [: r1 susing System.Collections.Generic;
) [: M6 w" n4 j! ?( t' Nusing System.Linq;
F9 K( u, W( H H! |using System.Text;
: o4 F" d( ]: l7 Nusing NPOI.SS.UserModel;: w! D6 _* ^# @: h& Q! A- T8 |
using NPOI.XSSF.UserModel;- m/ y1 q3 I# B9 }6 C! ?+ ]
using NPOI.HSSF.UserModel;+ C: r2 X5 X g; D7 ?
using System.IO;
4 W8 c$ R% v) `5 o/ pusing System.Data;
* r) ]5 ^- ~+ n) a- A4 C$ L5 A* D4 K1 s9 }, `
namespace CC
/ C- Q8 G6 ~& S% a# K: x" n* C0 }: C{( E* z3 F( |8 ~& E8 @/ f
1 f8 G. c3 }4 F, d class Program1 J- H, f' ^0 U1 b+ {% D$ F
{6 L" _, u+ _5 M& ]0 L
0 S+ y+ q% _7 Z% g: U2 [2 x/ Z
& b. F. j, d. N5 e# | static void Main(string[] args)
6 B4 T$ _. v; a X/ W# P# { {5 c6 F$ F7 e# h5 Y: \
StringBuilder sbr = new StringBuilder();
: Y7 m& i, @' @ using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件6 t# Y: A1 D, T: ~5 U+ A
{' T7 B9 X$ p7 W) p* J8 }1 d
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
) ~! g6 G' P$ G1 p2 A. F for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
. Y9 c: o8 V( `( W+ S# z {
; W" q2 `0 `# ^( X8 j, q% Q ISheet sheet = wk.GetSheetAt(i); //读取当前表数据* H# k/ o2 l s! v
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
, e$ ~( C, |% R& V* l {1 ]' A0 b6 h! e2 N% x( ~5 Z
IRow row = sheet.GetRow(j); //读取当前行数据9 a) |# h5 E' x6 c
if (row != null)7 s' P5 D/ ]0 B4 O) y
{ n& x" {) A0 w7 T$ F8 S
sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
# a3 C6 x: _3 m" d, x. V for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数* y2 T8 ^3 S) S; b
{
9 X8 f1 A0 }! r* K ICell cell = row.GetCell(k); //当前表格/ n2 J* Z7 g9 C' X, p4 C
if (cell != null)
, J4 Z5 o3 ?" F0 k: }. s8 f) ~% z {' ~9 D* P1 I; P
sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型( H: X3 c9 _& W) _
}
% G" K+ d1 N/ e1 M" ] }1 P% o+ y/ N/ ~; e! Z
}
, L$ J4 ]) N0 N! ?, v# C, S9 ^ }
0 i3 a, d6 }; z0 V: { }
: Y0 D0 W5 v f }
3 r! r' o) k4 o% @- t0 E+ s sbr.ToString();2 o, c. W5 _$ ?- D" L
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
3 l( ]# ?) U% E0 G: g$ { {
* b+ G0 X- [4 v4 ~" X wr.Write(sbr.ToString());# C0 B) e. v0 f! y4 v0 ~" t
wr.Flush();( j9 Q- c1 r& y# c6 R. K
}. p) d- d, m" `# Y5 {5 Q; Q. `% c4 p: K
. t3 ^* ^8 ?4 a9 y0 ^) F2 K! z; y# [: f" S
}
) t5 W6 l5 H# j( M( ] r
5 [: v4 k2 _0 R0 g. J$ f6 B7 a6 P* c& { g* Z
}
" i5 D4 A- g F6 p O1 }4 b3 F+ K) `1 C
2 H/ e4 G3 w( k. d0 X. L0 B8 ^+ X
2 O9 V* g4 m/ ?}
4 }1 f- l! M8 n3 M: }, h5 X4 g' h3 V1 Z4 O
+ ^. i9 A- R9 ^" R( D
然后 自己封装 给 c++用
0 r$ N7 Y! a; W
6 Z; t" f* }/ W7 J" A0 Q- A0 O2 r7 n
8 p+ W- [; W1 G6 D" J$ C! r, p1 A( l
0 u: k6 p% j# [& \2 g
9 x2 U, g% ], a& x& K/ Y
; ^- P% N: n7 |3 s+ c0 z* _& H0 N; y0 t# j6 d& z
& E. l8 W3 N. C2 d! L6 p; F7 O* I' o2 U1 G9 Y" z
: P+ \) d& Q$ Y/ w; ] c8 j8 Y
3 b- }( T- j3 Z" n2 @4 l* G
) y9 P/ } P- f: w, }' `
8 N1 @0 b5 J4 d6 Y0 H
9 B! V+ O/ b. P9 U/ P
" J' q# }9 B4 O, G! ~! u. Z; w8 B8 ^" l' |/ H) P/ e
1 g3 w' |0 Z' ?! ?) S1 `& y
8 L& x8 p0 R( a& F) g I8 L; ]
, `6 V: f* w/ f7 I" r3 V
, w/ Y( f8 ^; ]$ v5 q2 e# X4 L. Z6 m! p- t: C
5 \: C( g+ a: p' ]
7 U9 h0 ^9 ? }" H |
|