|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢! ^5 ]9 |. j( v9 `$ }0 t9 a
net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)' d' S6 @/ Q6 K. ^8 h6 q+ Z/ f4 T7 N
这里我用c# 生成 com 组件 让 c++ 调
/ _. h( X0 m! j
* h. g; k0 S; w [# }首先要学会 c++ 调 c# com组件的方法 (和com注册的方法): P4 m, u$ C% d% ?2 x. R; a
C++调用C#的COM组件(DLL)7 q0 u4 }( z3 _- @ N' f4 W
. s F1 A% y0 M y3 m, l; u1 |6 y下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.( V" c; }& c% h. l1 i; {
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.. Y2 y/ i/ U5 f! l8 o6 N4 N- H5 s2 M
, R" }0 [8 f7 x$ D% S
8 a! l) V5 \4 N8 f7 {1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom6 M+ i& Y J! c; Q. a# B
a! i& v* R9 Y) J; F2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
* \1 Y2 H+ B8 G& c+ q6 z- e3 I: L1 y- Z# I: w' C
具体代码:
, p. y$ F, a% p1 P6 D3 G3 e9 |; a/ t
using System.Runtime.InteropServices; //记得加这个命名空间
8 @" |1 p! p6 q6 T. k3 N0 F' V/ q( g
namespace MEI_AddCom6 r) n) K/ D R5 N6 H
1 _8 k) d, G0 o5 n
{
1 y, w h0 h2 @/ p9 E0 ]
$ T9 E) n% ]" d* F! ^: E) W [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.$ S( c F& T; \! f" S
$ T2 \4 f) w0 \. s //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
# ?/ r; e9 [- W7 v2 a6 J
! h) g; R3 W' a. H( e$ d [ComVisible(true)]/ N# c- p" F! B4 A+ x
2 X6 F/ g7 X( ~* W: {( U' T public interface MEI_COM //记得用修饰符public, [# G5 u2 L( t
# H I9 p" w6 m, |4 S+ R
{" l* x2 Q6 T5 a- o {
# \+ k2 H2 a- v* m6 D, R( I
[DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面9 C. X: J( `9 w. w2 R! c# q
' p2 F+ Y |; Y- Z
int Plus(int one, int two);
+ f2 W3 \7 L8 x& F. W+ J$ ^( i8 l3 L/ l5 k4 J. z% q7 v$ w: w
}
* }/ Z$ z& L$ {" @- J8 @) \, K0 a. }! D8 |
}# x. T& |7 ]. V; `6 R- I
c7 \# ]6 a: Y, m
' n3 B9 q" N% z. U9 I% ]% W% q
3 {7 i: Z+ e- X' b8 Q/ S6 R3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码5 v2 t1 w) z0 ~; k
n$ M; i: {8 e* L$ `( Y Ausing System.Runtime.InteropServices;. U2 C) ~% H- s! `- A* G% Q
5 {1 w' u' T3 d6 Pnamespace MEI_AddCom$ M4 w$ g2 V7 F T1 O: n' |( m0 `
' r3 }: q3 \+ E+ L. b+ t7 B
{
; b9 b4 y- _3 u" Z0 O
" h5 x, v/ ]1 W9 n- g+ k8 e [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]0 x2 Q- T1 \& C) U" s* Q$ ^
7 g: s8 c% Y; M, c) b! ~ [ClassInterface(ClassInterfaceType.None)]
8 J' ^; S+ |# p1 O/ y( ~) h
! L5 T- n5 w( }2 ]$ _% e. o public class MEI_COM_T : MEI_COM
" p" M5 X3 O6 j
, }" J6 W. Q2 T3 ~: X' v9 Z {
# a+ A; \2 k/ G) K6 \/ `( j! X' m" X! @. r2 g5 z% o& k9 ~
public int Plus(int a, int b)
) Z$ d; w3 ?! }0 C9 r
+ x' p, w( H2 E {
) T6 b: R2 m S0 }% e
0 c5 h" m% k( m* E0 V. u( K/ n return a + b ;3 g# L1 z" ^6 F2 G M
* n$ d- L2 f! ?7 N
}
. s! J1 y1 }4 p, C# L2 G; z% ~. {- K# O7 C+ Z$ j8 ~6 c$ G5 G
}
& }) s4 S3 W, Q2 p! K" @. Q/ _7 C( M% b8 ~" d: J
}/ z4 \6 X D3 O$ h# ~' @9 D$ Q: V9 X3 d
4 X: q3 ?" d+ f7 Z) _# @6 f# p4 L( r* h0 u
8 R$ P- r {+ w
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].
! R6 p$ k. j; L, Y$ I
" X: G* ^8 r6 w. A# i右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册, E3 f/ c6 r u+ ^2 z0 p6 S% Y& [
7 N5 j3 O C0 K+ `" K
: ~" Q- ?" y. d
5. 生成->生成解决方案+ D% I' C# o+ q' \1 V4 e4 w
注意 这个时候 生成 非常缓慢 : F) ?7 ?4 `$ z% H& y: _
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
& g/ ^( r! p i$ r) _6 B1 R) @5 | p7 H, H6 X L- y: v4 G
* N1 X, {8 M' U( P1 Q
---------------------------- C: v0 t6 j! Q/ Q% N- ~) M% ^7 ]
( V/ k6 B9 S2 D# v9 P
1.调用前要先把com组件注册才行.
! b8 {; d# v7 }0 {1 t& j; P3 U( W0 B9 v4 X5 b: n
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。8 P3 f/ S+ z+ Z# C4 q
以下说明如何通过C# 注册、注销COM组件。
) R% {0 p+ U7 w1 J6 \
5 K) y1 {: x q' b3 \" T" U为了能让生成的DLL能够进行COM注册,需要进行强名称签名
! K9 }2 ?. l4 Y$ f5 Y4 F打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
2 n% d# y2 j0 @* N% W创建完成后COMLib项目中将出现后缀为.snk的签名文件。5 B: G; q* {, Z! _, l$ A4 n6 g
最后,编译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文件。* M+ e; F/ c( r2 Y3 i# B
卸载COM组件: . @# y! M) ~/ D4 y
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。2 X# R4 e0 N; l$ Y, J- f2 `4 \! g
/ c- P& i! o2 A) g( v# x: r
3 R' ?* M: V: b- }/ z! c9 W, F& Y
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
2 b/ w6 g, e7 I; B
6 D' q; }( l6 M4 l名字取MEI_UseCsharpCom,点完成) Q! g/ m; H0 w8 x
' F- H" A0 D# i( z% q
把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.' E* O9 i$ [7 `/ u
0 z' Y6 p, s3 Y8 a7 J% {我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
$ g T( M3 J8 ^( g! k' m/ V2 L; I2 W/ N3 h4 N
. c6 ~2 e7 G/ F6 F#include "stdafx.h") V: S; H4 S$ q) `; h
#include <windows.h>
6 w9 Y4 Q, k) m" k#include <string.h>, d4 R2 @- e9 w1 i! N/ B4 [6 W
6 Y$ D. H4 I( ]' u; z3 q) S
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
7 w) z1 m* j6 R+ S2 ?5 H+ M! l& o: \
char* WcharToChar(const wchar_t* wp) //wchar_t转char*) Z9 g. V& b5 u3 s3 _
{
: ?3 ]- Y/ R H. M- k; h; }& s char *m_char;# m7 Z8 |7 b! \7 J
int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); * Y/ C$ g8 x1 q
m_char=new char[len+1];
: Q( {! F6 n5 J9 |( {5 ~) l WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); 6 r1 m4 ^0 y$ [$ U ]4 T6 C
m_char[len]='\0';
8 F; }* k* M/ }0 I2 w" J return m_char; 7 n) c4 d; |! w3 A8 q
}
9 \3 a4 X. _0 Wwchar_t* CharToWchar(const char* c) //char*转wchar_t! R8 ^* V! p4 E L/ n/ V( z: X
{ # F0 I. S) D9 T9 L
wchar_t *m_wchar;
9 Z: f2 s0 u3 }/ E" d! y int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0);
4 W$ L+ s- C/ d. L& S m_wchar=new wchar_t[len+1]; # ]! H0 ?. W1 @- Q s# n6 u
MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); 5 l1 R4 i9 T9 Y7 A1 q2 T7 k
m_wchar[len]='\0';
# ~0 b+ w2 k3 Y5 u1 H return m_wchar;
: H9 n- b6 k/ A- C% @: x& E}
8 E; M3 N* v! f( F; s( D3 g B, S J" H; Q) w" k- L
void _tmain(int argc, _TCHAR* argv[])" T G# ]5 s4 Z* d
4 k- W8 o! m* ?9 T& U" t
{
" P) _9 U7 H% s4 d7 `7 S' D$ z" B1 T+ x% k- j2 m& _7 P# s
CoInitialize(NULL);
# a1 N6 S9 \5 u& o8 w: j& x# x* @+ D8 s5 K' B
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针# A* z2 [4 C- x" O9 F' |7 K
4 E0 k/ I0 K; N; g, }2 ] ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
" j G# l( E; Q; M, m' ] g# l) x U8 H7 z* D/ C0 l. _
//这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
7 h2 I p% Z3 o- c" v& s1 d' x, @ S+ K/ }" L
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
( h" A, P+ f4 y. f' h7 u //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果1 Q% P6 i( A$ \2 D
0 ^: q6 a1 e$ Z5 {
long a = 1;
: i7 q+ T0 u8 C/ \8 u& z
6 {& i w- c* \ long * lPtr = &a;, [7 [/ p! A7 T6 C; g
' \1 S! z; U: |: o
ptr->Plus(1,2,lPtr);
5 @0 Q" m% a$ P. u4 r- H; w
, d/ T# F- {, r char msg[132]="";& M: S. y' b& ]% J/ V: S
sprintf(msg, "%d",lPtr[0]);( c6 G5 k% R& ~3 t+ | A
4 \: [: V2 o. D+ e LPCWSTR str=CharToWchar(msg);7 w$ X; Q9 u9 @3 M5 W( z
% ~/ N% b! r) w& [! {
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
3 N2 [& W [& f, K" J
/ W" j/ z3 z2 ]! ^! F( F I* s8 E8 |1 K0 o9 ]/ r, l
}, x3 m& |- P2 Y9 a) ~$ p
* j& O) [+ f: W; R9 w) o( k; Y
此时就可以正确运行了.得到结果3$ B* f# T, {% C, i' f5 C" x
4 I' ^$ L# _" d* n7 M
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
+ \! @2 v1 w; K1 r
" L" F8 y! I) v8 F; t& Z2 ?$ N8 O, ]. j% w% C N
--------------------------------------------------------------
1 a }6 w9 g& a% h2 ^C# Npoi库 操作excel 的代码网上很多
6 ]; x% I2 s, @1 b% y7 k3 ?% Q$ U
) c9 M3 c0 D3 s2 @9 ^// ----------------------------------------------------------------------! Y; ]1 Y! h) q" U t' Y& G
// 使用Npoi创建一个简单的xls文件,写内容4 b+ n+ e7 Q3 p% m U9 q6 A& |9 |
' W8 n \" e& @& \& ]4 G
using System;. l4 h1 v3 l$ A# Q: h" M# ^% L
using System.Collections.Generic;
6 k% t! z2 U3 B: @! a- husing System.Linq;
; j2 R% k" |; n( S4 u6 n8 Yusing System.Text;" Z5 W) b' t8 ^- }5 r
using NPOI.SS.UserModel;* X3 h) @' i7 x0 o
using NPOI.XSSF.UserModel;
. R6 m; I* q, T6 Pusing NPOI.HSSF.UserModel;
2 g9 p" b5 {2 x2 V8 _using System.IO;: r% v6 U1 j) x( p' y
using System.Data;1 w U" s2 F. ]! r( J$ l3 e
. C" d% {& W8 x. v: Q( f# G" A* P
//using System.Windows.Forms;
% u( a. P4 M8 A
8 \, P1 t" K, W# L( Znamespace CC
5 Y0 Q( X5 ^ I0 Z{$ Y9 W, Z% Q I6 n0 a( c' ]) b" |
$ S3 G3 V" V0 E# ^6 p3 p7 k9 X
class Program5 y% P' N2 n* {8 u) Y0 I6 n$ C
{
8 ?, I4 B! C2 S# ]0 R! D" \6 F4 [& l: L; x
. e, e$ I* }# B( c- a8 d
static void Main(string[] args)
% k( k8 ?! H. I! @0 ?2 p {% Z+ T3 v8 H6 }( V M4 z! M
//创建工作薄. i6 P4 t/ h. S, P- \5 y
HSSFWorkbook wk = new HSSFWorkbook();- J U5 ?* G4 ^# `: Y! o$ O2 h4 u
//创建一个名称为mySheet的表
7 i6 s: g: v/ h! L: p ISheet tb = wk.CreateSheet("mySheet");7 j/ J( w5 o. P4 N- h/ l7 y
//创建一行,此行为第二行
* J+ f, O' m6 Y+ i( O+ T! I0 W* M7 \- N- n IRow row = tb.CreateRow(1);/ Z& S! C( G" h( ]7 f' f3 }0 Y3 i) {
for (int i = 0; i < 20; i++)
& E. K+ ~: @ m+ b! g* I' f {6 s5 L5 p E6 y6 [ L
ICell cell = row.CreateCell(i); //在第二行中创建单元格
/ O! t6 r+ a. e: ]# M cell.SetCellValue(i);//循环往第二行的单元格中添加数据
' g4 ^( S6 T; [, a, s }
/ v% N6 C+ B" L9 s& {* A6 Q, e using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
6 ]* d* i2 [9 R% f( d$ b {
7 M6 o4 N% i+ `/ D) h1 ]; g5 X wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。: @! Q$ | M* v" S+ B
// MessageBox.Show("提示:创建成功!");& L$ B7 e4 u# K4 A
}
; ?, w0 Y. L, S# T! |4 |& h: M$ e9 a! Y8 H) ]& {
}
6 l* P0 p( a" V! K1 k) M8 t0 L5 X* y. l1 U6 E
2 T% F2 [- k( p v8 L( n/ i }, ?4 Q: y* d: `0 v
4 ~' _5 \4 ] s. n5 r5 [2 u& o$ f3 j+ Z
; a: d! `# C8 t}+ D% G( X& @4 {- J' J% T% \( R# A
) ?/ l7 B. E' m
// ----------------------------------------------------------------------
5 l$ i& `9 e8 }0 a6 {1 `( g q1 y// 使用Npoi读一个简单的xls文件; N4 J4 L5 ]) U3 \, A6 k4 f
2 R! D. q0 n0 [5 Wusing System;
$ n& C! n& s; P. Lusing System.Collections.Generic;
$ m# G9 [0 b) l5 v/ o uusing System.Linq;
3 u% e0 P5 l3 a' ]using System.Text;( w; l$ o* j& w4 v# ]
using NPOI.SS.UserModel;( y$ p/ D6 @* r4 ^. Z9 D" \& s" D
using NPOI.XSSF.UserModel;2 g7 p' j- Z9 J/ R0 [7 G6 _
using NPOI.HSSF.UserModel;. @; B% G3 c: @# R# o2 ~$ V. C) \
using System.IO;
9 ^- U: ?+ y) i" G% i- }( A$ ]using System.Data;; D v$ ^, U. ]* Z
, e+ R& y% |0 r% k+ t
namespace CC/ `. G$ [' I- d6 }
{
1 s# E; d. I( A; x! O. V1 Y3 ?4 o. x- W+ y$ o9 o
class Program
( ~- {" ~8 L4 _8 U {
2 W8 I7 e+ D7 m7 }
2 ^( T: z- V, l$ Y" a& D* x0 z9 Z8 _4 ?- J* |0 U# j, J
static void Main(string[] args); l l% o8 [0 U' J& E
{/ L, p! T; Q8 X. }. w
StringBuilder sbr = new StringBuilder();
* M, P; t+ X* s* p8 I. h' _ using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
5 g- u! u# e: ^9 k" r- g1 _ {
, {8 D9 C" c7 Q; ^$ _) a HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中; C T5 Q; M6 v- ?
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
5 P1 _9 Q5 Y3 r3 k {
+ C$ O- W" C! g/ d4 V3 O ISheet sheet = wk.GetSheetAt(i); //读取当前表数据' ]1 ? N! `; C, r
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数( H6 W: D; C2 V' }$ ?
{
- [% ^) x% |/ g. v6 d& q. R4 S IRow row = sheet.GetRow(j); //读取当前行数据
) e# J4 U6 F3 B9 l9 H. L5 F. X! n if (row != null)0 `+ f3 ^/ c" S; H3 F& w) h& I
{
2 W4 g5 T0 s% `( [8 E7 K sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
4 R# |' p, R$ Y/ [8 x( a8 ` for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
9 n5 j# ^+ C; `. H1 } {" J9 w) _$ z& j/ _3 R1 k
ICell cell = row.GetCell(k); //当前表格
, q; C( h4 C+ h# |1 T( A% K: C if (cell != null)$ o& X+ v0 {- t/ n, N$ F2 \
{
. d5 J: |- f: R) j- y0 S: s sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型1 ?8 t O+ N3 i8 I' H5 a
}% r2 ]/ @1 S% T, M( S% I, I
}- q$ h. {; \% M3 z, u" z
}% a$ g) ^ |3 a2 |
}5 D8 [. P+ F C& {6 Z. A
}
s! A0 l9 G, a }' I& ?1 N9 ~* I# j' e- y
sbr.ToString();
+ m& X1 j" s8 q- B$ ^& @ using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
" T- H9 D! y6 |3 S5 P4 @. G {
0 K% w! ^2 M e/ v% R: w wr.Write(sbr.ToString());- K" i t% Z- R) Z* G6 ~
wr.Flush();. ^5 z$ M9 b' v7 }/ b
}
, ~" J `2 S5 p# t" x/ C& M& `' Q" M! I1 f" S3 H& [
: y' U; _. d8 P! ?2 Z
}, n: a5 j* M$ O
9 c' |- ]6 l/ K( `6 k p
7 r, n& S; K; j1 h- f }6 N! V5 y9 D4 e4 |9 u
1 `4 d5 H7 Y @3 |2 C8 \+ @ s$ L
" {* U7 [( b9 ?8 U}
8 U, U# Y {& u
/ _% U; s, S/ _0 J5 T# W6 c1 B2 L/ @& N) V( W& n- }
然后 自己封装 给 c++用0 g4 c, n/ R7 N) I$ A
2 U/ ]( t( V$ o5 A" t, K l) Y/ [
# S9 X: A) _- g5 F6 X% C' @! o4 z2 Y
: A7 p7 U/ X% l, k, Y
0 `& A) A/ {5 q
/ l* R; b9 e3 Z+ w6 P
( i* Z: z( h9 T
# B! C7 [) q% v4 H' W
; b B4 b7 g( |2 M9 v' p/ a% m9 g5 H3 y( f& ~& B4 h
; a! Z8 W$ h/ R/ B2 g y9 Y% ~
! D& c1 B: ~) t; E) B* p0 E c& a
1 ?- m. o* A0 V# l# p' G0 S1 `$ C! e H5 @4 y! x
/ `( L3 D2 c! v# @) R0 Q3 j- d
, n8 Q3 _+ _' K% p! q$ x
; v+ D6 W3 j. \" F8 J' T; a
u5 L% H$ [. O! W% h' E4 D# i. @0 E1 j l; S
8 g' T) d: S5 H9 E, ]" b
/ L% o( c, x# a, d" b) a: m6 X1 ?
6 X$ X/ ~8 e" r7 S/ D1 N9 a+ e
5 t) r0 p" D* G* H4 y6 N |
|