|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
! e8 C3 G, H2 o, hnet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)% l- |5 W7 Y6 q7 s3 X
这里我用c# 生成 com 组件 让 c++ 调 ( [& _& z2 N+ a& I7 d0 `9 S
1 f2 }9 l* r3 h- N6 K3 x7 c
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)
$ [: n6 a4 e1 U' L4 YC++调用C#的COM组件(DLL)
4 a9 e, j# Q/ D5 v4 Y k8 v# h7 S' k/ q: {
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.: L* e \) q: J e: F' |
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
# }7 n% j) v: e4 w% z4 F4 o" o6 `& n- r2 O
' q7 V9 q& I p- N' k) Z
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom, J1 U, E6 ^' Y) j1 J5 u
3 _. P' Y0 j5 [6 p/ S. B
2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
8 s! e5 l4 u2 w- S2 D- W4 j, o0 t% j4 G" W6 r+ \
具体代码:1 s+ N6 ~+ a5 g+ h: [' p
8 Z7 z9 I8 W; U3 A6 R) O, ?4 vusing System.Runtime.InteropServices; //记得加这个命名空间, y9 J2 A; l5 [( [
, @8 O$ X: G; K. ?- ?: J/ [. v
namespace MEI_AddCom. W" h( P2 L; ]' a$ ^$ Y' o
- K# A& E) N1 w6 O! r{* B; }# a8 w! T& m3 |
; S$ j* A6 r* k2 N. }7 @8 M; g
[Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.
# F7 ^* M5 I7 s* m9 Y7 x/ U0 l* M/ Z) I ?# p" H3 l2 Y2 w
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
: t3 f4 a i8 K H' I% k
$ r9 Z: [5 R3 d- b; u [ComVisible(true)]( ~* {* i1 Z. j n
5 o8 n9 @6 n' M! c public interface MEI_COM //记得用修饰符public! a. `( T' x8 x
s4 }9 L u& G, q# W2 k
{( D8 k7 b! |, J
9 ~! f' {! l/ B& c; }! P+ i/ u [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面) h- G% N/ A9 h3 f; O
6 K! o1 m# f3 E8 \& J
int Plus(int one, int two);$ _- j+ ?1 K6 P" H6 w8 `4 a
! v, r4 N; Z7 z' F5 A# c/ k
}
9 P L/ a$ q4 N" p! Q7 P
7 r3 z& Q+ F* V+ R}- Z5 q9 B, G4 q3 V# \2 ]
8 G6 B+ m/ E# ~) l) j
' {3 t- N+ N" e- Y0 J. t) ~. \1 R _ G+ m3 I) j1 a* |
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码( |, v0 {4 B3 o/ o! g
) `7 `6 p% o) W) T3 j+ e/ ^7 @using System.Runtime.InteropServices;8 R8 l! y! \% d/ z& ?5 l
6 E0 ]* z# o9 z6 qnamespace MEI_AddCom6 F a7 O$ {3 H2 T2 ~
6 c' w! n$ A6 E* o, Q{
4 f2 v0 d6 ~* }9 m: p3 @' g+ o8 ~: O, U: |
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]. @2 C h6 U- X# h; O
6 ]7 C. f0 e- n Y
[ClassInterface(ClassInterfaceType.None)]
2 {( `8 f0 c/ ^! l# x$ y* F$ v% p: F7 e9 ^3 b6 Y6 D5 I Z# |" f
public class MEI_COM_T : MEI_COM
0 V& v6 U+ N# k# r$ f* @0 l5 q) j8 z# o A7 b8 {6 ^
{
% a9 I0 @) l7 d! y9 d" F7 o
4 F% r C: x: Z+ c public int Plus(int a, int b)
7 v+ c: \ { D: E1 W, G
/ X1 V F4 c: R {) \ o* r0 {- |! o' f7 b) P
' |3 }$ [6 q8 f return a + b ;
" q. C+ W6 [& I# u$ h4 w- o2 g0 G; ]8 U/ y: ~! v% O. M
}
D! V' l- Q) O0 X- G) P% s, t9 ~8 J2 U2 T( c' u: u
}( g7 O7 H7 L: h6 _( o. I
' \5 R2 a& o) Z7 R& k4 L* ^! k}
P* h% |- P6 n7 }! P" D8 N. p
( V9 m. p* Q% i# H& a- _' R {; R) G( d
2 U4 t9 Z3 g, m; r: ?) \
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)]., H! _4 V* Y$ r! @4 ^# W. n' \
! I: C. R9 x8 f' N" B
右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册
+ Q0 v6 v2 X/ c3 d# Y2 A" w, m O; Z& c( ~ o6 D
4 ^( y, u% o* j5 ?7 w
5. 生成->生成解决方案4 C+ t* u t0 A- ]/ Q
注意 这个时候 生成 非常缓慢
O7 J. Q' w8 K! D# `& O0 M 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容# q; ~; V" [- L- o2 o6 u
; f3 u" z) M4 \, S# T0 H }8 S, m" E/ E `8 n
---------------------------
0 s ~1 `9 R; {1 c4 o% h, H6 R! y3 c+ z5 ]+ N
1.调用前要先把com组件注册才行./ R) ]- @! a; r. y
$ e' l5 U' X* w2 Q5 }: K* b使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
# O. L6 ^# G/ f0 X/ ]& R以下说明如何通过C# 注册、注销COM组件。
1 t4 c' Z& K7 _( _. v
% S& D) Q+ a: H5 s为了能让生成的DLL能够进行COM注册,需要进行强名称签名4 [9 I4 h( S7 w6 q# }" V
打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。6 m, X* P f% q# ?, ^
创建完成后COMLib项目中将出现后缀为.snk的签名文件。7 z7 h9 k4 u& Y
最后,编译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文件。# }# v7 ?, X1 Q B5 a4 B7 v* [1 T/ Q
卸载COM组件:
1 @# Z1 F% @+ H' G3 E: ^$ |# @与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。. e! C a/ O, F! ]5 E
: g: o- c: a) i, M' u$ X. r# ?8 H4 v% J
/ Q' `( f E, n0 K* _2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
6 }: h+ S+ r1 o
) j# o5 w5 U1 m2 q3 h) l名字取MEI_UseCsharpCom,点完成
7 n" L- ?& o# S. L% h* {( {0 ]# ?/ Q! @5 l
把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.
T7 H4 S7 v9 Y1 F& y" A
6 ]/ m3 H0 M1 |3 }/ f8 V$ C我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:9 `1 r- o' a3 T6 M& w5 R
6 C# @8 D0 |0 f& M3 n" x' M: [. n' g( M0 {& _: U# c+ Z( D, V! ?: U
#include "stdafx.h"
7 s* x( f7 H+ C#include <windows.h>
! F2 ?# U+ z0 o5 n. b( I+ h#include <string.h>9 [! ]( ^' O: g1 _
4 s3 L7 r# d5 b: `6 G
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only+ I) k3 D) z% |6 g* z
; T. e4 k9 `* h
char* WcharToChar(const wchar_t* wp) //wchar_t转char*
! L, ]3 {; K% Y' [9 v4 L{
C7 k+ I' f% v5 k8 X6 b* A char *m_char;
! J9 i9 Y3 n7 Y" j8 P8 B) `* A8 v int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); " K4 F3 [+ d# Y: N
m_char=new char[len+1];
# Y' M8 H0 x1 L% @; t) ]" k0 L7 j WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
: G" y5 s/ G/ z G" r8 I m_char[len]='\0'; " \3 |: Y) i! l2 [5 K1 q' h4 G4 g) N
return m_char; " p" J0 G/ d+ F; _& T: I
}
1 n* t. ?8 Y/ f' g2 z6 J- K6 ~" @" Fwchar_t* CharToWchar(const char* c) //char*转wchar_t
) S. s% V- \0 V4 M: a8 J0 w{ 8 ?7 q$ ]/ [: v8 r
wchar_t *m_wchar;: _* ^4 U! _7 s
int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); % |6 S0 P4 D \
m_wchar=new wchar_t[len+1];
; {1 |5 j p' t" y MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); 0 e8 l: a% E. O
m_wchar[len]='\0'; . H2 p. c4 z" }4 Y% a, r* I2 X
return m_wchar; - y/ f" L) S) `) w
}
: y$ |8 X8 H& `7 r5 F
: v" A* X) W) ^- ?: _! Rvoid _tmain(int argc, _TCHAR* argv[])* c- w7 p* M% ^6 W9 c
0 ]( }9 c) a1 t- m# t
{ m# f; c9 \1 w0 q
* k- _6 ?" o# ]& h$ Z I CoInitialize(NULL);2 m, m0 ]1 j+ w# o3 l9 p1 r2 h
" _* |; e1 T/ B) V& B! t1 d. h2 j
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针# X4 p0 s {& M3 [1 T
4 [8 k# @9 o* H# T
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
* j6 l ^' {1 f9 A8 q4 i6 }+ v. j9 Z0 O+ ~ `: A# @. y
//这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
5 ` h4 T0 P1 ^ g4 H7 \5 `
4 K8 s0 X% ?! _2 C' @) c1 r- m$ d //来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.7 R4 N1 Y+ u( G5 u4 l/ v
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果8 R4 ?) U# c) t7 D
$ \" ?$ q$ ]& Y1 A# J0 g; g a long a = 1;/ D- b& w( z* m. e% c+ O
+ E) l5 n+ P: B( u) }% a' F long * lPtr = &a;- H/ \9 |- x% k6 ~& I: @$ | ?
; s: ` f0 M: b* A& k4 E ptr->Plus(1,2,lPtr);! R0 I H) X6 z, i* Y3 {
! a8 |5 w/ E6 F y; b1 ?, S8 h% m7 M char msg[132]="";
% q2 B) E; W; S: q sprintf(msg, "%d",lPtr[0]);
/ W5 _7 g: R; k
( ~4 Q7 }1 y* z( T LPCWSTR str=CharToWchar(msg); ^! ^1 z$ W ?
" R7 u$ ]% C# Z" ~! M) l) L
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);" i1 w: `2 _" V4 A
) Z5 X b4 { e2 t3 m( i3 A* |2 G0 W5 w0 P& k1 y6 }3 U; E
}
8 ^2 z6 P7 G# X7 n
& x2 A7 b! [2 I+ h ^此时就可以正确运行了.得到结果3
1 h6 E s) D* \+ O+ Y. k2 _1 g' e2 n |. s4 |
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
8 n0 G1 C8 p& N( k$ q
7 s1 Y6 c! B% j, p0 W9 Y8 Q1 X; B5 U1 S% S
--------------------------------------------------------------! d8 f' N( j; u
C# Npoi库 操作excel 的代码网上很多- ^* _, l' b$ N
' t7 |: S9 G! H' J: h7 W2 l8 L
// ----------------------------------------------------------------------8 `/ E% z9 w$ T. q" p
// 使用Npoi创建一个简单的xls文件,写内容
) F3 a% }& ? Q, D
7 ~: k k$ k; R* ]; u$ wusing System;4 X( l- Q" u2 X( `8 }: q5 R) r
using System.Collections.Generic;
. {1 P7 P2 N5 p; H$ M' xusing System.Linq;
# @4 v) u9 O' X0 Q8 Rusing System.Text;
& }7 {) Z. ], L B# Pusing NPOI.SS.UserModel;
+ a% q# E: B$ @using NPOI.XSSF.UserModel;1 e; K! d8 m; ]0 A2 y2 W
using NPOI.HSSF.UserModel;
* L2 e( i' _# P7 r C( iusing System.IO;
3 ^( b9 B3 ^- i$ i/ x7 }' p8 H) Jusing System.Data;4 I0 p" [' y( i/ F5 b
) [( z3 z: J o. V# ?! C B
//using System.Windows.Forms;
3 x z+ F' g; Z8 J& l9 [ n; T1 c2 }4 i- N
namespace CC" i7 p! _; Y, L9 J0 I# x2 l
{
4 d( v5 p. D6 Y7 S0 q
- J" R4 U9 w: ? K. P class Program
7 T s) d) v# T7 X {0 {" T2 L/ e' j
& t8 g. C g6 Q! b. G7 ~; L& i2 P M& }6 K7 I
static void Main(string[] args)& Z3 K# ?9 l' @" _3 n L
{
6 z3 h& t# P8 G4 u$ x) g% ^% Q8 l //创建工作薄
. ^1 e# }8 P' b) B& n' G8 \ HSSFWorkbook wk = new HSSFWorkbook();0 J/ D$ T8 S/ v' {# Z% p
//创建一个名称为mySheet的表
: Q( Y: Q9 ~+ ~' J+ p ISheet tb = wk.CreateSheet("mySheet");
6 V7 X3 Z9 U% H; H //创建一行,此行为第二行& t+ L7 _* }" S1 x# |* d3 z
IRow row = tb.CreateRow(1);
3 N5 v& q9 F8 T( X# b- ^ for (int i = 0; i < 20; i++)( b, y( c6 q1 S- U% Q" m
{2 {7 J' h# k3 H- Q
ICell cell = row.CreateCell(i); //在第二行中创建单元格
- T* {0 H, ]% Q# a4 U$ C cell.SetCellValue(i);//循环往第二行的单元格中添加数据3 u; v: O/ s6 G. v2 ]; U% d
}6 }; z6 V) J9 a2 R5 d
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
0 Z' W. `; F% ~. A! y7 G2 m4 Q {6 R9 Y6 h+ N0 T, j
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
; I# ^; c5 b; u0 r$ V, ` // MessageBox.Show("提示:创建成功!");
$ A. W7 D; E. j4 e) b0 E }" ^0 v, y1 p- ]+ H4 j
' w) _. @2 v7 s% |7 R- \6 _2 P8 r: S7 u }) N, S& Z6 D6 w% D7 {
/ e: p3 y; T5 Z z: n1 Q7 w0 M
9 y8 k; e+ k% q' m' D9 F4 P, Z! M }
& r" ]6 ^3 X; P. J2 m9 z4 \( d* t9 c
; @0 j4 |/ a' R4 k0 U x- g. P
$ n1 `" z: \* x3 p! q* H}
- X' p4 M% }3 q/ \! X8 A% ~4 Y: H4 J8 A
// ----------------------------------------------------------------------+ H/ Q$ w2 n! I' u
// 使用Npoi读一个简单的xls文件
# L3 s, f- P5 b% e* {# k$ U6 G0 `; O( N
using System;
# o" p8 W5 N7 [: Vusing System.Collections.Generic;
% E6 C, w* T" Q3 ?' H. |using System.Linq;
2 C& n! n e L2 R; j$ o* }using System.Text;; ~1 g. M; l% w
using NPOI.SS.UserModel;
. l, I7 F+ f0 M, X' S2 tusing NPOI.XSSF.UserModel;
" T- M7 j* Z! f+ [$ T2 g! fusing NPOI.HSSF.UserModel;! k; R6 ]$ x' i5 Q1 h, s, K: W$ o
using System.IO; M, F( U) q# g; S
using System.Data;
5 q6 y- I$ O/ u% F" V8 n. F# v8 _8 C5 s* C) t0 o8 t
namespace CC
4 ~+ y4 a4 g" j{" z0 k4 n( ]% m, _3 A* K9 M# g8 _
9 W: m1 R! h) R& Q
class Program1 q% A$ |7 w; }) ~$ y
{7 f5 c, D C. ^# ^
/ o5 c# C- k, @+ ]4 p5 W
8 |* k* K" K( M8 K2 _9 Q static void Main(string[] args)
" }7 k( M( T! ?' V& L& V {
+ b$ i( S) C l% q0 a StringBuilder sbr = new StringBuilder();
# j$ s& ]- D/ v& \/ ]& p q using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件$ \, c" F4 E' `4 I+ Z
{
0 N8 P) ^' _: C, l0 a! r HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中) u3 a7 n( d3 {8 C+ z6 c0 s
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数9 [* j( h: o! r' T
{6 y3 j- B7 ^( x7 t
ISheet sheet = wk.GetSheetAt(i); //读取当前表数据9 y$ E& @2 p$ E
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
5 L+ K' z/ m; n, ^, h {6 y8 X- \+ L% x7 J8 K6 {% [
IRow row = sheet.GetRow(j); //读取当前行数据( u3 ?! q/ S p. @7 H! x D, g+ i
if (row != null)2 B8 W# [2 T6 s, g) P1 h x( V: h f
{
7 h( b6 z8 O* ]! B sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
/ z8 C' k( z! S6 s for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
) `* o% Q: s( i( C9 X: g9 ^ {
' k+ a; I" N2 I! i2 i, a ICell cell = row.GetCell(k); //当前表格
/ g% q/ U. [; e; P% a if (cell != null)" K- {* K0 Q% n
{
8 D6 m: ^$ k; @% H# v+ B+ @- s/ G sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型
" s$ k& J4 |2 U. b- m }. X, j7 p' h5 A% `
}" m5 @0 }: B4 k2 r1 [
}
% t; H2 g* H! ^! E3 a$ u }" }* ^3 m! x5 z" c# ^/ |2 l
}' D& v- V5 J D2 u
}
, ]4 k' }( Y* M2 V. e# y sbr.ToString();
) `& _5 O$ Y% F8 {1 f using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中8 @* T+ z: i! S0 e
{
! p, \& G/ n( F0 E: m wr.Write(sbr.ToString());9 B: g/ c* {+ A3 ~- R2 p O
wr.Flush();
* p0 U5 l" T. D, s }1 T _: t+ h, l/ {! t2 K
5 v+ j- G! Q. r( d# G1 y
! N0 A" v8 S, x! n }
, T9 Y0 X! M/ V3 F# d2 ~
& x5 i! Z# m% d- M& d: u# d0 e
. [4 R: ]( G0 t* ^! p }
8 s) \1 j# E% M7 o" P4 T: J k! [ n4 }
. n, z1 Y' b# Y; M4 ]8 _, s/ e+ N5 R+ Q( y% ~ R" v8 m4 ^. {: Y
}0 B' |3 y; b1 d3 z; D4 g/ {
0 H. p2 X/ c* ?+ }) x
0 U4 q0 S7 ]9 P! k4 o2 M9 a然后 自己封装 给 c++用
) s, h; w& e7 j* l2 m+ S/ F+ p' m) z1 K, i
$ E1 h* W' O/ p
& A# }0 l6 |* [# ?1 Z! z
/ ?. O8 p$ ^5 D* W6 R# n7 `. w; L5 {( a7 ?- d# `
! s( |3 _% ~: K. u5 i2 y( j' x' P, v8 P
! R) |4 y1 V! \/ J3 Y2 T; x0 i
% [' t* F7 _; E) h1 ?: ^2 }. K( ^% ?7 ^% R6 H/ Y3 @! P
! G) y7 o$ D( ?4 k
/ _4 b1 D9 |+ l! F
A. Q% O* o; S1 c1 I2 f% W; Q6 ~8 A8 A' u4 N6 L' V
6 H+ V2 X- {" H+ ]
5 e$ T# U) U, ^! H# h0 T. }
( y0 A$ s3 _' U* g0 n
3 Z: t4 ?" a! p5 _+ J7 H) v0 Y& s. ~$ }; N1 b7 X" d
3 U3 I, E) @1 K% t
* Q" G9 I: F) C( [4 P' F/ W
1 E* g) J; E3 y& C( P/ E" d0 [
3 J6 Q c) z( p9 i6 O- Y4 D% Q |
|