|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
5 I9 Q) l1 a+ W4 Enet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)# P1 _9 i7 U( ?' ^1 \
这里我用c# 生成 com 组件 让 c++ 调
1 U" m$ |4 N* W2 S
+ ^7 ]3 W0 b5 x首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)
4 o8 C; K& h) b! d; R. dC++调用C#的COM组件(DLL)0 ?% j; @2 _9 r3 s
8 _* y7 y+ o% {' b
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.# A; E; @, A! w$ J) }. G O
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.) p5 |' r3 S8 j/ W
2 X8 n& I8 `; \$ A/ ~ O9 P
8 I- T+ n) Z$ s4 I& U1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom
) Y" l- N1 G' w% d0 x% c
* R! o7 ~; c- D; d, {- `2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
. N- {( h3 j8 n7 _, _$ k
' M) c3 U/ }6 D具体代码:
1 ?; ?8 }7 N! D( M; r
4 U# X; H6 g! husing System.Runtime.InteropServices; //记得加这个命名空间! W7 }6 N o2 w9 m; i: g
3 y& G; f, b. ^$ X2 M2 e$ L- t; W7 Z
namespace MEI_AddCom
% D' @. C1 l" s7 B- p+ R
7 b5 j0 e. a9 _# h{
* J+ y8 y0 W1 a8 v0 w' U, Z' t& B! H1 H$ a* C( R% [5 ?2 q' _/ R
[Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.2 M& U5 H( n8 Q9 R3 R
" j7 b3 h: d y) R) _0 w' ~ //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
* W- z3 P& B' l. L! w; v
3 V. E' Q3 R6 R5 ~1 M- N [ComVisible(true)]2 P" \8 K6 @, {/ l/ F4 L
# A5 N9 l! v3 m O6 c. V; J public interface MEI_COM //记得用修饰符public
1 M p- ?" v# L& c* c
5 |) B5 O, w. A4 E {9 W+ v& i5 l- y2 q
% B4 N1 g) \9 K" }5 j! {
[DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面& ^4 E9 J, ~- \( w
# L: \; G. o' X' b int Plus(int one, int two);4 a& O% F" F0 _
* u1 U" X+ O3 F; h7 T }
8 _9 ^7 X2 y' l+ r: l$ G5 L1 _
( X/ O3 e+ H& K* J1 \9 f1 B% \}# @# c7 D) t' ]% a- o' k0 |& E( |7 C
7 B) Y$ q, A" g' L
/ \. g# t z7 P: f# H- q9 }5 f: }
' x9 a% E4 e1 i. @
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码$ O8 k* d7 l9 @: F6 G
; I* L: i" S8 p/ ]% T2 gusing System.Runtime.InteropServices;% T+ X. s0 |2 ~
: U# q* v! `. v9 q8 H) L9 k) ?. _3 knamespace MEI_AddCom/ r5 U. w1 F, {: ]1 B( A9 P8 I) r
; N+ K* o6 n: D0 y- ^& t{ v5 F* @* D9 s1 |
2 n/ a5 f; w F: D( f! I# r# ]8 w
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]* G- b/ i2 _. t, M" a9 i
\. d' F! r% u
[ClassInterface(ClassInterfaceType.None)]
1 o I# S2 l# W, K7 X4 V# g
) R9 K9 Y& F& k* l$ c7 Q. O public class MEI_COM_T : MEI_COM
6 g2 G8 g" _- d2 \8 V, L* |% _5 z; T, a# e5 ]
{9 b$ Y+ s$ `" b3 W) t+ G' E5 t
3 y. Z" D- t) O9 z
public int Plus(int a, int b)
) p1 H# E0 `: N) n. s S* h- C: j- l0 k0 G; d) f
{' V# \/ \. O& i0 Q% ~ L
/ l$ A; ?7 o7 T) }7 {# O return a + b ;0 T8 \3 M2 B' b8 ^, C0 M
2 H u& w, D+ o- p6 ^# x* C0 l
}& K* d0 W4 R: f5 l# d8 _: d
; k& N* Y8 e+ r- Q5 Z# d S- \ }
c- r+ X( A$ m2 z$ o7 Y1 s
8 b! T9 E2 ~' J- E0 @}0 S5 c8 r/ @9 B# \3 E, R6 e
/ V: e+ f( I9 e \8 e9 N& ]! Q( U& }) i5 _# g1 C
: o" ], i+ w- X0 r' W& @+ d4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].; E0 {7 z- }- X ^/ z: _) c
" J* v O9 X# ? a% D: h5 t
右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册, L1 { d9 n2 T+ l4 J: ?
: b6 Z7 H- Y! r
) I/ j: _' H; @$ f# W( I, u
5. 生成->生成解决方案) n O3 [' U0 T
注意 这个时候 生成 非常缓慢
A( l9 W; L* n5 O/ r 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
% @# Z! B6 |0 _+ F2 N8 B: b
9 a; O' W$ ]) j* E# z$ c: i0 A% M2 M! i( G6 G* O
---------------------------+ S. T" C3 S: G6 n5 ?2 Q) j2 Z( O2 Z
) X$ @- S0 S O! B* u6 T- l
1.调用前要先把com组件注册才行.
9 f) w7 |% j/ ?# C2 X0 r/ d% Y6 t& r
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。( j9 x3 P! M, _
以下说明如何通过C# 注册、注销COM组件。
" R9 i1 b) s* h3 x5 f/ A& m9 w! W+ E s! F" H' m2 Z
为了能让生成的DLL能够进行COM注册,需要进行强名称签名6 u+ F/ W4 m$ Z+ X2 x9 T2 f
打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
& S! J" i+ i+ q( q+ z创建完成后COMLib项目中将出现后缀为.snk的签名文件。- R* m1 L6 h( Q6 f1 F3 U
最后,编译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文件。8 w; y0 H6 i% A1 e# I( I4 n: B
卸载COM组件: 9 x8 d! O. c- r
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
. f$ E4 t/ B& P6 ~! a) w8 y1 \2 d3 {: @
/ R6 m/ Z i5 F* L2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
; j, A5 x; \4 a
( ^3 ^' A9 h" v0 f# i3 X7 `7 m名字取MEI_UseCsharpCom,点完成. P3 c; H+ H# S8 N+ A' ~" ?' F
% l6 v$ q& L" \6 x; B把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom./ q: K( S3 c/ v
- m+ L* ~/ v5 @5 I( \; X9 w Y: ~$ P我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
) d+ a8 @; X! q' k7 }; N' N$ M8 _. M X* m; P' p" Q; ^
- u& b* @# x5 V3 q#include "stdafx.h") ?, Y& Y& e8 ?3 d8 r
#include <windows.h>3 P- A! P b( H. R# S0 ^
#include <string.h>
# c7 v0 M2 d; u6 y! }6 _
! b" L! L2 n. h* x9 k#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
9 C/ }& ]; z* S$ F* |
* X8 I. D# m2 q# Tchar* WcharToChar(const wchar_t* wp) //wchar_t转char*
+ M% I; p" M8 i; S/ e7 j{
2 x% N4 r* o) p char *m_char;
0 d1 A3 T) I5 m* F' v int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
& m6 C0 D" o% ^" K m_char=new char[len+1]; 7 u; e; R' Z6 U0 a$ f2 G6 b
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); / B. K6 ?: A2 g9 u- `$ F o
m_char[len]='\0'; 7 a) D, U9 @! _
return m_char; . Y1 _1 {3 }4 l) V& Z8 K4 e
}
9 i( L3 q, p/ [% M2 h' Awchar_t* CharToWchar(const char* c) //char*转wchar_t
& |: j; z- X( k/ A( H5 j' }{ " O& @. ^% p, y, [5 M4 L
wchar_t *m_wchar;- e0 d: @# U5 c2 b6 H
int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0);
0 H. H' p ?; F q2 d- ?* T# F m_wchar=new wchar_t[len+1]; 2 K3 d5 q$ m" ^
MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); H+ E7 Q/ H" }' j& G. @2 E2 f
m_wchar[len]='\0'; 1 T J( R8 [; E3 k/ q
return m_wchar;
" ~* ~- j* O6 c: y1 o} 1 g I; w/ G5 R' _
# }7 E0 O2 Y4 R5 @0 e# Tvoid _tmain(int argc, _TCHAR* argv[]), ^4 t8 o& `) {/ S( V
4 T$ K) a* Z' o7 [
{- X2 x* ?# B3 ~: Z" ]" U- ]9 R8 w
+ e V4 o( ?/ T' F6 `
CoInitialize(NULL);, m; t" j$ N) b( ]3 B' y1 `
1 D; o/ O0 M9 ?. S1 Z/ o1 u/ T MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
5 y3 K; [& o) w( }6 o% Z, R& m6 k d; m8 p: y
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
. _0 I7 ]+ g- \
+ ]# @( }5 Z. `) ~+ D2 R //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
' v9 N+ ?7 y/ K3 s
" K& B: ^0 b' b: g2 z/ T' k1 @2 B //来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.' V0 F) P) x) ^7 ?: J: N
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果2 v* Q7 D* N, O* Q* s" c
* m5 I. n# S( z0 e long a = 1;
2 o2 X: ~5 C% j) u
5 F& J4 \3 J& x; U- Z% I! @8 d8 y) E long * lPtr = &a;. [9 g9 [* _; C) m2 \: ]
) }1 x4 Q8 I- `; ]/ w A! i7 Q0 Y ptr->Plus(1,2,lPtr);( S; S; g+ ?/ W% U# o( d
* ~; J6 Q$ s P( g1 F4 o9 L4 t2 R
char msg[132]="";" b8 i c0 s% ]' A6 P& j
sprintf(msg, "%d",lPtr[0]);* h* O/ [6 \7 v7 f; V
/ V$ _" B# T T4 H* v% X. M9 K LPCWSTR str=CharToWchar(msg);
, ~0 @; d1 j' O4 u. B3 r6 P/ J7 d5 K. H4 t# ^/ e, C' @
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);0 o( P% H6 I! _7 M d4 \
% Y9 ?( V. a' w( _7 j" G9 t- B% v" S* F G% k9 f
}! `4 ~( U# r% |. B! w& p' i
# T7 r4 d8 X$ Y7 B+ H# [& E% ?5 k此时就可以正确运行了.得到结果3
, {! m: \ U6 H/ W s. Z/ H- T
- K2 A- c4 c! a% l: b如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.+ k: O6 M4 B0 i6 g, x N9 u, w
+ x- h" H" m8 N4 c
& A9 |2 y. k; j, B6 Y8 {--------------------------------------------------------------
- J. k* x U. lC# Npoi库 操作excel 的代码网上很多) d$ b* r1 f; |+ m1 [
. g- V Z( n' O5 f
// ----------------------------------------------------------------------# W4 y0 E3 H7 P2 x# I0 E! ]
// 使用Npoi创建一个简单的xls文件,写内容) }" o" `1 s- l! ?) F
. b8 z- C' U4 ^1 x
using System;
+ k( z9 _! a! t3 D D {4 G7 C7 Yusing System.Collections.Generic;
& K6 }. q+ X6 b0 \3 v- _* lusing System.Linq;
$ r7 H S3 Z6 P( k6 uusing System.Text;
1 n+ W% ^) J( ~using NPOI.SS.UserModel;
+ d9 E; E+ [+ Gusing NPOI.XSSF.UserModel;# F" M3 E" e; r$ Y! x
using NPOI.HSSF.UserModel;- }$ E$ _, H* S( R% ?" O& ~
using System.IO;
/ X) h# E0 x( s B7 j9 J1 e5 ^( J) Eusing System.Data;1 G- b5 f g/ V% [" q
. i# i" Y) D e5 U//using System.Windows.Forms; 1 t! I( H& l7 x8 _5 y* h
0 Q7 z o/ s# ]! \# W
namespace CC" c: T J, `8 G: V
{: a( h9 W: P: m& c; |+ {9 J' ^% ~* e
4 h2 ^% b9 g& c( r8 w, S# V& O
class Program) }( J/ ^. Q2 N/ [+ x k- r# }
{( x$ V4 X+ L% Y" w6 I9 O& B
) [" z: G& i7 Q: T, z
/ T [& e, N& g0 X static void Main(string[] args); y% @% A5 s& P1 W! R
{9 X4 D1 n% ^9 U7 D8 h" @
//创建工作薄7 D3 B1 @8 m" A
HSSFWorkbook wk = new HSSFWorkbook();9 [, ^" y) y% r
//创建一个名称为mySheet的表
0 T" K+ o% Y& r3 C* ?# G ISheet tb = wk.CreateSheet("mySheet");6 n7 e, @8 K9 t3 ^4 L
//创建一行,此行为第二行0 Z( P0 c( I& Q" U* h
IRow row = tb.CreateRow(1);! R" n& `' o( q* [6 `3 A
for (int i = 0; i < 20; i++)
5 G. `# Y3 u5 \ {3 G5 J8 [0 E* b9 j" O: L
ICell cell = row.CreateCell(i); //在第二行中创建单元格
/ t3 u( j4 }! ^ cell.SetCellValue(i);//循环往第二行的单元格中添加数据 T S+ @' p# B& `; C
}
* Q6 v7 O, d7 H0 q! |) I k using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
( F3 t# y& n; ^% f- h! Y7 W+ c% v {
6 U% f( b! I- E7 a wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
! j7 Z+ o+ U% b$ ? P+ L) F // MessageBox.Show("提示:创建成功!");
! f' T5 U: O5 U" | }' Q$ s' t4 l2 k) C: z
8 G" A: Y9 S! Y& A5 V }6 d+ S4 C) |) T: G2 _) n/ R
+ d8 q3 d/ y: D9 ~2 e3 L8 ~" q s$ `# t. p# Q6 Y
}* m/ V+ g. h' D! E4 {
' o( f2 _' x, r6 s% X: O3 Z
4 `' x5 R. ?( Z% `5 }/ D; f
) |2 A& U) l% n. [) m. V. c) W}" e8 q$ @9 }- x3 u
, u/ E2 e v3 f// ----------------------------------------------------------------------
/ r3 Q5 j% n$ G2 u; n( n7 m! p( }// 使用Npoi读一个简单的xls文件
" u- {6 P/ t4 H( h. u, N0 O7 e: a) X6 H( V
using System;# E0 J6 X5 t' s8 C1 P) |
using System.Collections.Generic;0 V0 l5 E1 f$ W( ~( V
using System.Linq;
9 S. A j% u+ A) M7 vusing System.Text;$ `0 L6 R6 U0 v3 Z2 V
using NPOI.SS.UserModel;3 C# _% D2 s. U
using NPOI.XSSF.UserModel;- v w. D) p, Z/ L6 n# p; O
using NPOI.HSSF.UserModel;
$ S/ d% n2 ~. W( Gusing System.IO;
; Q, n. G; t) X/ Y, X, Cusing System.Data;; i5 d. F ^. h; B! i
2 c& A/ D q& p# z3 L4 l. J
namespace CC
3 o. o _/ K- |3 M$ h5 }{
; a) d4 x0 a4 l7 c4 Q$ ?8 y# G& B# l# H/ D/ O; A* I/ G3 z V* `. Y R
class Program
. c& o% h$ D4 T( P- p9 F3 x {. R7 G& b U C e! \+ i
% k1 z' U) W% C; f, ^7 h2 z- Y
7 Q# w6 F, K" x. {, }
static void Main(string[] args)
1 }4 V% l! P+ a7 f9 G. t! M {" b \' @: K5 t, X; y
StringBuilder sbr = new StringBuilder();
: P! `) l9 P+ o/ q9 O3 i using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
7 J8 d3 i U3 v {
1 e) k$ U6 D1 A7 S2 X HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
# q( b3 o3 G" D {" f& T; l for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数5 J: M" R% p) p9 _/ }2 J+ h
{8 R E2 M' U0 B) I; n
ISheet sheet = wk.GetSheetAt(i); //读取当前表数据) Q5 ~; K6 W+ I3 Z5 g( U
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
; }4 [3 W( |/ J+ Y3 A# }4 z {9 }& _/ \3 a9 J6 v0 S
IRow row = sheet.GetRow(j); //读取当前行数据! C6 y' `' k/ ^; J/ x
if (row != null)
$ p. ]7 Y; {+ C- S& x+ s1 V {, |' C" {* z0 x7 x; M
sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
( \% E0 [# s ?# Z+ m! s( | for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
% W" @5 |4 X0 v0 h* Q6 V z {
, Z7 E) b. o$ ? ICell cell = row.GetCell(k); //当前表格
( a4 f7 x3 ~* u. \' | if (cell != null)& Q* q/ K/ l! I! J4 N9 V
{
5 a' m" z" ?& c" w sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型( T' A' A; X) [; h/ M
}
4 B( g3 N5 b# m- q; Z: k# L }! R7 Z7 G" i0 o- r6 e6 @4 \6 m
}' D" g; y9 z$ o
}! m3 o8 q0 o) d& U7 O; P# {
}' }9 k% v# T( p! W! v. a
}
$ _3 ~/ @- Y* Z0 @ sbr.ToString();
b" e8 Y1 v( J8 f1 Z using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
& d" m& E1 Q8 _# ] {% X5 ~% M8 |: t4 C
wr.Write(sbr.ToString());
/ I) T+ N4 b& C0 t. ^& `' ?& _- A7 W wr.Flush();3 L" I8 R/ ]' L+ f+ t/ G
}. _. o( I. ~3 @* c8 S" t
2 T( @* {5 k$ l3 a* {9 j
5 r1 J+ H. ?4 Y% E }
8 u5 J9 O9 m, }2 e& d/ S$ g
) o% I0 h3 ?4 }. V
9 w6 n' C6 W4 }/ j3 h ^. P3 q }0 k( H! j1 w# [
& r% C C/ d1 x! V. a$ Z
6 r% j3 C% M4 O z% i4 x; E1 n: ?% i5 L& a( j: o( ]0 g) M
}- x. `- ?7 ^2 v# Q! R5 W) l, t
1 O7 W0 y, a1 o1 `6 ~8 ]+ q% a
9 W, h' s; \0 k3 o' T( J5 I然后 自己封装 给 c++用
0 P* w) C8 [1 i3 @. z# c* i
: J0 h4 K+ u1 X- G
4 R4 B% c; n0 D/ ^
0 v" p7 Q: ~ X3 p& ]1 m m, H: Q* |1 U6 a' a! N! B
' W& }( [) j1 B4 L6 J5 i5 M. c
3 {1 y8 }1 u9 p5 o) j7 Z4 o
- @8 R4 r( O5 t6 f- s) Y
4 c1 u% I! b2 P, K7 `( a# Z* |6 Z G; t1 f9 ^5 U2 @9 v
O/ E! C& A- H. l& H& E7 P& v1 \2 l' ]0 i0 W$ O8 f
" [ J( X |$ G# o1 {6 C' D
& a/ R7 H5 [. b P! J
/ E' Y5 g8 u5 _) }' t [! E
9 r& U- @. h3 }" H3 n: L5 z
. E6 L% B' ^& n' S. ^* O
5 E2 ?0 o8 Q! O% N
9 n6 p" j3 J( B) Z; p" ~# t. P
+ G& z7 l* z0 W1 N4 D/ @; F0 k- P! r- H& D- i7 \; p9 D) e
9 X# G! E5 P1 q9 F4 C
0 m& z/ x8 B# i( l6 u# `& P) Z) I* K# i
|
|