|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢8 R& J: F$ h# m I3 Q/ ?0 m
net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)4 ?- l* n5 Q9 w- g# N5 D. l
这里我用c# 生成 com 组件 让 c++ 调 , _- ^ x: R+ J$ n2 @9 X
) d# ~; W# W! `' y2 O& |
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)- z U- v1 ?( F$ [# w; n# u
C++调用C#的COM组件(DLL)0 f- R: }5 ]5 `9 f0 R
# m+ l9 C7 O# E- e$ R下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.7 L1 C% H' V( \! B
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.- ]; c5 z1 J# p% R' T
9 ^$ N K; Z! }% g B" m! S
% d# W/ ~0 P8 R+ t& C, _9 F" I. F! l1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom3 z7 P9 i1 P, B9 `" U, C3 h
7 R) R& S3 n9 u& ], i2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数# P& ?+ l9 v, r( \$ H H4 k
' t2 [6 A) D: z e4 y" n2 y7 b; C具体代码:
[! x0 k/ K# L/ p! j
( J5 T* y) M r6 @* _9 Qusing System.Runtime.InteropServices; //记得加这个命名空间% O7 o7 S9 J" N; z
) g% [- K- K3 ^: y/ Xnamespace MEI_AddCom
9 n8 ^% x& b1 G
A& {7 ]' a9 N# q{
2 z7 v* r( ~, b6 v- l; B; M. y3 x ^8 a; r9 D; P
[Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.% h, `3 G$ S8 ]4 T A- e* Y5 I! k
7 i' j$ M, R ^ //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生6 U/ s0 z; j1 Y/ V6 Y5 J4 g
. J E" [5 K4 C
[ComVisible(true)]' Z( [ n" J4 R5 m4 y
2 d- D# Q0 b W
public interface MEI_COM //记得用修饰符public2 |5 ?. h0 L+ z: i
: E z2 p! V4 B ~) Q- s7 p3 P3 r {
: F; y) p. X4 b" V |! ?0 ] Q( v/ B) U" {, Z+ i$ M
[DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面6 |! ?0 T6 ]# N6 p+ T: K6 f5 ]
% V" d0 O+ V. [1 Y$ D8 a
int Plus(int one, int two);) `1 C6 [5 Z7 q( u0 f: p% R l( t: v
4 b! `3 R/ k7 M) v! w
}
. {' a; Q; F6 ~ c" ~0 e& i( `0 R1 D( {1 j, u
}
2 F! h/ ]5 o* V
5 ?+ C0 r2 Q! m1 X$ [8 ?6 _& T& Q7 { t8 x) z8 N5 ~1 d8 X; W7 ~
7 I6 E/ u* {+ a5 i( Y+ _, b0 M: @
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码
8 u% d. c7 v g2 o" k: e- H! Y5 k5 `$ `; p4 `- Q% W
using System.Runtime.InteropServices;2 {: R# k, S7 P& m; ], c& g
$ `: B9 |. q. e$ ?6 @0 b
namespace MEI_AddCom
7 m3 O, n. Q) s* E- m: V( l' r
# w7 f* X) w! V- B; C+ E. e{
& x q8 N" o- z4 n' x2 f6 F4 L( o3 s! a4 m1 ?1 F; X
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")], l4 ~% S! `: {: _+ o
% F7 i% E" j8 L; A0 a3 T
[ClassInterface(ClassInterfaceType.None)]6 F* i- L2 i: [/ C
$ T' A, i9 @& V6 A7 u public class MEI_COM_T : MEI_COM* K1 U0 d- q$ ]
; [. \) G1 i7 G0 r1 p6 U* E
{
5 R( O& c \, U: o0 t5 S% `) J6 c" R! _6 q) p! s
public int Plus(int a, int b)
1 b; w3 R- r4 O2 { v) f1 l7 } [$ [: _) C# l
{. w! V5 D% ?7 d& Y# A$ e
! r0 F/ |% ~, F$ f! h) g, U$ Y return a + b ;
8 R3 _5 T1 c2 [2 y6 S
L L, W. h& R; h$ d ~- [5 S+ m }
6 F) {; D( C$ f: k' S" Y+ j% P" h! S& R+ s
}
' i3 \& a7 m3 r4 ?% K* l3 C+ W) _2 s% k* a0 [( t% b- _. g3 O `# {
}, P' a: o( J5 k: I) {/ u
* T. W# c$ D. V& c* {- u6 T8 J+ l }
; x6 K- b7 X3 i% `# X0 f
7 U7 _2 t1 w3 S Y9 H4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].& \' J; m/ |& \ r+ f, R
' Q/ I y# n T右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册9 e2 a) g' {7 e8 p: o" C
! W% ~1 f2 }6 j* ]" y/ r# E$ [$ _, c! t4 A
5. 生成->生成解决方案; Q" R) v" M; l5 f2 D5 N" l
注意 这个时候 生成 非常缓慢 8 Z1 v. b. J; L
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
c9 z7 d$ c. [, J9 C( z# ?0 ?0 T3 A' L- I; I6 u
0 x0 G' j' t$ |' w8 a4 z3 a# }* W---------------------------4 Z v3 }8 C) Y/ @
0 U" w7 l7 E# ~/ Q3 I H) k
1.调用前要先把com组件注册才行.
2 E) T8 e0 Z0 M" ~* J# r+ [
$ C; p0 Q% I! Z. p) N9 R j使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。% G1 C0 m s& F
以下说明如何通过C# 注册、注销COM组件。
/ ~) B5 J# k& u5 w5 z
% g% H( F+ d" {为了能让生成的DLL能够进行COM注册,需要进行强名称签名& b5 N; O8 ^8 i8 X. u( K, } C- ~, R
打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。" m8 f- y1 y; r: v# F
创建完成后COMLib项目中将出现后缀为.snk的签名文件。
# M/ ^0 k) c+ F/ S; d3 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文件。+ j( l( y/ ]! z( _
卸载COM组件: 3 W5 { f' a: ~# O! Y Z" F
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。2 j% f: o [/ {3 n& Z
* ?+ ~ `3 q6 d! m$ h# I/ q$ Z! T I9 d* T
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
, _; ], Y' t+ l# v1 L' H$ ^$ a9 d# S" a4 F
名字取MEI_UseCsharpCom,点完成/ i! Y7 X5 V, R& S
* ^+ q2 Z$ [( Y# U# i7 P0 b, _把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.
9 w3 y; ` @0 P# @! ?- A: L) ^6 \8 B! }4 u5 d3 \" M2 ?
我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:9 N- `% u3 X8 |, |- `. Q
) P' i) U3 v9 F" }( s9 }# [3 o5 c9 d, x7 ^: D& w
#include "stdafx.h"
5 w7 H5 ]7 w$ I& C) k#include <windows.h>4 g* ~( h6 Q; q3 P9 D
#include <string.h>, O: A' \3 _( p4 K$ Q2 Y9 o
" D; g2 A8 I" F3 s' s( ^: m! {
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only0 U- ~3 G$ \0 x% r: M# O1 f) U
9 y4 ?1 ]) H5 T6 e5 Z' D
char* WcharToChar(const wchar_t* wp) //wchar_t转char*
& R# x5 d, A8 _8 w{ * K9 j; u( f: F/ ]
char *m_char;% j% v4 q& N& H" N. b5 O
int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
. t& }8 x) E+ _$ t( { m_char=new char[len+1];
/ B2 q* Q3 B! q( } WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
3 E% A% B' u; {6 `! D: X; ^: w m_char[len]='\0'; , U- h* w2 c4 i* `
return m_char;
: f2 b% d/ `# g/ Q# u5 t$ |}
. ]8 u% r; k( ewchar_t* CharToWchar(const char* c) //char*转wchar_t
) p1 e+ H2 A) J9 \+ l{ q& R: s e* Z
wchar_t *m_wchar;
; m: }- z' v' j int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); 9 r( s& s2 X& S& _9 N
m_wchar=new wchar_t[len+1];
: t3 t! Z; k! {) ~" q5 d8 O MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len);
5 I" N5 H: z, Z" g( _ m_wchar[len]='\0'; ; k2 \7 R$ z2 u9 d: h, r( H# @ N
return m_wchar; . o/ g ?/ x6 u7 `" J% ?
} - Z+ o9 R3 m/ v6 N
+ D' n/ k3 y; Z$ p$ N8 ovoid _tmain(int argc, _TCHAR* argv[])
) N7 Q% R8 H3 ~7 z4 ]2 E& a, h* u* ?8 I, _" { \: ~
{
0 {& c! t( a; O# K2 N
5 z) G) S. M3 C) u/ y CoInitialize(NULL);0 X& w1 |& W- b0 E! K& H/ ^
& ?; `! Q# T; D% c7 Z- p
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
d/ Q/ p2 F- ?1 u6 u0 b4 l8 g- \$ m: p$ t
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
$ W2 Q/ M, _/ p# n
* u+ Y- Y8 D+ q2 F //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接6 j% c2 G5 q w2 t" X0 d2 b$ Z
6 ~& r/ I, B3 a8 q- F1 ~# K
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
4 M- | x9 Q4 P: N3 J //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
3 _/ v0 d$ D5 W5 K- e w; ?
, g9 K' V3 \9 o' C* d long a = 1;
' Z8 N' i- C5 Z" `/ B) q
. b" G1 P6 o; o$ b long * lPtr = &a;
3 I: f5 v! s/ s: u0 h1 u% a% I O5 e6 p
ptr->Plus(1,2,lPtr);/ R& w3 M& p/ R% [4 e, P$ D% E8 C) G+ ?
$ |. e+ A3 W' `" T char msg[132]="";6 [8 g* O, A! Q
sprintf(msg, "%d",lPtr[0]);
% j1 p8 m6 H% W7 I Q/ O; F! G* \; Z" I5 |6 n9 \- D; `8 y/ t' d+ W
LPCWSTR str=CharToWchar(msg);0 M: I% @9 {5 l
8 ?3 f& w0 j' ?" B2 M5 @
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
4 g; u, h' k5 I# ^. n% n$ o1 s
4 W! U2 o' y1 w4 m$ q9 A
0 _9 ]. C' c* C5 d7 M8 b2 `}0 N8 K) T7 U* x) q
4 Q( O7 K$ q3 A3 q0 [/ ~( d) M此时就可以正确运行了.得到结果3& J! u H A7 j: ^0 o& f8 C7 ^
+ r: Q( Z8 P" O4 Y) X- ]% D$ m
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
. S% W5 D. u' T$ Z6 k3 G3 @- Z" R. D# |# K3 w# n/ r' G
) e% l8 B$ ^8 `0 F5 p--------------------------------------------------------------
5 @! N7 h. P& p9 }4 ~) `C# Npoi库 操作excel 的代码网上很多" t& j1 l. L! }5 `8 j, K9 N6 \
# ?+ r4 x# k" n5 ]: i8 x" }% |// ----------------------------------------------------------------------2 X% @* W+ W |9 v% H
// 使用Npoi创建一个简单的xls文件,写内容$ H& N9 [ t+ {$ q3 s1 g
4 G& _" }, `7 A0 \2 x' D
using System;# s! I% S! m* O6 K. {% s! ?
using System.Collections.Generic;
' t+ ?3 A" O+ J1 `using System.Linq;, A$ ]2 H/ s6 x1 Q3 P, t! n0 D
using System.Text;
/ o) O; }8 f6 H0 husing NPOI.SS.UserModel;
8 d( D) v1 Y+ J6 Pusing NPOI.XSSF.UserModel;! c v) u; @- b1 X7 n' A0 v+ J! l: z
using NPOI.HSSF.UserModel;: ^. ]8 r Z; r1 u) S2 g
using System.IO;5 S) A! F0 @. [$ n% l o2 q9 H
using System.Data;3 E* {: Z2 q/ ?; h7 m4 ^
8 g& o% M5 C/ n6 W% T$ O
//using System.Windows.Forms; 9 U: T5 z9 R" v/ A7 A
/ r) e8 ^9 Z. S
namespace CC( ]: L1 M& n! r t& b+ p! D
{
& V/ Q/ H g V2 f2 ?' Z1 t5 V. D) D
8 Q y4 I" ?# b, S( `+ ? class Program# K/ V- `9 T, F1 D
{
S; x+ d; @1 K# u! m7 l1 ~2 L6 `3 \. K/ r
* G, l4 G# ~/ Q, O2 I) A( M) R6 P6 t+ y
static void Main(string[] args)& P6 t2 h+ L+ i6 x
{9 C7 L9 ^/ Q6 d- R; I% ]; ~9 `
//创建工作薄) n9 g5 S( C6 r! c
HSSFWorkbook wk = new HSSFWorkbook();
# c$ t3 q' l. D, o; R* _ //创建一个名称为mySheet的表
4 ]' ^1 d0 P! s ISheet tb = wk.CreateSheet("mySheet");
5 I1 J! g0 q; g% g: u& j //创建一行,此行为第二行! u* w+ O: }- q: d4 o( k
IRow row = tb.CreateRow(1);8 u& `3 S! s# j7 ^- v3 N
for (int i = 0; i < 20; i++)0 G* }" Q' s1 W# A( q
{, w! T# o: M; ]' o+ j
ICell cell = row.CreateCell(i); //在第二行中创建单元格# h+ f$ H- m: |" P
cell.SetCellValue(i);//循环往第二行的单元格中添加数据
6 d7 g5 }2 b* O0 ]" ~8 e9 l4 x5 ^0 i }
! t' \; Z. ?$ X' c' P: ^ using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!" m4 |0 d# M& F( i
{( e$ e& W( Z9 p2 G5 f( u2 Z
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。, s) Q7 m) `' d# i
// MessageBox.Show("提示:创建成功!");
" Q5 @5 H" m# f) ~' C }+ j/ W- b( x1 v* x8 x0 j8 c
0 n3 U" F8 r8 q0 I }
4 c- Y |7 X' U% x: S) L/ B4 E" Z6 ?- G4 C' H
/ s x1 P# W N4 ~3 i# m0 B }
( F7 s4 x8 f: k
J1 d+ T9 L# M
( `! e9 Z( i" `
7 r1 v' D W$ V/ f# O}+ R2 _8 c3 l4 o c# J9 [0 d
( o" t4 U) A. o// ----------------------------------------------------------------------* {( I" R0 P2 x
// 使用Npoi读一个简单的xls文件
$ [# y' x0 W( i& `5 @
2 H/ p3 e f8 `- k% u2 a lusing System;. c9 D" I/ ^+ A
using System.Collections.Generic;& k& W, C' ]: m+ h5 N
using System.Linq;/ V) c/ E$ D4 s) k$ ~
using System.Text;; W3 e. l( w4 P R; d5 b4 a4 d
using NPOI.SS.UserModel;& b2 i! @' _. [2 q5 ]
using NPOI.XSSF.UserModel;
& V, Q4 H1 @2 l/ K" Kusing NPOI.HSSF.UserModel;* R" u3 E1 l2 |1 t8 B
using System.IO;
4 S0 i( S9 k* U+ L5 B- y0 Y- Lusing System.Data;
6 j3 Y9 X6 ~' B% `9 ]4 j- F9 A+ v6 I0 F4 C) w! Q3 g3 q9 d
namespace CC
$ t! R% j2 j# G9 G& k{! @# ~3 C1 u1 W* ]9 G# |& w" ?
1 S7 R3 w) @/ p' {& b: f# K
class Program
" M1 s7 s9 `2 o* Z- s& m {6 F* L4 Q5 A3 p+ s7 E
- k0 H/ y1 I" V- F+ H: X: J/ d4 h$ X# Y/ V- h+ j/ u5 C
static void Main(string[] args)3 D/ ~' M) i0 v
{3 f9 A. h9 {1 A. Z
StringBuilder sbr = new StringBuilder();# n2 D+ s0 ~0 J1 }, l5 K& @! J( e
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件9 P e" x' D8 c, O1 ~# [
{
/ P6 b+ s! T& v) j, c- m8 N% o HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中) N# m. i2 M) K
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数 e; K% Z6 }$ Q1 j" h0 W
{
( W: w& s5 [+ A! E' N* C: }4 S ISheet sheet = wk.GetSheetAt(i); //读取当前表数据/ Q/ n" W0 M- Y4 a
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
- \" V1 P- R2 [$ _8 @( ]" W- t {: \3 U# S R4 @: }) U* W( G% I
IRow row = sheet.GetRow(j); //读取当前行数据
! O+ I7 F1 q1 W if (row != null)5 A# x0 r$ p9 _9 S- `/ V' J% e
{
* X, O- {8 y$ [8 T6 W sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
4 g$ F1 j k0 F% t3 T for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数6 y3 Z( ~- ]; L* W
{, o4 o x* H0 H4 b" H
ICell cell = row.GetCell(k); //当前表格! n8 G6 N6 [! S3 R& s8 V% v C5 u% C! W
if (cell != null). m% c6 ~- {" e A
{7 Y6 S. b- I& H% x" V# C
sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型
8 z( y3 \. s3 Z+ D* Q+ B# A2 }8 _5 o }5 i a3 U+ n K8 {
}4 `2 ^* z) H$ u) P6 z
}
& a, u. G+ c; Y9 N5 _/ y }9 X4 l% q) @, D# e
}+ K& q8 q. Y# K( V
}
6 r% o/ D! F2 m+ R sbr.ToString();: L1 T- ]* G! l
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中9 H; Z5 j- S/ d. f u; N' H
{) x0 s- Y9 R" C
wr.Write(sbr.ToString());
0 S Z9 m7 b- e, y5 ^0 [ wr.Flush();8 {4 D! A! F* A: F- Z
}
8 g, k+ O8 @. l4 U) a4 t6 u6 B
( R5 f% v4 ~% U8 i' I
4 y$ X2 t ~' p6 Y. D7 o( a }. e$ q/ E( F: O- j! f% N5 L- A
# P$ m4 I. L& a1 @
5 i! Q, N" @9 w& c. Z P+ n }
% {" g1 D g# i4 Z0 i- n! U% H7 O4 l ?$ m3 T% g/ P# k
1 M3 x" k+ O" u
+ m! S. Q. x3 H r7 L, n/ G
} P5 J/ J' o$ B8 B! N
: y6 N7 I7 `/ p* i; M# D/ A
# S# E, _8 \4 g1 ?: d
然后 自己封装 给 c++用1 b$ L h6 e0 S$ _
3 F! I/ a: o) Z8 i# X# H2 S- |& J. z$ S7 B
& l2 r# \6 X+ ^ Z/ I; ]
" [; `. E6 O6 U9 S; F" t _4 W V- C# n& O6 i& |3 ]
: |/ Y: S8 B+ w; J* e
5 f" h* o- S: k- B+ Q; ?
; d& F% {6 v4 y0 V- W" Y
- D# u5 m5 C, w- ]/ w: ?2 P
5 Q( b( Y; i2 T- ]$ `5 J: f a
3 f+ L1 ~2 k4 d5 j; ~3 J
& P6 Y* k7 f1 @/ z1 C& ?
+ u5 d/ e# _) k& \
$ E$ y' w7 {) P7 @* O1 q4 W) d7 R ~' Z& b& f7 Y4 ~
; H3 F& _& [1 s2 ~" ]2 _
7 j! V7 S' l: |2 k$ i6 I
& D v. k5 w+ F/ ^* B( v& p+ d: M* J/ f/ n/ ]4 {2 d' S7 x- r
; P7 b9 w& H2 K4 F7 ^3 g( @
8 l2 K% _* t" ~- y3 n4 Q! X! ?; \/ h( ?, F) ]) v( d
8 s& W h1 ~# X0 ]
|
|