|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
3 H6 J$ `. h# h4 P7 Rnet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)
" a% |0 D z; M" W8 F这里我用c# 生成 com 组件 让 c++ 调
5 I: Z9 J2 Y% |% ]
2 D: I8 U7 E# l# L首先要学会 c++ 调 c# com组件的方法 (和com注册的方法); m3 o! l' D2 r- d, ^/ ~
C++调用C#的COM组件(DLL); W6 @* K. q" B6 a
% b+ i- V5 X/ P$ P
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
. p# r) u8 `! d8 a: t首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.; @. I/ E5 Y3 [0 y$ k' k
" A2 {5 u/ b5 M# [7 m
/ h+ b4 T' q) z% F
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom
i9 K; u5 Y6 H2 T
" y* n. u7 E, b& U4 I( M5 ~2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数$ O; R! D5 A6 Y
) e' U7 @$ i" `1 I具体代码:1 C/ D9 X6 \. k m7 @& F
8 d) `/ [3 l5 x6 _2 Xusing System.Runtime.InteropServices; //记得加这个命名空间( L7 s& n: C: B f7 s( i
) i/ a$ O: g6 O+ ^# i* H2 M
namespace MEI_AddCom
* D3 x0 ?( t/ |9 i% G2 X- y- B9 L/ h. D) o
{2 o; w# H' V9 G/ O/ L, b
9 I9 W# |5 S3 z. Q* p [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.
+ I5 S9 g- y/ P b" J
' F1 }/ b$ i9 r: ` //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生) U, m p* f, O! n' v
4 S+ o+ c, n8 Y ]% q: J( R) F [ComVisible(true)]
5 v5 A" o2 Z/ V8 y
0 F) I# d& L7 O4 g* w/ p' N# I public interface MEI_COM //记得用修饰符public T/ N6 E. e" K4 H+ B; X
4 @; V- s+ m" }/ [$ v. \
{
3 z4 U4 J' Q9 p' t5 k/ T
5 u i. Y1 r9 z( X5 y; z; m7 W; ? [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面6 I& d+ Z% G8 v# D" x8 s& w
. O: a+ N& P$ d int Plus(int one, int two);* g+ r; l' D# U* x
( e5 Y6 B8 k- t T$ L) R% _
}
/ j: C# O2 _; U. B. g( A
+ F9 j& }# I B1 P}
) n! g, ~- k" V8 a+ j2 F$ U% F
) O$ O7 V$ o) \
7 }+ e3 g: a, `3 x/ Y1 b0 c6 ` P7 {- Q$ E9 r$ S
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码( j4 r3 U* `0 s% Z5 B" V+ m
6 u" p6 V% s" Q( S/ m Z! g+ z ]3 L! F
using System.Runtime.InteropServices;4 L9 m8 s G! c' x
" b' u" o+ Y- a) ]/ d# ]
namespace MEI_AddCom# j5 g& }$ W) s4 W
* k; [ A0 b& L: _- W{+ z, u+ Y6 A* j6 x& d
4 T, `% n6 Y* Y [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]/ G3 |$ ^" ]! c5 Q4 x) }. Y
% E7 j' H }0 W( ^ [ClassInterface(ClassInterfaceType.None)]
/ ]3 s3 Z7 u7 Z7 p( b4 c g2 o7 E. }. b2 K/ `2 p. {
public class MEI_COM_T : MEI_COM0 b- I: p0 `& v! M# |! m; Y
1 ^& t7 x4 {8 T. c7 Q1 l. z/ c {
_8 V8 g. I: M4 w( Q3 s: c: s* B: a H" |! _
public int Plus(int a, int b); s* `. [) Z9 M% B
/ U9 D `& Z5 D7 {. x
{( X! O! R( ] T5 A
: W2 s! w8 j- _% f return a + b ;) `" ]! @# R9 ^: F: {3 |
0 H4 A; G2 @7 u" X
}
0 S' D1 d6 D; X8 g. M
: W V, `$ z$ M! [ }; C4 d" n+ p/ d; `
0 p% ]; _: w6 m# g2 A}* K: _5 {% _% b/ N: U, b" I
6 R( ~3 `' g/ |" Z4 M% W
) _0 L, a4 h% I/ N
# U% X9 m( f- P/ B4 P4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)]., b1 B0 _5 m. ], j2 [: ~
" o4 Z# y: i- `
右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册
5 R! A; }, ]+ A
9 c( U0 L8 e1 H- |; q' ]
; ?3 \. K8 y, h; G. a j5. 生成->生成解决方案
f* g* b0 {! M# ~! T. m. u 注意 这个时候 生成 非常缓慢 ' A( U8 b, V& @4 _; b
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
o6 X/ W7 o2 B" w0 z1 N6 W6 U1 | t5 V! _
# W/ K/ ?' x2 {---------------------------
' H- o f; S8 t' `2 l, h; x8 N
" Z9 K4 ]5 V1 b/ K0 j1.调用前要先把com组件注册才行.
9 q K3 C& X; ?- @6 M0 `6 V. L0 v+ I+ a! D$ h& Q
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
7 z, ^2 D, m$ N8 y) _2 u以下说明如何通过C# 注册、注销COM组件。
, w- s0 \& _) H8 S2 H+ t+ O" h4 W, o; o" r% i. c2 l( ]
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
) r5 |5 o; y- P% S打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。) E$ S; h! W! ^# X1 n) u
创建完成后COMLib项目中将出现后缀为.snk的签名文件。
, e" O Z8 {5 G" U, C最后,编译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文件。
5 Z; ~( ]0 R: U) ]卸载COM组件: ' M' S# c" U% `5 c+ N9 W
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。$ f, E& ^* R) |- f2 c3 W2 v
. s v0 C$ p5 h7 I4 F2 P' _7 q
, a* N4 `+ I. U' A
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序 E; w8 Y g2 Z2 F/ A$ V/ B' ?- _
! C! S* V* q" r6 ^$ j
名字取MEI_UseCsharpCom,点完成
- m% S5 J2 z1 a" }8 ^
4 Z6 k$ M1 }, ~* _: {' i把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.. T+ |/ j0 I1 m1 e! r% c
) F: d L7 R4 a$ Q' u& Z
我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
4 ~# ~5 o! ^; L- x' _
( k, o$ x4 e# {6 i4 e8 O! F4 w+ \2 v$ ?* d8 X
#include "stdafx.h"
# x: `1 |( z" m5 v3 ]( R1 s0 f#include <windows.h>
7 \, M0 t0 G7 \#include <string.h>* m9 F1 t4 F! [. R; B- Q' w! G
7 W! f9 V, T" ~ k! s, x% J#import "MEI_AddCom.tlb" named_guids raw_interfaces_only0 F# H- [& K! A0 z1 q1 f( B8 b1 y
* e0 l4 i' ], j. Y$ j, `* vchar* WcharToChar(const wchar_t* wp) //wchar_t转char*
1 D3 G1 N7 i( x$ d# p" E# d. _6 W+ D{
# M6 x! D1 W6 K1 \" O x. o char *m_char;
1 V4 Z5 b( `7 |, r. I' X int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
) o+ s/ i9 e4 c/ ] m_char=new char[len+1]; % \7 c% H/ Z) ?6 X* A1 ]- R
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); 3 x2 C( P: N% ?
m_char[len]='\0'; - ^% ]4 C6 _, B$ @. {8 E! t0 D/ K7 d- V
return m_char; ( |7 n, p5 E7 x
} + |! g/ R& }8 S+ ]4 d! g9 W5 {
wchar_t* CharToWchar(const char* c) //char*转wchar_t
8 D* \7 m+ l% d. r7 C+ a- y/ E9 b% K1 F{
7 { `( ~% h: }6 b wchar_t *m_wchar;
; I$ s4 q, N. ^( i4 }" q: O5 s int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); 7 E7 s* O# x5 q+ i1 {
m_wchar=new wchar_t[len+1];
2 X% |! d2 g0 N5 Z MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len);
. c- \* {! f) W5 C m_wchar[len]='\0'; 3 D/ u+ `4 O1 v9 {
return m_wchar;
5 N5 ?6 ~- `$ W N} ! c1 ?+ z8 _7 H1 T( ?4 o
1 o9 Q f6 Y, X- O0 f% n$ Mvoid _tmain(int argc, _TCHAR* argv[])$ O& m2 N b; Q0 Y4 ^
|6 P: n$ x1 \) E+ o' L5 y
{
# U0 H$ C3 D; n% J" P8 ]- K) g7 F. H$ W2 m. U; b. }% M) I
CoInitialize(NULL);2 Z! z# }# _0 }$ V2 {8 ?) M
( Z. r) j( Q' V5 h$ i* p
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针9 @% z9 B; i7 U
. q2 T7 |8 F' ]& _# A ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
2 Z+ o4 d/ g+ r, n, ~ H# o1 \- B
//这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
2 I2 T& V: r6 j3 u4 K# y0 c/ V7 Z
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.6 r# C H- l3 g6 Q8 d3 l/ |8 I+ H$ V
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果( u) d" P! q4 e
1 b7 ]1 w0 e/ p8 K& X% z& J
long a = 1;
( m0 h- M m" F( c, M, J7 G! K6 e! ` Q, x- ~
long * lPtr = &a;! V& P3 k. _) \. I
' ~2 {* Z" F, L6 Y
ptr->Plus(1,2,lPtr);
. S$ P) f" o. Z( V2 }& F5 h; a; D6 z% p/ C" q
char msg[132]="";
& l* m1 H9 l- u/ B sprintf(msg, "%d",lPtr[0]);
$ ^5 n) L. ^ s0 d$ t: l5 W: F
8 [! f+ [* a1 L3 V8 M LPCWSTR str=CharToWchar(msg);
$ D* V' D% L1 [: U/ R' b4 _( z
, Z; B0 O" w' h, m MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
1 V8 M5 D9 P/ a+ |7 o3 p
8 J# L8 l# ?+ b$ f% E- ~) t3 Z% B8 M0 l' O- T$ k: `4 k4 m
}" V l3 Y" a$ |* L# N1 i, d( O
7 M; P; V+ o2 w; c4 C& H此时就可以正确运行了.得到结果3
% Q3 y% s7 |: d5 F3 _- L2 ~) L5 B3 ~7 v* P0 H5 f
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.) }# }2 H; B: Q7 `
9 t8 W. K" g' ^8 c7 ]! T" ~# r' C; A0 j6 P! c5 `3 t, i
--------------------------------------------------------------/ z0 d+ ?6 b; U1 t X, w; u+ N
C# Npoi库 操作excel 的代码网上很多5 Y4 M" D0 ~: X3 W/ P9 I7 W. P K
9 I2 |- q. E2 q6 z// ----------------------------------------------------------------------" l9 z! ?2 Z2 L8 s% q
// 使用Npoi创建一个简单的xls文件,写内容2 m9 d% M3 D `, ?2 |, L {
( @ @9 u7 X( ?+ L C
using System;
0 d/ K8 f1 ~0 S* \using System.Collections.Generic;
, s/ w- F4 r; a+ V, R2 kusing System.Linq;2 T0 ]# v) h1 N
using System.Text;
% b N. q* M0 wusing NPOI.SS.UserModel;
7 }6 e1 f/ N' g" Z+ [using NPOI.XSSF.UserModel;
+ P- P' V/ T/ @: kusing NPOI.HSSF.UserModel;7 v f+ p: J! ]1 o* y! Z) A# s) u
using System.IO;
6 b* s2 [7 D0 P" V3 a# g2 Lusing System.Data;. \. o$ M: R- X5 g) {
1 ?7 |4 n3 h7 ?4 Y/ C9 X( S
//using System.Windows.Forms;
1 G2 {( h" r: r4 i: [
/ T4 b0 g% S& F0 }0 F. Mnamespace CC
" N, z9 P& F2 Y' I3 n5 @0 w{& A j4 ~3 c" @( A
, U0 u% [; \9 U$ k0 X$ a: ^2 V% d( s
class Program8 g0 k) V& a6 M7 F7 g2 F( ^
{
: ~0 H: N8 q1 f5 U3 Q% w7 y8 g9 {9 ^ w8 E- U* ~
) _" c4 T4 a" z1 B# L5 O
static void Main(string[] args), m* Y1 V" |- G. b6 x6 p- ^& q
{; D8 P. M) Z4 w
//创建工作薄1 | e# E9 K* ]( u
HSSFWorkbook wk = new HSSFWorkbook();
7 [# O' e; Q" {- ^5 y) b //创建一个名称为mySheet的表
$ h. N: S. S. R7 ]( o1 H6 T/ u ISheet tb = wk.CreateSheet("mySheet");
: K" {" q% g/ \7 \& _! e( _7 H //创建一行,此行为第二行
4 z3 U5 ?) N# k; Z$ R1 P1 b4 G IRow row = tb.CreateRow(1);: o- ]& V8 I" n( o' D( Q( x" p( E
for (int i = 0; i < 20; i++)
4 \6 |( U7 n9 ]5 @ l5 W {4 b) V, F. p% U$ T# `; K
ICell cell = row.CreateCell(i); //在第二行中创建单元格# Z: ?4 ^8 b- `- G( \' e3 C
cell.SetCellValue(i);//循环往第二行的单元格中添加数据
( q/ _+ H( |7 ?1 H& K! \ }
) \7 k& n6 o+ [8 w: |2 | using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
( U% p8 ^% w z0 C# N {8 H" \# N0 s5 n4 U9 l8 z3 k
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
6 l( E5 _6 r# ]5 N! l. H // MessageBox.Show("提示:创建成功!");* n8 X/ Q! x# h. t% {2 o6 G+ c. A
}
" n" m: q- w1 K6 W' ~- u; j1 B$ W! g1 A
}9 e/ D: _ A4 t
# R2 K6 ?3 t% n7 q
1 u- t+ I* w, }, q; c/ S0 e }
1 P/ k8 {& {8 _/ `$ D- g6 J0 D
3 {5 @+ h7 V+ m
3 {# V- E9 E0 W* T. ^3 o0 I1 D. ?8 i+ l3 J3 R0 f& r ]- j
}; ]% {3 Y' {& D0 s' ^
- U3 E. _0 k/ |: K// ----------------------------------------------------------------------6 k& B6 S& [0 V
// 使用Npoi读一个简单的xls文件$ z' O2 Z' c( H# J a* O
$ `* P, f6 ?+ x
using System;) L4 T2 Q. E9 [, U7 t4 D" _* V
using System.Collections.Generic;( ?+ _* }) I3 |: L
using System.Linq;
; M, E3 E% ~& K' J( R5 _using System.Text;
/ e2 G) L) v8 u* V6 g' Musing NPOI.SS.UserModel;( C6 G8 w: ^' B( f8 T
using NPOI.XSSF.UserModel;5 I% G; U; k: G
using NPOI.HSSF.UserModel;7 _: x3 |$ ^% n. f" \7 y3 r I4 j
using System.IO; W/ J: |) b! p
using System.Data;
9 d/ [8 i$ q2 y u5 G7 ]+ J0 m3 r( a! l
namespace CC
/ |1 S4 N. {4 e' n9 n7 E{3 P) q- s3 f" ^) P. k4 m8 w
8 ]4 i. G$ U Z class Program
, `& E `; ~5 @ {
. w) p7 N( M5 z( @- B. a. Z, w$ ^& \& o: `* P
7 L1 B- t6 x [( l. g8 b static void Main(string[] args)) h& `7 F1 P1 U9 @3 n( R( c
{- j$ I- @9 k( O8 {
StringBuilder sbr = new StringBuilder();$ j. n( y% V! I* ~- {9 H: @$ x9 c
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
! ^7 y% s; L& S4 M% ?3 \$ h) o {% Y5 G7 ?$ `! p Q; s% f2 e$ m# ]. A
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中% B* E' w$ C! J4 H% o" @ D
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数9 V, g+ Q+ W" P8 i0 ^
{
; l0 M( ~3 Q. N* p, i" [. F4 F+ ~ ISheet sheet = wk.GetSheetAt(i); //读取当前表数据/ L, e( q2 j/ ?" o
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
6 v& J" \; p, i% U% R' V {
2 I& q8 ~4 _2 }& j' r4 Q9 _ A IRow row = sheet.GetRow(j); //读取当前行数据/ G9 ~7 v- w* R/ Y
if (row != null)( ]$ F/ w! B! U1 n/ c
{
% e3 M |% ~ A0 X sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
( b! c2 S; k$ L) ^4 L for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数; @" |( B0 @4 y1 A
{% n: I2 k; z# u6 q$ l& B) C
ICell cell = row.GetCell(k); //当前表格. s5 p" k$ p4 T4 i& g
if (cell != null)
/ N2 j/ f3 i9 Q9 F {* C$ @1 m g- Z1 O) b
sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型. P/ _: J' L# P+ |& h |& L: [
}2 V0 t V1 I9 b$ ` y: V3 K
}" J/ X/ ~# I% M/ H J5 C
}: v) E: H( O6 |3 G
}
2 c9 ]* Y/ ]3 B% V7 o3 ^ }! }1 {; s$ c) H
}* t8 ^6 c; h, n$ w6 R; R
sbr.ToString();. i! _; d! x8 v8 b& f
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中3 L, a u3 J* y% C
{' z) G% B+ E& K2 S2 C6 V, m
wr.Write(sbr.ToString()); S7 h6 z+ q P* _% e; d' c
wr.Flush();; Q+ b2 L) g& V7 X1 v. O8 I, _! Q) X
}" Y& f9 a- h- j5 o3 D% U& N4 ?
7 L5 l% r, n V U( f" X; z L4 s0 j, J$ |& {9 a1 E3 I
}3 o. @1 U- f) Y$ S; i% ~( x
+ E. x' _" G0 e5 ?1 X
9 I3 c' v" g0 p; ?+ Z4 g; ~
} l+ W* q% L6 k1 w
, v" o1 p, \& p' X2 E" o4 s
* f2 }' j5 h" B: l0 r' \5 l
4 w4 ^( |1 ^) j( o" _: o}
1 Q; G& j; d% }* W: c$ r& m; ^8 j/ ?$ q; a; `8 E* x% h
( ^+ q; M* c; r {# ~然后 自己封装 给 c++用! b) M3 K5 V' ^3 D. I
8 T7 K7 r8 C; S
0 v9 |; p; r1 X& j; M
4 U! y2 o; w. P, {$ m7 T7 r
7 u6 f; E2 E7 P! j" v8 d, x* n) L4 n- f) C
I) T& i, \- u! G h, U
) L% T8 ]0 `: C1 Z1 n# p1 @3 H
% r1 J% d2 i. Z: @, I
8 r8 Q {: g! i. f9 l* H/ w
% o, I# }4 d& e4 k6 R2 X* h: e4 o; h8 Z4 `* `- j8 X3 a4 }
* y& K, M0 U7 [5 U$ }) ]) b
E; U W5 n3 ~+ Y3 E# E% S1 @% c1 `$ e5 P4 F2 `
: z ~: l1 m) j) o6 W+ f
2 G! b) @) O0 ?4 I+ V# R
& z% T; r& E) {7 g1 V0 ]/ t! X [. z8 n1 B$ S- g# k# M
+ ^* W2 _3 F! ?1 z. W& I4 A( q
. G& {* o0 m/ r4 c
" I5 Y2 e/ Z& a: g# i" W& N4 U% D* u: f f6 @) g
|
|