|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
$ o1 z* i4 J* s8 u6 ynet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)
, B4 y& F' u, y# s6 a这里我用c# 生成 com 组件 让 c++ 调
# g/ ?" u( F R( M" |# E! u; D7 |& b/ ^5 \/ C* I, R$ r
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)
9 |, Z# a8 `6 C8 }) J6 \C++调用C#的COM组件(DLL): b2 b4 d4 X$ b! C P
. Y$ A% S3 J# x
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.3 K( E5 P0 _* Q5 m/ {. ^# ~
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.7 p! z0 H; {4 E: t% w' I$ x2 i/ G3 c
/ E- J% O& c! w( w' n8 U2 F( q0 u' T) A' h; X
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom9 F3 E! C/ ~' b5 H/ t% m
+ G9 ~) L2 n5 @4 L& @! j
2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
) `: S D) X! F6 R0 x0 h6 G. {: ~8 w1 n& m) _+ x& i: N' c2 P
具体代码:
4 t! j* U4 E$ L6 A. d/ W8 e- V, L6 q% v7 Q3 ?4 a: D+ o
using System.Runtime.InteropServices; //记得加这个命名空间4 @& A i% n9 T( h1 v! L- W
# r. Q0 V0 c! s1 N* ]3 K, b: }# j
namespace MEI_AddCom, w8 _$ e) u9 z4 G
9 V$ c- v1 B, m$ }! N
{# z3 b, g$ @( ]# K! \
v5 F) M) O. V& Y! U0 s% }
[Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.
2 m8 Z3 Q9 d2 F/ ]! ]3 ?4 o1 T. q x: y
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
& E- e+ K) p3 i8 h+ }
$ w9 ~/ V8 a M& _. `( A/ O$ q [ComVisible(true)]3 c! ^5 k, ]) ?3 _; F
8 n6 k" X7 n/ m; ~8 b. u3 L public interface MEI_COM //记得用修饰符public
6 {9 A% i4 i3 f2 \/ T( [& G% E% ]: ^0 l0 w5 E
{
/ y0 ^8 e1 q/ E$ h/ \
2 D6 e; q. l3 w3 U _ [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面5 z; v. }+ G: H
' i6 }4 G8 N. m8 w' |
int Plus(int one, int two);
( W; b; |' f+ E& W! C. ~. g0 i0 o# i- L4 f. o
}
+ ?* F J: W' p6 e( F" Z' Z9 M( p. \/ L: S0 V
}) o3 W1 M& h: [9 X4 o
& W. }5 b0 S- A# c: Y- W# e3 e& x6 ]0 P! u
9 t3 n+ S: |/ T0 K2 @. T9 T
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码1 I8 n9 P2 v& d5 @) D- Q, `
+ F0 Y3 Y, |& G8 y O
using System.Runtime.InteropServices;5 X0 y& b3 E1 t" I9 u
, t$ Y3 J; A# P( w& a: o5 o' V
namespace MEI_AddCom5 F6 R2 N, e P. c% R0 o( |* v" ?
9 A* t G; s) w+ f8 O7 W- f# @
{, L2 J. _* u, D
4 v! L$ b5 E" y- M9 C3 R" T! y8 x
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]3 J% K6 f* D# l4 L
# a) s3 j" g$ f4 X( U! J, r [ClassInterface(ClassInterfaceType.None)]
' A* z' U2 k. V" ]1 w8 n
8 w7 S7 w) y7 S* U public class MEI_COM_T : MEI_COM
# }4 a" i2 A6 T3 D3 ~( h
; ^& w1 S' b9 r1 ~5 P {0 r9 y4 E, h9 I+ H: W o4 r
$ j& |2 v5 f% j# u2 g# t public int Plus(int a, int b)9 a% u( |9 y3 A% G0 _0 C
! _' v, D7 A% h {- G3 N+ G- T- }4 _# K& D8 m
( a; A, B8 i- P1 i Q6 T6 J
return a + b ;' R9 E' ^# `. u6 D% i! z
# E1 O0 x3 G* x# j! l3 @ }' {0 I3 I" `% W: a6 `$ v8 L
+ O K7 O: l) v2 T) H7 w
}; |2 q0 U+ x9 e, f
! R( n: i8 Q* _$ k) q3 d$ K3 q0 C, k}
4 G& K. p- [- I" _ `/ i* K
# ]$ U: E5 M5 K2 w* m2 ? W/ \' f8 n; ^$ K
( v; g" z7 q3 |8 E; j. }' S- e
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)]., g0 E1 P! Y. ~$ J+ n6 b5 ?
& ^& i; o5 x. A7 n* }! T
右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册
5 Z* b7 u6 Q3 m5 M1 k# w) B; \
( A2 D* Q/ }5 t; [; @$ j4 I/ a3 E& a) Y
5. 生成->生成解决方案" c# I6 I2 D2 X; p
注意 这个时候 生成 非常缓慢 & l& J3 x+ L4 F" k7 k" m' K8 g2 H
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
9 }$ ^0 k1 T& d6 C5 B5 x2 ?+ f# \7 u* K) B4 r, j# i
, }+ A- |0 a8 H% C' i' S& e
---------------------------: m/ O" m3 v: V: {) o' p
# p8 `5 O+ `& Q! w9 v% \
1.调用前要先把com组件注册才行.
7 ~8 D( q. v" _" b: F* M' ]+ W0 \+ n
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
/ |9 q! Q' Z( r3 Z! Z, K2 W1 |以下说明如何通过C# 注册、注销COM组件。 ! p- S, W* ^, j8 W }1 Z4 k
' k- `7 k' y& ?. A为了能让生成的DLL能够进行COM注册,需要进行强名称签名
, C0 ], i4 _8 X) P4 Q- e5 u- D打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。0 d' V6 S/ y" s6 z
创建完成后COMLib项目中将出现后缀为.snk的签名文件。
* ]* Z5 B7 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文件。
4 ]% @' s, v" v' i* s( P卸载COM组件:
: y6 S' E d- `与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
2 r+ k" y+ A0 P+ v* g5 |
c( h1 n. z \2 B g1 ?6 k) Q( X" g( w8 \5 S
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
4 Z7 e7 a* Q& @' r; h) C' g+ k: J, \- |9 @4 A
名字取MEI_UseCsharpCom,点完成) J, a6 m- z4 }
" U" W ~% C1 ~# M! a0 q9 q0 ^. S把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.8 |7 f2 p+ u( s
: i, [9 F' s# j我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
; O- \: c& n& R) j7 P
/ G6 w; W# v8 Q0 y# p9 R1 r: Z& C. D) |
#include "stdafx.h"
$ }( @/ N" F2 T* n' F3 F#include <windows.h>. L. H+ h! ]; X7 [
#include <string.h>
, L! x" C* T; q
1 s7 v. J4 \8 F5 _9 Z0 J#import "MEI_AddCom.tlb" named_guids raw_interfaces_only, n, ], {' [: d
4 x" x- t- Z, X. u: g6 @& ychar* WcharToChar(const wchar_t* wp) //wchar_t转char*
6 t& K% }& m* }6 N2 k0 r# V6 A! |{ 0 Z5 X( g1 B9 U# U2 e6 Y8 B
char *m_char;+ T9 l0 I) N; A3 m8 ], X4 B; \/ w3 C
int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
- D3 }7 o. F" W& f, k" n' z m_char=new char[len+1]; 4 Y; x/ h9 ]1 ^4 y: j9 a" [
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
1 Q! K9 \$ U% Z3 G m_char[len]='\0'; $ m4 Y1 x. A. G; _1 `/ J, _
return m_char; 4 h4 |0 o0 V" Q4 z
} . K2 q& q, w! H" _$ C3 V* x1 ~* a6 L
wchar_t* CharToWchar(const char* c) //char*转wchar_t5 [9 G8 J0 }* R8 f
{
0 ?1 N @; N* F8 Z: E# p wchar_t *m_wchar;
8 p/ H( h( t- w/ ~ int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0);
8 }: R5 Y7 r; r. K m_wchar=new wchar_t[len+1];
" Q8 l3 y% E# r! h- b2 Z MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); . q7 Y$ _/ `2 d- _ n3 {# L
m_wchar[len]='\0'; + l" W& o9 m* O5 H. O
return m_wchar; $ d6 J& _. V, X: ?2 U
} $ D$ E4 ?; x5 Y0 o0 d+ o2 N
6 Z7 c) ]- g; I& E6 ?
void _tmain(int argc, _TCHAR* argv[])
m% H5 Z: \+ ]6 y" p, v+ q2 v- b7 N+ g' |
{
7 V3 X$ L0 E# s9 z! u5 r# a) D& q8 n0 T2 D/ I( I$ C% U- z
CoInitialize(NULL);
$ w5 a1 G2 F, P' d
% G0 [3 q! P# p7 i6 ]9 _ MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针 Z' h. \& a/ }# y; k
2 o4 R3 n# g3 l9 V" a+ `! ]2 s9 e
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名; I+ }' g2 u; _) d4 r! w; I& U) ?$ n1 P
! ~+ B- Z/ x" k6 F. [* \8 M //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
' [& Q2 P( o9 S/ d4 {4 r8 M2 P( p$ d0 W C! K; T3 r/ y
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
X1 [; u, L% a# `4 h //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
1 b! n f) t! ~5 H
2 \5 a! m$ M% j0 E& i& c) z long a = 1;5 ~2 n% h# i3 r- L) M0 N8 k
# X n+ e: J- D6 v* v long * lPtr = &a;
$ h0 E8 c4 l, C2 g; |! N- m
9 w& i/ N# n) J* D! z8 {6 } ptr->Plus(1,2,lPtr);, Q C7 S0 ^( T2 ^1 x% P" N) U
9 K! C- c7 ?- Z2 v char msg[132]="";. F9 p- @! d- ^9 v4 [' r6 Q* H- v
sprintf(msg, "%d",lPtr[0]);2 a5 F# E! h9 v# s# N
: u p5 n: n. L4 ?) V2 ^+ I) | LPCWSTR str=CharToWchar(msg);2 C1 k2 {6 o4 _/ t" e
* ]3 I- [8 {0 g+ g2 M6 A1 r
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);* |$ _9 e2 E. X7 _
; E# \- ]4 Q s# t: \) O6 L. q- I
7 a y5 J3 {+ ^9 u9 Y3 X}# l1 r9 h2 `' ^# T2 g
4 J; C8 t& a' ^. c6 f# l% C% i此时就可以正确运行了.得到结果32 g, C# Y# Q0 M2 K
. H5 K0 k) _: ~ d4 G$ Q如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
" K4 J3 Z: G6 t2 f6 u# J
4 }" Z2 X' v4 k" b' `9 M s# M$ h& J$ O+ f: P* h V) _: C: u H0 V; U
--------------------------------------------------------------! n) p, f7 o, [
C# Npoi库 操作excel 的代码网上很多
6 z4 b# g6 g$ X( i. M& p& J" L
: j/ x7 N3 f+ U3 x9 H3 I' a; q0 v// ----------------------------------------------------------------------% f8 m* s7 ]6 S6 B! G+ V. \! t4 _
// 使用Npoi创建一个简单的xls文件,写内容
+ u+ G/ w* S6 H0 R/ e. _- E: M
( h: q; s% f2 A) z Musing System;
& W, I+ l6 x+ k% N2 ~using System.Collections.Generic;
6 ^9 H# t3 ^) `0 Jusing System.Linq;
; W# u, \1 P3 ousing System.Text;
/ n* a4 D3 T$ [using NPOI.SS.UserModel; c- o7 a5 W9 o2 z
using NPOI.XSSF.UserModel;
" |$ S9 c g* iusing NPOI.HSSF.UserModel;
- y2 I6 l1 N6 Q2 musing System.IO;
/ ^: D+ v* Y4 x7 Z- X7 c& }( y) Busing System.Data;9 `- Y, G; ?0 C4 M. J; l/ X
; U5 A3 i) U, R//using System.Windows.Forms; ) V3 h2 `7 _# u" z3 [9 V3 S
' u+ h. o: m! Knamespace CC
4 X! e. O: t4 T3 ~* o+ R# ^{! T7 n; Y4 H5 s
3 o$ _$ j0 }$ A* [2 z
class Program
R8 k, b ^0 A" [& k7 K& T {0 i6 _0 w- x" J$ {& a5 ?4 w# E$ K
5 v% z/ o# F$ j- I
" m9 k% Y R& n. U0 w static void Main(string[] args)5 R. H( b: j9 H0 \) E$ p- K6 I
{
6 \5 l9 A' O% H9 H- ? //创建工作薄" M1 S2 H/ j3 B3 O* R: W; T: o) _
HSSFWorkbook wk = new HSSFWorkbook();
9 s) j- n' n$ E$ \' I5 T //创建一个名称为mySheet的表- u) L C' r- u8 G$ a9 I( |
ISheet tb = wk.CreateSheet("mySheet");4 R1 V+ i3 \9 N& N; h( l, J1 e
//创建一行,此行为第二行
4 Y- ^" N$ S5 S1 M4 Z. j% f IRow row = tb.CreateRow(1);
9 F* G& e) Q7 G9 w% _0 X for (int i = 0; i < 20; i++); f* C1 t5 w# x4 d8 z
{
4 r* D! S2 P0 X. j ICell cell = row.CreateCell(i); //在第二行中创建单元格
- O2 r, W. ^- D* d cell.SetCellValue(i);//循环往第二行的单元格中添加数据
* |% p# K9 ^' s% r$ X }
2 X% w2 I6 K( J0 j# e/ H t using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!- |+ w1 _: P! I7 I# u# f
{( V: ^7 W1 U5 \* z) m/ P- `. L
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
& e& Q4 v7 k7 L // MessageBox.Show("提示:创建成功!");
+ u5 y9 C; Y9 u/ v5 c, w }' O: i3 |6 ~7 g/ v+ s
! e Y* U( q2 H6 P7 ` }
+ }) z/ p: I4 |& _8 i, A( z! N3 o, h2 T& e& }* q% }
* \# N" r% l4 l3 L }3 B" e) D+ h# r
+ G. g6 W9 B( l1 n5 ]% w! ]
! M4 o2 n2 G# B! t1 P- I3 F2 m9 ]$ [
: c2 e% j+ s9 m. V& l$ G}
0 ~& I d- ?: j( W! D* l" Y( e- s4 [ c) T& G
// ----------------------------------------------------------------------' l, e6 O- M( ]9 p0 t1 p9 N$ {
// 使用Npoi读一个简单的xls文件
2 z9 H+ |( n3 u- m7 ?. q! S
. r, X' G+ B( D1 V- Nusing System;
! s* f Q9 a$ j$ jusing System.Collections.Generic;& j' E5 ]& N: V) \& f
using System.Linq;" w* P; @' l" c2 a
using System.Text;
% q; o- L% p! X! c- S+ tusing NPOI.SS.UserModel;
- V6 B1 V8 N) q6 n) }using NPOI.XSSF.UserModel;& ^% E5 z: m3 b, m9 ]& E; s
using NPOI.HSSF.UserModel;5 n5 U& a; q1 ^9 J6 x
using System.IO;
8 P0 l! p9 |, Wusing System.Data; E# y# E4 s4 _: S) l* [5 v
" @3 a. E `. @1 z* p8 ]
namespace CC0 Q" o$ F% ~ H
{
0 q: C O2 W- G. x/ D! V+ u! t T7 p0 T; V( a4 B
class Program
1 O" A5 e& c# p) H {
! _2 x0 h' b, q" o+ u% a1 O
a$ @' v7 v$ J3 q- H f* b: R! k! i8 i2 Z' L
static void Main(string[] args)6 Z( b* J3 X. f$ q% C4 W7 _5 F
{
* n! E% N; c# ^( O StringBuilder sbr = new StringBuilder();2 c, _9 y4 D( i9 Q, t9 Y0 v2 U
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件4 D8 } s6 s$ k9 q3 d6 ?
{4 q9 @, ^/ K1 r" g# S
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
+ }3 [& E3 s% h$ ]4 B8 z, L4 {% K1 m2 j for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数2 O/ s% i6 O5 h8 \/ V, {# Q( o
{
/ c* K# b/ ?( U3 }( d ISheet sheet = wk.GetSheetAt(i); //读取当前表数据; H6 j# t& Y9 Q+ R$ m* _
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
' J% e: E$ T0 P, e" S {. Y' l% P7 Q2 v# E/ U4 B
IRow row = sheet.GetRow(j); //读取当前行数据, ?0 v. B# P, b
if (row != null)7 w6 Y7 m5 o7 C; T! _
{% e9 A% G0 H$ w0 j
sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限% X N: x2 t9 K# K& h3 @7 _5 a
for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数% F4 n( ?% X+ L% q* C* K) j
{2 p4 K1 z! M2 N0 a; n" ~
ICell cell = row.GetCell(k); //当前表格4 v2 Q' |& K# o2 x2 w
if (cell != null)
& E3 u4 _9 `3 O+ g; k, @6 Q& _ {
# f8 w) @7 n4 B$ k- B# `1 d sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型
: U: ]- u& J( f- }7 I* U3 h5 M }9 H1 L: W8 K. U1 y' R4 c
}
! I* j7 ^5 g. O }
^$ h) R. Q8 }0 U. O0 e0 U }0 q9 X, J6 E9 j$ X% G5 J* J* l5 C
}( G8 I1 P' N4 K
}
1 U7 |1 ^2 B4 L+ J+ A' u sbr.ToString();1 n+ w+ u1 c* Z
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
# p* r* M& s9 J- Q {" N6 H+ R/ q/ B- v `5 k
wr.Write(sbr.ToString());. W- M8 \ a6 ^+ m- o( S# q1 t# V
wr.Flush();: _1 w! f' q1 J
}- W! i9 b9 X5 ^. O4 z/ q7 D, `7 M# V
+ A7 V @0 U9 Q
" [/ Q: M/ A6 C. h }
& y) v3 h9 V% q
^ V& a# Y, U" Z; X$ s) p- F, {3 f# m. _
}
3 E. H9 {: D7 A7 g+ j0 F# i c
. Z$ ]- T% R+ ?; B$ t! E: e' D A2 J# ^/ n* G+ [1 E
8 ]! w2 \& s* [( X6 H
} L7 N S% A( s* V+ c2 _
& T7 Q% K) W" |! G M8 u: w" b
( j# @" m9 C/ J然后 自己封装 给 c++用- @) B5 w4 c: a4 h2 T
! i( _1 A. B1 w* v
. E5 A* I8 q' x! u% C
; g ~6 \0 i& K1 k+ m, X$ g1 m% D' j9 w! H+ i
: [3 P4 L0 Y# F% Z4 _1 U% ~1 E
2 V! H5 @! E7 C6 R& ]
; W1 Q# D8 P7 b. N: o* b- X9 i% X5 y3 V9 t, U5 i6 ^ @
. w! D+ ?7 I; K8 ^/ o& m7 Y7 J) }
6 E. ?1 L& {* k9 `% G2 j6 e% Z
& e1 X# S! H; P1 W
9 [: B4 D5 K5 z, K
! `; C I" i$ o; ^# R
# C: b2 p$ u- r) y/ U; Q" Y# A4 c: b' V9 ?6 M" @
8 S/ p# F4 F3 ^' ^1 w! }9 P
- K% E; s( y( R: D9 a! D; t" n
9 s: p& i3 m4 f
( W9 p7 M' ~4 `: k- B2 f+ f/ c3 ~0 Q5 W( S& L/ e. e) }. d4 Y
9 w) ^* j$ |* ~4 o# x
[+ ]+ D4 \6 F+ f( }! g
4 t4 Q, y9 |# M# N |
|