|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
& r) ]) J2 H, H2 T+ T/ i. {net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)5 h% d3 w$ \) y6 Y2 G) N* l$ E
这里我用c# 生成 com 组件 让 c++ 调
; A" y. I4 a2 ]. c# r- g$ @3 M% ?( B9 _! m8 p3 N
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)
5 x& I& k$ Y [+ C9 z2 `C++调用C#的COM组件(DLL)
: N7 b% k$ q! L0 }
J7 G, M Y6 s" V0 j: q" o5 x" G下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.3 U B3 A, Z# m& u2 `
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
* B# H. f" Y. T, Y& A6 ?/ t$ J! v
& J( Z' U% Z$ I4 x- j$ t6 k6 Q* G
+ D: {/ z! Z7 ^ r9 o1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom5 o! T# @' k! l& U' [' l# d0 b$ D0 u
/ z, C8 ~( R$ v2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数, ?) l) [9 }! b* y# D9 J3 o
4 o! P& {$ f9 O* e具体代码:8 H# c* z5 t" o6 P" w
7 S; f2 C! H# F' M
using System.Runtime.InteropServices; //记得加这个命名空间
7 G9 P* k" z2 b$ b( ~6 K7 ?
/ ?+ J, Y1 x2 d3 ^0 T! H5 }2 dnamespace MEI_AddCom
; R( D- ]3 ]4 e* \) `; o" |) X
0 Z, {: n4 Y5 |' N{3 M- j% _# ^1 _) \) ~
4 b7 G8 x n( B. y0 { [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.$ a' ?+ d' w$ Y3 B/ M8 ~7 f
. G! F$ E4 ~' J6 y9 g5 l1 S) Z //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
, B# @! ?6 \) a _- ~3 {0 m3 C* H1 ^( S( b8 }# q8 [: L8 D1 P
[ComVisible(true)]
0 \9 j( s# l! R9 B) ~0 c
3 `" m' h! z f" U" L public interface MEI_COM //记得用修饰符public3 z7 |0 b3 ~4 K+ _6 u! k) l1 Z
5 L, [% {2 J! w4 Z; c2 t# r {! R0 X$ ?& c; J6 L. ^ r6 g0 G; ^# J0 f
$ o% @3 _! A) p0 K: H0 q/ f
[DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面" m" m% s' p* c, @* X
) H; {% u+ V; H1 Y
int Plus(int one, int two);9 n; I7 z, p" u$ Y
+ D3 o8 ]8 F$ h; ? }
, D$ O* [) x: d: _1 ]5 \, b! q" _6 [& K* c* ^' \) ~" n) _0 A7 P
}. A1 M! i5 b7 D* B, ^" H7 n: m# H
/ J" d1 a! o) Q2 ~1 R
8 U& C1 I! D, s
1 `& r2 @: `" Q3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码* G. S6 K& ?0 H4 P
7 u5 ]- [1 [4 z! L5 pusing System.Runtime.InteropServices;0 q d0 b/ r* M( A" f0 }
& z% m2 n8 G( D0 Z- x5 q: gnamespace MEI_AddCom: `! \. }7 D4 r2 X/ K) o
+ E3 g* v { V1 O5 H
{* C" i7 x& `. Y( @: I# d( }. ]& n
3 ~4 d( a+ N" U: s' ^4 {" K/ B/ h1 k
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]
4 l( I7 S- j0 P8 z- d% d9 P+ ]7 r2 N1 u X- k
[ClassInterface(ClassInterfaceType.None)]
( u9 W( N5 y8 M# y
! J4 f. q! `3 [ public class MEI_COM_T : MEI_COM- ^" c: b. G) z2 h! r
( W: }- L7 R7 v& l1 w {) f8 \5 b7 V/ Z' A8 D
4 Z& ]) t; t' n
public int Plus(int a, int b)
Y9 {- C5 K" }$ Z3 i4 B+ w g- |4 T
{
( l6 o5 u! S* B! K% C+ i6 C& W! A4 l. z+ U
return a + b ;
+ H+ C0 k' D- u! V4 V7 J3 i
" o6 f, P) Y( ^' F7 v' M }
7 w7 `+ t. Z ^. i) y9 p- s: U: E. x) Y0 B4 j, }
}. y2 o8 n( r! W( F: d
6 N* b# Z" E8 ?+ t. d$ \ {1 [' h}
1 b% |2 P" ^2 t) y0 z2 ]/ i/ E! M7 I7 x& o4 D
/ a" O- d- K6 S' \* V8 x% T% P# e
$ g4 a1 f$ _; g& x
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].. ?6 I% W$ Q6 X
R7 z# w6 [" x右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册0 E' B$ }2 h" e: l" C9 _$ L
: u/ Y% [# t' j. Y2 z
( e5 U0 @; y* i6 D" _( C3 s$ r
5. 生成->生成解决方案3 \: n6 g. s3 v! O; i ^
注意 这个时候 生成 非常缓慢 + C ]( m5 O8 A1 v0 G
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
9 |/ T! E9 f% Q: |
- p4 Z( p4 }6 M$ P3 o5 @" ~
% ]" O! v" Y) v5 w---------------------------
8 |2 v, g3 O# p( c$ a: O) [
" R$ V0 Y# w6 Z1.调用前要先把com组件注册才行.
) T( V! d* U) P5 k6 r& `. e1 X. `- O& W2 I m
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。) Z7 e. S' \& w# P- ^9 M' R
以下说明如何通过C# 注册、注销COM组件。
) _- z1 |% t9 N* k. L0 i& R
! X: p. K6 a8 {) F0 f, [( j' [为了能让生成的DLL能够进行COM注册,需要进行强名称签名
% P6 C6 b2 G, D2 }打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。$ b [( }9 j: ^- \. E
创建完成后COMLib项目中将出现后缀为.snk的签名文件。! g2 o. w- x8 Q& m1 V; A9 r
最后,编译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文件。
1 a/ x3 _$ F' g+ F$ O. G* S卸载COM组件:
0 m* e( D9 X, n2 s1 y/ C与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
5 x8 X' ?* G' z) O* P2 n
& z; t7 y. C3 b) n
~# ]! T) u) P$ j2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序" a& }4 L3 p, c* Z8 S' u
' _6 S. n L9 _0 h名字取MEI_UseCsharpCom,点完成
u& Y, @8 ~: j: A; R1 @9 O- J
/ P2 t' E& n% s! r6 }* n5 {2 W; M1 m2 t把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.: l% r( M2 X" C4 r9 N: b, u
5 k) P! b* j" z4 S3 R0 y我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:, B- w. J+ M- N y
; o; d ]4 ^4 r4 x) ~! Z. e
0 m" y, ]/ h( X4 V+ k8 y$ a#include "stdafx.h"' G4 C v: e* R+ ?! ?. I
#include <windows.h>
- o; M1 H- V# j- h: c#include <string.h>
) N5 S \3 c, `6 D8 \: O8 I, y% b3 l9 a2 g
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
1 C0 N- c5 L/ V% M9 z5 C. j9 ~9 v3 v+ m7 _* X/ {0 R
char* WcharToChar(const wchar_t* wp) //wchar_t转char*
/ p _/ v- D8 N6 [& ^5 y{
2 V0 H0 d2 o5 A: {% r char *m_char;
5 G" U% m& U9 `8 q int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
' C/ t/ J7 h0 Q+ E, u( y' y. e8 E m_char=new char[len+1]; & j: t0 W A8 M. M+ S* ]8 U
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
9 [- [' z! {$ O8 c- y2 ~ m_char[len]='\0';
; _! h1 o- g* h6 X: e return m_char;
3 p9 m% n- Q$ @- D: S}
' |. c3 g( _* \* D) B" O( r0 Wwchar_t* CharToWchar(const char* c) //char*转wchar_t
- I2 @* G- H A2 y{
. U# F5 t/ G2 |* @& p) S4 c wchar_t *m_wchar;/ w5 L$ o% X. S F, p* w- L7 ^
int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); 9 {6 H \! V v7 N# x: K8 @. A
m_wchar=new wchar_t[len+1];
1 G4 t; v @! S' |' p2 M( E/ ` MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len);
a3 ]7 S, c7 s b- v: Z& \ m_wchar[len]='\0'; + c. }( }' ^( L% j6 y. Q
return m_wchar;
6 W1 j5 h9 a7 q2 M& g& o}
8 U& ]# r5 b9 h" F
( z( `' n$ E3 C: `void _tmain(int argc, _TCHAR* argv[])
, t, L9 f7 |5 K+ `" ^
6 U5 g) c7 a1 @5 X9 m1 t p) d2 _{+ T: j" _# E0 G8 t9 [
: n6 s8 p0 E+ b) D
CoInitialize(NULL);# J. G2 [) L; {6 [8 j' r7 N e
* c8 q7 Z, ?, d* H; R6 R" {1 ]* K
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
& ]9 W% V" e0 H' H! ]9 ]! P6 o' ~7 `
' b. I: Z5 ^6 y% J! H* G ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名6 }1 H3 E8 P, b6 u1 L: A
, f1 \- f* j k; @# ~- `- G
//这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接6 e& c' s4 A; i/ k
* `8 P- ~" p9 P //来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.4 L; c& ?' E7 f1 S L4 d {4 Q
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
; a& O. l3 Y$ L2 H }( I( Y) _7 E9 A7 S; e4 t
long a = 1;
! Q+ H0 I# J5 s0 Z: L5 g' O/ m3 y! x- q8 d; H- f: o5 \
long * lPtr = &a;7 H- P H! ~% o6 N. T9 e$ J
: [. N: e& J$ r2 V# W& f+ N ptr->Plus(1,2,lPtr);1 j* Z, S; z* L2 p' z( W: n
1 S: F) S p4 _/ ]" B' D' m: d
char msg[132]="";
p( R% ^6 d6 t# {4 U+ ^) e sprintf(msg, "%d",lPtr[0]);4 F, ~, h! K% V% ] v$ t
+ E) H3 J! C; o6 t. T9 x- b' r2 D LPCWSTR str=CharToWchar(msg);& `2 f0 y! Q; a
* \. p* G, M3 M* d' }# B- S9 Y MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
1 W$ q+ `/ B5 e) k/ h: a+ |7 V4 N- S# p) b) g$ m* P: g
* W; L( N& I& `* J L" O9 x3 z
}
4 U1 ?7 ^; L3 d# X
6 A! i1 A- j d# D2 K0 h9 l此时就可以正确运行了.得到结果3
/ E- h+ X. \2 q+ K l9 j4 J0 f
: M2 E1 O* q& W% N" o; s# h如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.: F! m* l) ~+ w, D7 X" T r
, x! I6 \' Q* }; i0 `
x/ i0 W; }! R1 I
--------------------------------------------------------------
9 \) ] |' y/ F. U" wC# Npoi库 操作excel 的代码网上很多: z9 z5 F, i6 L: h' X0 q( A0 \
8 e' I% A4 C) W/ K5 {& W$ s4 ^, q// ----------------------------------------------------------------------2 Z4 I \2 m m
// 使用Npoi创建一个简单的xls文件,写内容9 I( l8 [, l) T
) q7 a4 s% e' w! zusing System;
# N! Q1 ~$ g6 iusing System.Collections.Generic;6 L9 X$ o( t6 q D
using System.Linq;$ R6 `4 ~/ V0 J) q* F9 \% }. R5 P
using System.Text;
1 O* j# L2 H& l8 C5 o: `using NPOI.SS.UserModel;
+ D* l6 Q+ D1 y5 M0 ?% z/ A# m/ cusing NPOI.XSSF.UserModel;/ ]" e- O4 P& G4 R w
using NPOI.HSSF.UserModel;
0 n$ [0 c6 N0 k% q( Z, Vusing System.IO;4 k }9 i, b, c1 W, W" I
using System.Data;2 Q/ X0 U4 \" L* ?+ H3 R
& `; h9 a7 q. C# H5 D* M- T' R0 ~* q
//using System.Windows.Forms;
9 X. u' b3 p" X, B5 Z- o& J8 }6 _" b x
namespace CC
' Y# h8 H* I# F) M: \{
2 r7 N' o6 H$ i+ \+ k' a3 \7 B" Z) V) q s: J4 w7 r
class Program: ~- {# v. o6 N( ^
{' c& Z/ p: Q& K9 T
# C2 g0 S( X+ M- G' n7 X& c6 r s
3 N+ ?! u4 j1 A# S) I( A9 V& I1 x1 o static void Main(string[] args)' U8 [; H( y5 r6 N: F- h* ]9 E
{
& r' e: q. P+ G //创建工作薄
( O7 S9 ^) K# i# y, E4 K8 S1 } HSSFWorkbook wk = new HSSFWorkbook();5 U- | [# \# |
//创建一个名称为mySheet的表
" O9 ?4 ~1 G) @) U8 n+ Y ISheet tb = wk.CreateSheet("mySheet");
0 t, M+ ^7 v8 j& s; z8 w+ Z //创建一行,此行为第二行3 }2 w1 `& J* V0 x( B( c3 ]% u
IRow row = tb.CreateRow(1);0 z% \# y+ @- E6 V0 u- |2 B
for (int i = 0; i < 20; i++)
5 L* r5 i0 w! r& | {
! Y8 X1 A" ], I. B& q" p4 `! K ICell cell = row.CreateCell(i); //在第二行中创建单元格. X Q4 j, Z; Z! w
cell.SetCellValue(i);//循环往第二行的单元格中添加数据
# @# p4 b6 R" n; g1 { }
$ e" A5 S% t1 O5 d using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
+ |8 ^9 o) h! Q; @ {
$ T, K% A. D: W wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
8 b! ] B0 B- }# Z/ ? // MessageBox.Show("提示:创建成功!");
$ F1 ^3 M2 Q4 W6 m# K }
* m; l8 M& u4 k+ y" b) g1 \% Z1 f, Z
}
6 t% \% k/ C) K! u. ?
+ W3 B y) r8 o. t+ U( b0 H; H9 x( L2 u8 C
}
+ H# X: t. s- [1 _$ @ J- P' E' T& m1 R% B6 Y6 f( Z' C+ B1 y
* a q& B, O2 W/ J) l
1 A7 _/ d9 ]7 X$ _# S% w}
* _# V; Y& w; L8 [- ?! x; b8 r# Q" q8 ]" \! Z8 p3 K
// ----------------------------------------------------------------------! l9 [; d. U3 e, P8 Z( Q7 ^5 l3 Z; r
// 使用Npoi读一个简单的xls文件
& a( Y7 n' x% C1 d5 N/ [3 P. k( u+ J* ]- u V
using System;
1 |/ o m! L0 \/ {* K: `% Xusing System.Collections.Generic;
" i0 A' G4 _' C' Busing System.Linq;4 B& B, U, H0 _* s0 _$ S& S
using System.Text;/ \9 s; k3 R0 z7 N+ [4 K
using NPOI.SS.UserModel;
+ b( W+ V6 R* Z2 Qusing NPOI.XSSF.UserModel;& f- @6 b# p2 p+ p- L9 J
using NPOI.HSSF.UserModel;
8 E' V8 c$ ]9 l( A/ ^6 `) B gusing System.IO;
6 X: w% {1 I: e3 [using System.Data;
8 f2 ?- F5 j8 V
5 Z4 ]6 s+ q/ L0 M0 \1 c1 f3 ^namespace CC
1 m7 e4 a& Z% T7 G) J# S. s{
8 j8 f' y' D5 s# }. p$ i) P! B- Y: {# v: O! y& l+ g6 N
class Program
/ u4 i, H0 l- w0 P2 G {$ Y' f" _2 z3 a J
9 ?" q; \6 N+ M% h! i" ]. `
2 x, {7 O% D# [7 `5 R" J& k
static void Main(string[] args)1 i" G; q2 u Q+ O2 u4 b" M- Q$ B
{" I$ j2 \- M1 N
StringBuilder sbr = new StringBuilder();/ b, Y% [; w4 a- m" ~4 q4 [
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件1 s( h' i4 Z9 G/ V* C2 l
{) v+ X9 i A9 r" Z
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中6 d3 x% l# w0 {) L& G( O k+ l
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
; B) r) Q) S9 U2 j% y {5 I* h. B- h. W
ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
" y$ T6 }# u& A: ?% y# l0 S1 V6 k" D for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数+ X4 w5 P: G8 ~! u0 ~7 v1 ]7 \8 q- w: k
{
# N2 z: ~. v W3 x0 H IRow row = sheet.GetRow(j); //读取当前行数据
* ^2 C7 V( r# L# R! D if (row != null)
. o9 l$ C: L8 c1 Z# O) V0 @; i% K {+ ^0 X% b1 E1 K# m
sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限& ]' k2 g& F1 }: \; j2 Y
for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数3 n- B% f7 u3 \6 @3 ~- ]
{
8 p0 T: @. N1 h; X2 d' D) F: ` ICell cell = row.GetCell(k); //当前表格8 D7 }6 r1 X6 L$ C W3 u$ E
if (cell != null)0 p& U3 f: t9 r# P
{
8 D# O9 M. s0 e+ V( q; W sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型# N" h2 h P. z% g( o
}. M! W! W& d: S2 T' Z
} [5 x4 q- ], `3 d/ A3 M
}
. O* G5 q. `: o- @5 v# r }
/ q' p. a9 C' G }
4 Q b8 t4 g, B8 B7 |) R- N }
" q3 d& [1 K- s& B3 O; r sbr.ToString();8 D) O( j+ a' i# h) a2 u
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
1 a6 a4 S; y' N# Y' m. a/ L {4 Z( b- v1 d8 ^/ f
wr.Write(sbr.ToString());
* Q) Y2 {% }6 q f) S wr.Flush();
% K: I1 J& A# v3 O0 O2 ] }
3 }4 P# Y" a$ {7 m( U7 ], L
3 P7 z, N2 y0 C x% Y( g! b" t
4 z/ }4 D! J6 T4 ?3 W: |! r1 q4 ~ }( e% O# \2 y9 h. ~
. O. E( Q9 ?4 h3 `6 y0 I- [+ {
! k( D: Y7 a! n3 `! q }
9 `7 u: F7 ^# c; y* W: O3 S
% C) C f; z( Z( P3 n, l
2 x9 Q( R) T1 ?1 q! e" D2 _7 M1 F, p
}. ~1 M1 x$ U; F% i4 W& c
5 v/ Q' [7 Q/ o* t+ K
, b$ v, }/ \/ d然后 自己封装 给 c++用) A! P/ _- E, Y
: Z5 y/ {2 C0 G& q/ a
( ^( E5 R. A7 N/ F- A" P+ q/ m: M/ m) ^ j
2 N' S# q3 [4 B7 ?5 F; t r
$ W7 y' ]( C& o
' g7 ?3 m# }, [) F
% {0 m! I& Q# Q% e0 x, o0 k: A4 U7 `2 w D( p1 Y( M* o, j# y# ]
/ P" m: {1 C( J+ I# t* v F) K6 }* {
. D- C/ } Y/ E6 e3 j
5 A) h. n$ R, X [8 s
0 r7 x1 h1 b. ^$ E
8 Y& ]0 a4 t; [ Q. J
0 E- m: L2 ?- f {
4 t2 b9 A% G! P. X! Y _! {3 K' S4 C& n' V4 o2 q2 L1 |
, D: I7 H& B2 A
7 u1 h/ g, T* Q( y1 _% E& B6 B% X0 I7 a
- a! @/ |) R: ?) q/ \: r0 v
$ I1 o* T* ]9 `: f: H
" e; \" ?0 {0 ?+ }) n
; U* T5 |( b) v) O. w |
|