|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢5 U1 Y1 v3 t) v( j
net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)% d* T" \/ R P1 p
这里我用c# 生成 com 组件 让 c++ 调
3 z+ V1 l0 m2 C$ a% s, l
4 Q* w5 @4 P0 r5 { x首先要学会 c++ 调 c# com组件的方法 (和com注册的方法); g7 v0 A% m& I. J6 u- W* y
C++调用C#的COM组件(DLL)& n0 |. n- k4 v) Q! s# a; w5 r4 ^6 u( B
9 h9 U# V. j" p3 a( {7 S
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
! u! _) M! Q- ~8 w: @- T首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
: z1 _/ r9 h) R0 F6 Z4 ]) ?. R# W+ w3 f; b+ \! J3 B
# S2 A% x5 X0 j1 ] f% x1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom0 h& A. m8 O2 H- h! y5 b# H. A, }: L
% c6 C( D6 ]1 v2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
4 s; T1 P8 ?. ^! C1 l6 }; q& _$ }+ T4 J2 A
具体代码:
. r( O) e7 v' [+ Q; } d% r( `) D# r
using System.Runtime.InteropServices; //记得加这个命名空间 v- q, T' [8 w
* {$ l8 C3 x8 B0 p. L
namespace MEI_AddCom( ~9 O& B j7 d" B
$ U$ [) y0 {, B7 F' f2 f. Y{
; L: W$ I& b4 i# P: {7 N- R |4 F/ K# X/ m3 M# ?5 E, `: W: r
[Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.9 k2 R0 R0 f4 n1 p$ r+ B- A+ a
' L2 b7 G6 r, L1 j# U //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
0 u1 T% _- G3 e& a2 ` R/ e
8 n' q+ T4 c" j3 w [ComVisible(true)]. C' t$ _! Z4 l1 b- I6 l2 ]
/ }) |" N. q# q4 ]' y
public interface MEI_COM //记得用修饰符public7 K( v7 q/ F! N; `4 y0 h/ z
3 u+ d" \# `* I- w' G7 ? {6 s' d: X$ ?1 k O8 E
8 i7 Q2 [' W/ S3 ^ [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面9 h+ L8 ?" v& m% [, g
+ d) X4 ?# J. V+ |; R int Plus(int one, int two);
6 H& H% ^8 J1 W1 b$ d4 a9 L; ]
9 X# X! P6 h) }4 D' v }
! S) s) j0 n% j/ e4 A8 l& Y. i/ [' m' f
}
4 K1 t* Z" E ~3 b& M$ I- N! {5 S) t. y
! r( t" P" H, g3 O
) C* q$ E' s' ^. n# u& M+ g3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码
) ^; L+ I3 }, ]* f
1 F2 Q( [5 A' q; qusing System.Runtime.InteropServices;
+ k% b) N$ K5 k% Q3 L+ @
& @: x/ ~/ e9 \' ^' \. [3 W- z5 mnamespace MEI_AddCom! t1 t! y! L4 V# f$ [. x
; d, }+ i: j' r4 |' k$ a{
) z/ r1 h) o1 K5 {
$ P& C6 j* }- a [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]$ O5 G1 C, G* ]6 n
5 a; M& K e1 D$ D [ClassInterface(ClassInterfaceType.None)]& Q5 y7 Z- \$ C" C
# `6 O+ Q" Q2 o, G4 U4 ?$ u8 ~: Z public class MEI_COM_T : MEI_COM
1 s+ u2 O# ^3 ` X0 n: t& k5 x5 Q9 V0 S6 G" Y% w& i1 j+ d1 L: f4 T( f
{
9 C6 z. K1 e0 n/ S2 P$ a. T) i% p7 M% |7 T& \8 v& Q7 z
public int Plus(int a, int b)
. n# W6 E! p2 w6 f7 K8 x4 }! w2 W
4 n u6 `5 W, G. U: @* S* ~ {
2 S3 [$ G$ W) Z: P3 T) s: E, O+ N+ E. ^+ R& p( E
return a + b ;
, J5 t5 |( c/ m. }* ~
- v V! q) }. K& ` }
% n5 s9 A& c" l! F& h# p
" r5 x2 Q" I: F1 s5 c }
c! G9 c3 X; h6 f! M& X9 o3 Q6 P M/ y2 F3 `, }
}
9 J& v- u8 r2 T6 C# L4 N- ]4 c6 c
V# T6 e. v, ?) I' Z# y
. c3 C1 }" `* a- f* g3 Q6 C* A0 Y
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].0 j0 C# L: Q3 K/ }, C- v
* g* x! }* E7 k5 M右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册6 C9 V% E" _) c$ y8 ^
- a4 u% A1 V! F
5 ~2 K( R2 Z; `7 S8 c) s) C* i! O4 q, {5. 生成->生成解决方案
- b8 q: J$ C5 A& n' L 注意 这个时候 生成 非常缓慢 & a+ O! |9 p: t9 w0 |- }
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
3 Z0 _, \" a! Y' }5 |$ J' ^% T) N) R0 [* _, t
- a, q: y/ m% G! b1 _
---------------------------9 j# A, g& Y: x8 W6 ?
# G( G J& H5 w
1.调用前要先把com组件注册才行.) u' Z% @7 _8 h8 E
5 P8 n5 D4 [# p. N8 I" P' l
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
# G! r. c5 a: c以下说明如何通过C# 注册、注销COM组件。 ' L& R; i: E3 M7 _4 S
7 n% l# _$ R: A4 c8 a- P6 @5 o) o' h" B
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
/ k7 U( W5 b) K* ^( N打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。* t1 k# }" G" R
创建完成后COMLib项目中将出现后缀为.snk的签名文件。
; m3 O0 k) `- ]最后,编译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 e4 k& R$ u! [: m! D卸载COM组件:
) m) }/ C0 {/ n3 S( J" p* r& O# P8 k与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。1 d+ O5 p5 w5 C1 `) b7 {3 @; `
4 [8 [6 r9 ^7 D5 m/ Q8 l2 c
8 k3 M! G+ U% Y$ l
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
- U1 S( f) R) Q: L- G
2 P, N% x6 I2 W4 b f8 H0 r名字取MEI_UseCsharpCom,点完成
& m9 u; }# B# k# f# b$ D2 @1 ]; O: A! _" }( C7 @
把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.1 F! X- E5 `6 ]7 x
" w: T. J3 ~+ ]2 n+ b n: R, r% M
我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
3 }( ?- @( v0 E) j3 p$ V
* |) n1 C9 u3 A4 J: l- e
1 s8 R7 Y- ]$ |7 i#include "stdafx.h"
$ z1 I. x( q* z6 f" D0 E#include <windows.h>
% a- j& [$ P# H#include <string.h>9 `3 S+ n3 y6 C4 v( S0 F
" J0 r6 J/ I0 l& D
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
+ Y% K1 w) _; ?$ v4 L+ \
( J& G9 V# u$ P4 s }+ O* wchar* WcharToChar(const wchar_t* wp) //wchar_t转char*1 H4 r7 ]2 i3 b7 U* P1 c/ Q) Y
{
* `% F: J) u$ N0 N _! i# X) q5 T char *m_char;
H8 i9 \$ j: s int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); 2 X2 @& ~8 ~' J( b- X5 \0 e6 c
m_char=new char[len+1]; + E: R+ Z. F- s4 l; `! @% E# ^% `
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); 3 k% W0 B {2 } H
m_char[len]='\0';
% W6 r% r, K7 N2 ]. d return m_char;
8 h. ~3 _' ^8 B1 W} 1 g( N& B* h' Y" f5 t
wchar_t* CharToWchar(const char* c) //char*转wchar_t* _3 q/ s! V: z# Q9 C4 o
{ 1 t$ G) n, g6 L- ^: }+ p
wchar_t *m_wchar;
- j1 b$ i# x( x. y int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); 6 o4 X, g. N) g4 m. {
m_wchar=new wchar_t[len+1]; + |# y7 {) G4 s6 Q! G4 u' U4 s
MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); ) L2 b1 x, S7 _2 S4 C
m_wchar[len]='\0';
1 X5 l+ |6 O+ j9 a& V0 T. G* x return m_wchar; % o+ N7 O- q8 i }3 o* d
}
* X- ?! {5 Z+ s, I# Z( v
$ R0 ], z9 y6 Kvoid _tmain(int argc, _TCHAR* argv[])
+ W! }3 P' u% i+ L, A: u' L5 r% N1 n* | l2 I
{
: q, F" d3 q5 W
& ^8 J% L: Q) J& D9 n ^2 \ CoInitialize(NULL);5 }6 X- ^6 B- n% A3 p
- ?& y5 U! N/ e/ w' [* n
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
3 l9 u) }: `' S. V
" e# |: Q; Q0 L% \. f9 g7 c ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名9 `# e) Y5 k- @5 M
& w' f! E" a2 I I
//这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
; T5 s, c5 E2 B5 N2 ?. ?$ C6 t! _* ~$ i- k% Q H! ~
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.9 C7 e3 X2 Y0 s ]8 }
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果5 q* L! {3 |. o g1 V
& H2 C6 @, ^& t. Q U6 T3 R8 @* p
long a = 1;
* t, v- x. M; {! P4 V1 Z/ J% r5 B0 _6 w) Q3 i* G3 U
long * lPtr = &a;
8 U1 L: s. L% d! i" U( f
1 K% @+ `3 i+ e$ Z ptr->Plus(1,2,lPtr);* d( M, q! |2 O9 Z Z \
6 }: R* r3 A" }
char msg[132]="";0 @- Z/ ?1 J- x( [
sprintf(msg, "%d",lPtr[0]);
& v. k3 E% P6 g4 A' ^+ e7 t7 ` N+ T! P. p. Y# s3 |
LPCWSTR str=CharToWchar(msg);6 q+ M, Y' W+ v5 P. _& A0 i
% { k6 E- j4 h$ `
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
4 d) D) N% Q) [5 R, s1 N
2 t' \9 d$ f( s) H, Z1 {1 u, z. l& y' g8 h0 ~
}* }6 s& W! H8 l2 o. x
5 k* z* Y- d! N3 x4 I此时就可以正确运行了.得到结果31 G5 o7 ?1 \% N2 W1 D
. J& [- x+ n, u, K) k0 k2 ]如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
9 W4 Y. X' a+ P2 t8 B, ^& K: m9 Y. z1 v- h( g
+ l- I+ }' ]: y8 A, K9 \ R--------------------------------------------------------------" N& N8 o( }1 S' D
C# Npoi库 操作excel 的代码网上很多& C% J; u6 I9 n* N. D( m7 j
1 `9 {/ v2 }# |// ---------------------------------------------------------------------- |, e U3 Z: x6 p9 ]. y
// 使用Npoi创建一个简单的xls文件,写内容
( g0 P: ~7 X7 c P8 W+ [: Y6 x* z
$ Y1 z o, c9 uusing System;7 |+ g! {0 b7 f
using System.Collections.Generic;$ W- ~9 Y& B7 A& U
using System.Linq;
( x5 Z. d; s3 rusing System.Text;
. U6 a7 A( u: i+ t @ Iusing NPOI.SS.UserModel;8 w' r- \% K9 r8 S [
using NPOI.XSSF.UserModel;, y6 S9 C% D9 n. J" h8 h/ ^) q
using NPOI.HSSF.UserModel;
/ A. k2 g: Q/ {% m4 C+ V4 ?using System.IO; z3 q% Q, k) f* n. l3 \6 w o
using System.Data;* p7 ~% D' T- s; r% A
0 F2 X- m" X; b& |1 T" P' N3 e//using System.Windows.Forms; ! Z/ k9 v" `! i' }% C' I" ?
4 l. w! W- h1 X2 g6 n8 c6 G. R) p
namespace CC
$ M6 G6 W/ T( H3 ^1 [ {{8 A% [7 L$ @8 m4 t
& J# K& b6 \/ K class Program* K% f7 A* w! s' z. ]# I- ]" z
{3 p9 q3 t3 I4 a o( n9 K
1 }) E6 [% g5 F9 _3 d- K7 f+ F$ B5 Q% P+ Z' P# I( W
static void Main(string[] args)
8 y( E7 Z! J8 q {
' Z. E* a6 F, f5 g+ I: } { //创建工作薄
1 j. z# i! \( W" X+ G* e HSSFWorkbook wk = new HSSFWorkbook();0 p5 c# L. ?. |" z+ \. j
//创建一个名称为mySheet的表, H/ J! G; H' c; `: } L
ISheet tb = wk.CreateSheet("mySheet");( O0 x$ |) V5 x: I: C
//创建一行,此行为第二行 z) P' I) p9 E1 b% B; x
IRow row = tb.CreateRow(1);
. c: j; e% z% i! K- N for (int i = 0; i < 20; i++): `# k/ W5 X7 {; p0 Y) _1 I( d$ j
{6 ?4 f4 t" G( ]0 L) x: c* O5 Z
ICell cell = row.CreateCell(i); //在第二行中创建单元格2 b& r5 {% t8 @
cell.SetCellValue(i);//循环往第二行的单元格中添加数据
! C3 k! o8 j3 ?, U% g' h, b6 j/ {3 i( q }* b5 k6 ?$ ^* V7 G1 V
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!: l1 @" v$ X$ o) I, N
{
+ F! e6 T: I) Q$ ?6 x6 ? wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。$ A: i* H5 t% O) R, E
// MessageBox.Show("提示:创建成功!");
# R" n+ ?2 O; H! F+ M [4 {2 | }
: V+ n: z8 s1 |2 X- X" P+ F$ W1 d5 A) m! u' ]+ p1 s* }# [% X
}6 r" L; x& u. `' N5 P$ k
- t+ r8 z1 t9 [7 J4 Z9 N/ r: j' G
" [+ T0 h+ m! N) [' s, b
}1 g- N" i/ }5 P! d0 G
( {# X s2 w: |& R# l% k. l3 K' e
% ?* _0 K; g3 _6 l
( x+ F( X+ j, d+ o$ j; B}# i( H7 q+ i! v
0 n/ y6 V8 x0 I: }! `
// ----------------------------------------------------------------------4 X5 |6 I5 U' {( z/ j
// 使用Npoi读一个简单的xls文件+ @. C5 r4 M* |, t% _
6 e. b6 Q: @& z3 ?( S4 F# }
using System;
1 H! Y. X2 E2 M, jusing System.Collections.Generic;
* _ C" p6 g; U, A8 }' yusing System.Linq;
. q t$ R1 P; [using System.Text;3 j$ k3 j2 g A- X8 a8 d: N
using NPOI.SS.UserModel;' o1 j' I y% ^* r# {) W4 D
using NPOI.XSSF.UserModel;5 z/ C9 _5 x- S5 J6 S2 E
using NPOI.HSSF.UserModel;
7 i3 x: y9 n- K0 H( l# ~* n' Musing System.IO;
# C5 M! h. s1 d7 Q: Q: B1 W% Tusing System.Data;
6 X0 p6 r3 J( z) y8 A$ I& j: P; z: `! S; O( @
namespace CC2 e0 g" e9 P# ]: ]' m% w/ a
{% L' x3 i% T" } m; k" h
! b- j4 c8 B% c class Program
8 W$ ~' i K9 u& l: C {& o3 y' j2 c( X' ^- P
, |. k# Z8 D0 P$ R5 G- r9 t
1 c! i! \& w' f static void Main(string[] args), B2 B. F5 C; [* N; p I. c
{
- b9 Z" y! f \7 {0 s StringBuilder sbr = new StringBuilder();, z+ ~+ ^# @' o* V
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
9 e! c& R& m" X# ?* V7 y' o! p# X8 t3 s {
4 f1 ?8 t" F1 d- T HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
$ Y+ L# Q& ^. ] for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
; P* b0 P* a7 Q9 c {# N% o1 k0 Z) K) C# m- S
ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
: @) ^5 t2 L) R: T1 m" V for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数 D/ {; ?$ r1 t: L7 s7 w5 k
{+ B5 g. u8 n8 n
IRow row = sheet.GetRow(j); //读取当前行数据1 T+ y' b' n9 q e; R
if (row != null)# }4 K5 {1 H: F# c \
{
- i1 O6 L4 K3 T, T y; i/ k sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限) R* r. M' N! e2 k1 e, [% e6 v1 G
for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数; Q* P# \+ V4 W, ~, O
{$ ?' b1 Y, j" m- T+ G6 u
ICell cell = row.GetCell(k); //当前表格
. Z( A9 M. c" k; C6 b if (cell != null)2 J6 n0 F0 V g" h5 N1 F }
{
9 P" L( v7 }% N2 g* j) g8 [ sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型6 B; f. z% {) R" `! q5 y' n6 o
}
3 x c4 k) [! ?. D5 x }
" E, g( A1 x2 B! ?' ^1 u }" N1 b- z0 u* g7 v" a% i' r( q% s
}7 O, w2 f& }# @/ Q* }. b
}
8 h5 J7 R( d2 { }
3 H. q% M% I- `0 p" ?( o1 M sbr.ToString();$ Z, Z3 }( B6 G9 u
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中, t3 q9 k0 w. k/ E ^( X- V
{% z' F" Q- e3 x& N: B' I. e+ v
wr.Write(sbr.ToString());7 I7 \5 E8 W& k, j8 `
wr.Flush();" F, i+ H$ f+ d; p* ?
}' G4 Y& d Z( s( p& R. c" t5 X
5 ~# h' }, \7 w! x/ [4 h/ m
; j% z' {- f1 @6 w) y+ H Q* h }
: _5 n/ \. f/ h3 \* g6 x8 Y9 V4 s7 s7 e8 T: ?+ p
& ~' K5 ^- y% O }0 X" Q0 \5 Q6 \ d! I
6 L. F+ R( ?' I2 q% w4 s
) ]1 A5 g; l+ ^$ M/ m* c" I* n, G4 E
! t5 H1 H0 b: }% A0 T# I7 u}
9 }/ r! J; O% R& }9 G. v6 T% w6 t/ [! c V/ y) d. W" u1 W
/ e. ]- Q) L% } ]# f9 C然后 自己封装 给 c++用; @! {1 y; t7 x3 ]" ^
% P2 X" U3 I4 L. [1 `7 ]: z- j
! u- y' k1 t8 Z+ W0 n X4 N I1 s
% @9 t0 t4 R* k; K
$ R& j$ y# ~6 k
+ q" t' G. Q! ^6 Q! c+ k+ o9 J' a8 W
* N. v0 D$ a- Y3 `! X
! t! c4 B8 y0 \. F6 }
: }+ R- `! P" u& b% o% ]5 R1 ^5 v" G$ A: Y7 ]7 K1 r X
) @/ U+ f' p' q8 o7 V$ F
7 O, _5 }/ i" q) H# } v! f8 n
1 @% _, X8 A: c7 O. [6 v+ @
; \* @0 x' G# v2 x0 v. w
6 r) {4 J8 H3 y, y3 U3 w
/ ^9 U3 g8 m6 |# A1 P2 z
: f& ]$ b! c2 r
$ Y x9 N) s' m \$ F4 `' Z* V& h7 k* Z' F) Z' @ E
" t6 e7 j- \5 j; `! `& j e% P" P$ C& @- K* [! X
& ?9 W7 I3 w# @' N$ z& u3 G
4 v, f# R4 A7 ]% s
|
|