|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢1 {' N, P4 Z, x: ~# p
net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)" }: A# d$ R: X$ c
这里我用c# 生成 com 组件 让 c++ 调
9 |! ^3 U& s: O1 K% A# N f0 c: j4 y- K9 i
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法): U% v/ x* \2 O4 I) ], G' W8 C* P
C++调用C#的COM组件(DLL)/ P) q, k" t6 z! K# V, h; U
, F! b7 N. N7 e0 W: J下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.* C% p3 t4 I8 W, C$ r X
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.# N2 m0 g5 d- I" ^, f8 X! K# ^# ^
5 {, r: ?, `; i% R
4 C# W- s; F$ P! x I
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom$ Z3 n: ]* K, g* o. u+ o$ D
4 u! @* c' S2 z- {2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
. { b( A9 r) |4 i% z, |( E1 L
6 _- J9 ? g5 }- I, F- F具体代码:5 Y' U1 N; n8 T5 u; }
7 f+ D, C$ u( `; [using System.Runtime.InteropServices; //记得加这个命名空间! a5 V6 N) Z" M
* i Z; L5 G; P* [/ n, z8 Y% U3 b% L
namespace MEI_AddCom5 P0 f: o- ?* p( s7 u4 K O. S
/ G8 V: a9 H* J0 r9 S3 | K3 V{& {$ |& I! u D7 n! @; C
( b0 ~0 g- f9 v6 a3 \
[Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.$ ^- a9 ]- p3 F/ j$ M1 d3 N+ }/ s
! l+ S W- t8 W8 t //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
7 x$ B- N9 [0 m" A( q9 ]* E* w! }
7 m7 v/ r' B. y+ ?9 |* C [ComVisible(true)]& m3 P, f, S# o) ?) `
9 k9 ~) W P( G* y2 _
public interface MEI_COM //记得用修饰符public
# @' P3 N3 B3 ]9 a( }* Q7 o
`+ W9 A# K" l5 [ z {
* F# E' o- }! k' K/ J0 q
H4 [0 S+ ?$ { [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面
4 I% S/ G' X8 E2 F* R! e2 j
: ?; W7 F) N) d* u/ T int Plus(int one, int two);0 G6 k' L) G; r3 G/ {
/ Z2 N0 w" r( |& w4 w5 X Y! q
}
9 Q u7 r7 |2 [4 L# ^# V
" q J* L7 E, c9 d+ r+ Y}$ p; d3 ~1 l% T- u5 i" O
- n& Q3 U2 Q3 M* k$ L4 j" U# g
6 J: `7 g5 U1 K# `2 K7 t6 `" L3 e# k. G+ Y0 p0 w& S
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码
& f5 X6 i# G- u2 h' x2 G5 h8 Z& B. Y; k( Q' w
using System.Runtime.InteropServices;6 v4 W- ~7 [, E& q% Y; i# I5 E4 T
" s7 M% P6 J' b% Q- R: [& d
namespace MEI_AddCom
$ B$ R2 z! D4 C: M7 a7 Q: W. s; ]5 f$ v8 T2 j" T; R
{
, ]: R7 c5 B6 R w# S% N) c
% g' Y1 ?( A6 B [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]4 J2 R6 d8 {3 r/ g7 X8 y# @
3 |2 s' Y7 L" y8 X
[ClassInterface(ClassInterfaceType.None)]9 R' I8 F: b* m& E8 r0 ^* X
1 N& t, O" y6 z) K6 L public class MEI_COM_T : MEI_COM
* d" R* H# L8 c
8 d. O9 M' H4 C# c. _9 G {
0 U2 O, P& P/ b' }+ e& X( V g: q9 w! |& ?
public int Plus(int a, int b)
$ \: T& j; o% x- L% ?$ ?
& Z' i6 }! g0 F, A% M, R {% e* ]( [1 j4 Y$ \3 a2 ~
4 U9 m% g1 b% {7 V8 I* E return a + b ;
* ~4 S) k6 u5 d) o! M1 N
3 d6 _: |$ y$ V }; {" R5 Z; a' V' {$ D4 s! s
% ~2 \1 a4 t) e( k, Z- P }
7 Q- I: A, Z9 a$ [4 U0 t# Z" @) G% q) c% t
}
. U7 D+ x6 D0 d0 ]" [( c/ d3 ^1 a# M
5 m% u( a8 X0 r; b& V8 s) l H: V2 z J/ U i# y
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].
1 E* |. L+ y* {% f' M1 v
3 m) f% K8 c {' P2 E. a右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册- X- }- C3 ^" h- a9 ?- r
- R" O8 D8 S1 T v& H/ i" ?. W! E/ t8 n X! _) o
5. 生成->生成解决方案
: g5 S1 g; q' r6 J 注意 这个时候 生成 非常缓慢 / I, n6 b; i8 M. `0 H' O
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容. _- r2 A Q% p% \; X
6 a% R6 W' v p+ P: E4 X: n
4 D N8 N7 d7 t$ a---------------------------
6 P* b# A, Z) \7 H/ b& `
8 k; p* Q3 P! M- L2 ~! z7 Y8 ~1.调用前要先把com组件注册才行.
& _$ M+ f& A3 |9 D+ E$ B# k0 s: W+ q7 R0 v8 b' |3 \
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
, A, ]2 _& Z& i* k5 Y以下说明如何通过C# 注册、注销COM组件。
) k1 H1 H7 Y7 A* f S% _ I' m
) k& q& g8 Z8 G2 v为了能让生成的DLL能够进行COM注册,需要进行强名称签名
& q- |1 g, a) K$ C2 `! Z打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
( N7 H. D; H; l3 H2 E# o创建完成后COMLib项目中将出现后缀为.snk的签名文件。0 Q" V5 Z' a! e0 q( i
最后,编译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文件。& |8 F( G. a: J0 ^1 @( b- O3 }0 ]
卸载COM组件: / F( Q( A; ` i2 B6 D- C
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
& p( @. Z }$ H' } p" O0 }4 j+ e8 c4 V9 C6 E N' T+ J% v
3 ^& A# M* w3 b! b* M( }2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
2 ?8 z, M0 J1 p9 }
C) U5 k2 X Q- S名字取MEI_UseCsharpCom,点完成
. r& p: e5 N9 W1 X1 t+ p
5 o9 B1 W9 k" f. B( a1 }把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.( v* r. i6 G8 o/ i! Y, t
( [0 G; V7 B+ ~1 H- d- ?+ P
我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码: B" j; D& |: E: O9 @) \
) B+ F" {" ^$ _3 F1 L
N% v8 z, A. S
#include "stdafx.h"( O, C+ ~* T$ g5 Y( K! X
#include <windows.h>
1 D7 _7 R! H% u5 E5 _! x! C! N#include <string.h>
& h* `; ^9 V5 N/ i$ q0 y' ?* I N' u4 F% C0 i, O" b" Z, ]9 s$ R
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
* f$ x4 z; ^/ J8 ?' q# _' N8 B( Z
% I- A$ N( X& ]9 P+ Achar* WcharToChar(const wchar_t* wp) //wchar_t转char*
# S2 x! u4 N4 Z: \* h& o& R7 {; g{ : D% z* R2 d) F. |+ _2 k2 d
char *m_char;
. ^9 v1 x6 z3 q# O; I4 D) \ int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
: G& e* O% X0 @9 ] m_char=new char[len+1]; h: h3 j, |& E" b% A) w! O
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); " Q* u0 G' g' s" a" _
m_char[len]='\0';
) |7 f' p1 f$ j1 B3 T) Z( Y return m_char;
# ]) o6 [0 p0 t1 q$ x- S9 V' L}
- Z& ]& C+ l* kwchar_t* CharToWchar(const char* c) //char*转wchar_t
% E& T8 v6 P! p, k8 I" H{ - H' D& A. R$ U" j3 f8 w. l6 G
wchar_t *m_wchar;
- W- ~* d. N8 X9 D int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0);
/ y$ E# P, X$ u: |- y5 }! w m_wchar=new wchar_t[len+1]; / H* E# m5 z+ J8 c( ]3 M/ @( Y
MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); # X6 ]% b% r' j5 X
m_wchar[len]='\0'; ! j/ L% c1 l, _* F4 F
return m_wchar; 5 q% C, H$ X. f- g8 {# p6 P
} 1 D$ M+ M; m6 F; s8 Y: M& Q& J$ A) f% b) H
( i$ K, s9 T/ I. l5 p2 p4 w$ t( Qvoid _tmain(int argc, _TCHAR* argv[])" F0 M0 y9 s' F6 v& K
* y8 M. c$ k, f5 I; O0 ?: F
{0 q" m# K, K! p5 W
4 J' D# ?( D$ H; V4 T9 A. S
CoInitialize(NULL);1 e8 Y Q+ Z4 \ _, u; g$ j
1 m g- N5 r, t2 m# v
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
- w$ F4 \- T: ~2 t. b4 r! m* X# U- l0 I- B1 B
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
$ {1 e8 V3 b8 w3 k' i6 F' t+ w% ]
6 Q# m. K2 O1 q+ y; q //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接4 j6 Y- g3 D( R6 C. X& f. ~; m8 B& Z( V
3 W' I' [$ B# k! m5 ?, F W# p
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
0 w+ ]5 u' m+ t' I5 h //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
6 e' T+ S/ ^5 {- t6 d
) N- K2 r/ j( v long a = 1;. P4 ]4 P) e! i4 N( M# v- u4 U/ b
, V2 V5 w/ C( m3 f, y' c+ X8 ~ long * lPtr = &a;; A6 e8 c3 T" P1 R. O6 s: ?
8 P5 U7 @: m' \/ C' |! h ptr->Plus(1,2,lPtr);% h! c0 Z/ j6 d% ~* h- i ~
# y+ @; }/ X$ e; d char msg[132]="";' x+ J5 T* @: c
sprintf(msg, "%d",lPtr[0]);
* R$ G0 U3 J! I2 M" F* ?' H. }5 N' z# G0 ^ ]+ G6 }5 u
LPCWSTR str=CharToWchar(msg);0 {$ q! r. X. s3 Q& N
- @! C5 d2 v D/ Q. y
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
( o, H7 |# d& d% i6 R: ]" |8 [
' C$ [9 Y! b% ]: p8 b7 M& F! U% a. C1 d, h, T
} U# z* R: h- D* {3 ]
' a' v, g; u& i; h
此时就可以正确运行了.得到结果3
) w2 C, U+ p6 W5 c9 i" F5 _+ A2 P% c$ Q5 Q2 e) u: \
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.$ D. b8 l5 E. D$ c
4 N' `* k& A1 @$ Y
% ]6 S ]6 P: B& V# _: |+ [; k! V--------------------------------------------------------------. i& x: d) o- X) Z8 I, k4 M
C# Npoi库 操作excel 的代码网上很多
# l: J6 n# s8 d: j; \" p- G6 @, H
3 I+ r' A5 `$ x' p, g// ----------------------------------------------------------------------0 g2 f- Y+ V9 B3 f. F6 J
// 使用Npoi创建一个简单的xls文件,写内容7 L- I5 M& D) W, o
6 Y* z: J( S. ?1 n) k2 h) s2 h
using System;
% W. ?( Z, G8 qusing System.Collections.Generic;2 J5 A6 H Q( H
using System.Linq;
( o7 c; x+ w }! r% r+ P: m6 d8 B3 lusing System.Text;8 C: n y& R' h' s2 M
using NPOI.SS.UserModel;
; p, L( e* _) q; C# ~using NPOI.XSSF.UserModel;
- w8 |- K9 X7 T- ousing NPOI.HSSF.UserModel;
0 [' A0 I; p1 H# T5 [2 Ousing System.IO;
" u. K: g o; t1 [3 {2 yusing System.Data;+ k( f$ _2 @ Y/ M$ ?% v
0 `* J% C7 G; i% U//using System.Windows.Forms;
; S0 E+ c, g8 H0 T3 }
; i. o! ~1 H4 V* ?namespace CC
+ p) z$ n/ e7 v{
. z# a, }8 ?$ j% `1 i8 O
% \: A" I$ ]4 H: m$ e class Program
4 | s+ Y6 t- V2 R {& @% Z# M4 Z) h( `* ~3 O/ Q. U
* V7 `1 _' z2 F+ i. m& Z6 V) r. {& k( h7 G# |: A3 K
static void Main(string[] args)
) k7 u* i- Q: n3 F: [. s6 E0 N {- n8 }; R+ S. W* I7 Z& c+ w$ L- N
//创建工作薄( I, ?6 }) q; i# n
HSSFWorkbook wk = new HSSFWorkbook();% t6 n) `' n a, n+ E$ W
//创建一个名称为mySheet的表2 N% q" D& I3 B
ISheet tb = wk.CreateSheet("mySheet");
, {6 Q" D. }6 V6 Y* ]; I, ~ //创建一行,此行为第二行0 w l# y8 y# V3 ~ G" e& T( v. T8 T3 @
IRow row = tb.CreateRow(1);
* e- u. j$ ~$ X- k6 [' U for (int i = 0; i < 20; i++)4 V5 \) Q C- i
{
4 `% B" y8 _+ E$ U, G ICell cell = row.CreateCell(i); //在第二行中创建单元格, E1 r" G! x7 P3 h, w4 H5 m1 Z) `2 j
cell.SetCellValue(i);//循环往第二行的单元格中添加数据
6 g& F$ ]3 i/ H; M j, C, z. [ }
# _% A7 }7 \; [* u using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
- k' X, e, D. h6 [- i7 _ {4 J5 d# `- }% X1 s- |
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。, w8 F5 R" v- S4 e9 A$ I
// MessageBox.Show("提示:创建成功!");
$ R) `4 a& L" n/ ]( r9 w5 b }
" C7 E% E4 K D i' j
7 W7 t# t# a* @9 W }
, l5 G9 T% w1 C8 i9 ~0 G) h# f1 X! N/ d' s. F3 A ~' \1 L
, H( c8 Z; g$ x( I
}* `) p1 y) U2 Q) Q5 Y/ k2 D
5 l& A D! @% U; v, f0 J! ^3 u, [+ o
' M) ^4 y5 ~5 V9 V+ D2 }% z) m
. H8 h, L. q/ i+ R! [3 E& d
}
7 j" Q1 I/ p. L' T ]. C+ K( J( e$ c. @0 i
// ----------------------------------------------------------------------& L& \ r9 W# Z' l
// 使用Npoi读一个简单的xls文件: F# g5 a$ I A3 b
) R# U8 i- ~3 `1 E2 a! T3 D
using System;/ ?6 H+ ?. _, T* {3 l: [0 `
using System.Collections.Generic; s+ U& d/ a4 C0 A* I) {2 F- l
using System.Linq;6 ^/ l3 z3 g# U' ~
using System.Text;1 R5 k1 b i2 Q0 b. r
using NPOI.SS.UserModel;
$ Q% ], i& J8 x, f/ \* c, Z- Pusing NPOI.XSSF.UserModel;
[2 X# Y* y Tusing NPOI.HSSF.UserModel;
0 G. g, W: o9 N1 {! T3 Husing System.IO;4 v: S- k' U P
using System.Data;7 L9 {$ ^6 s0 X- {! t+ B
- w/ d$ f6 M' C
namespace CC
/ ]- m2 n# h0 f1 K: r' ?3 o{& i% H4 z7 B" l3 ^3 A' N* @! z
9 z Z9 Y! P0 `$ r7 E8 h class Program
9 L# N. j) h0 Q+ Y {
; Q6 U8 e0 S8 M* s" \3 V$ y; S( }) c$ s* m n4 I* o
: q9 N1 y# i- n& {) w
static void Main(string[] args)1 B4 ?0 a6 o% D; U, S9 K) r$ X
{8 b4 I. @9 D# V# x5 c
StringBuilder sbr = new StringBuilder();/ w9 T* w" f5 h/ e J; [+ v
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
$ P$ w: O# a7 v8 C3 c8 P1 r {
+ L r8 f! s' _ T HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中7 c" |3 j/ u6 s( z) w- G
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
* t. j3 A0 T: o8 [- e1 F {
- m8 j/ ?4 o/ H4 q% n; b4 b ISheet sheet = wk.GetSheetAt(i); //读取当前表数据2 `9 K. x2 p" t$ H
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数 S1 i7 Y- u" ^7 F, A
{, v7 \/ {: r1 S9 [7 F6 s& g
IRow row = sheet.GetRow(j); //读取当前行数据
- v; D$ X3 e1 ] if (row != null)
$ ^4 y7 E$ B, H! r" C0 f- ] {
' s5 {; Z( r7 Q5 V sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
3 `8 F& V9 J1 g( \ Q, t2 F for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数2 W! D* ^; P( R0 V
{
p9 U' M/ e% D) q2 A8 c5 k0 g ICell cell = row.GetCell(k); //当前表格9 l, F+ \+ }2 R
if (cell != null)
: b2 _* M0 @) M; s8 e8 K8 P, i {
! i. \8 z! |/ @$ n- k sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型1 a4 a$ V3 K6 l: p, {
}
6 b: m6 @: S' K" Z. Y8 ~5 C }
: x& Q7 [4 M& q w' L# S6 y } }; B: w: B2 X3 u7 c# M7 M
}6 q1 Y$ P$ }' F s3 X+ c
}
$ r# ]3 x* x! A4 u7 H: y }
" A6 t' }1 X# n+ G+ P+ B' ? sbr.ToString();
2 W# l9 ~% K! _( K- |8 U using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
8 i; C6 r7 ^ q- l {
/ `+ u; {, y$ M% ^ wr.Write(sbr.ToString());( L# j' M4 b' A+ e% p: ?
wr.Flush();" [. g: f9 n% m+ P/ _! v! |
}
; Q( P: U: ^& h" M4 k
* }) o. R: U9 S5 s: U: F
: m7 X5 N1 }+ S) R( a- } } q' V G3 x1 |! ?0 z$ a
^8 ]2 g/ v! d, b- O0 X
0 |. B$ k2 o7 e1 O }
+ g( E, B u" d! m7 K6 p0 K
3 c+ V& I/ ^* M7 C4 D8 K
/ V2 Q# R/ O/ M# F. B( w
7 M$ w& W6 y6 p# _& z( d}
8 a; a3 [, X2 }" Z
! {3 ~1 w' H% V
( I6 G8 t6 j+ A" k4 f/ h5 h0 r. S然后 自己封装 给 c++用
0 A* c- ^, ]5 l- H9 J c0 ^& t$ N% X8 a
' T! {! i8 `2 q- j+ |0 \6 k- p1 o6 [6 A
, ~, S6 O% r% |' q( u
! S4 M3 ]- e3 h; o) @; }1 F
' E3 H! `* D; i" ~
H: |1 r4 r& [; x+ `/ `9 g
+ t/ p! [: R( S. Z
+ v& K* c0 X5 J+ z2 o# G; j0 D5 T7 X5 M0 O( D' w2 J7 @
5 |5 B7 X; O$ w' z: \! {" [) r* k7 u: [4 l3 u
+ g/ }- W( a9 i0 R. _: g# Q" o
~8 z4 F$ _1 }1 C. P1 T/ Z/ _$ n: O( G
3 t; k& N# e1 ^4 y' v+ U2 @6 c: ~
0 `) y$ p) d6 L1 k. g- b9 {
3 r$ j, t6 @( D W4 P
, _7 g7 }; ~8 i" O, K( L# E3 `, h$ {/ n# o8 I
3 ?6 X: }7 _! z" P! N2 L- W% l+ ~3 U9 \2 I" r! {! F
" W. M' P, G" {/ {, x5 `% Z
2 T! S( z+ t1 I" d |
|