|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
×
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
* [+ A0 Q! ~: N0 Q% V0 |net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)5 f* t8 v+ t: m) k4 \
这里我用c# 生成 com 组件 让 c++ 调 / `: s: c* K( b7 X
: }, C3 R( ~5 A0 O t6 {) W. ~1 x
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)" j8 b: z, [5 E O. j8 ~+ O
C++调用C#的COM组件(DLL)
# Y9 @1 r( t1 w7 Y. r( p0 m8 Q! @
3 W0 V. c) A- q下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
5 N+ N8 u6 \+ h) O3 q6 N* O首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
4 g' V5 D% M# T" q) s& M2 H$ }& R; G7 S
; j+ z1 Q# q8 G d* s3 K0 ^; i
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom
7 a! M+ ]+ x3 Y" k. t) P8 I; \+ n# M' O; W& h- d9 R) s9 t& x
2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
; F! U8 a) m: F" F3 S: a4 S3 J3 H3 |4 v7 G' {) U# U% k s
具体代码:
# O. p4 v% ]$ y' |
$ B) A6 u' S" Lusing System.Runtime.InteropServices; //记得加这个命名空间4 Z; h( Z' O Y9 P D7 {
$ H' b6 W& @( v5 W& M" r8 g
namespace MEI_AddCom. b+ @; p! o: ^6 ?9 b
8 j) ]5 J' K# ?* _
{4 }% v# J1 P+ v
! R5 a, t+ B4 E [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.5 {* _' Q C: ?- W" e; r
: a( @" k- B2 ~( m* ]
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生3 [2 k8 h2 O. z3 }" d
& n' [1 i0 C n0 @+ J [ComVisible(true)]8 O9 g& @' a/ t y p- @6 R+ E7 U
; y6 W( {. C6 G
public interface MEI_COM //记得用修饰符public) F3 J6 t' I, Y* k) G1 T
) f6 D8 `. E2 ?- F* L+ c
{8 H9 e% q* b' H: P
1 E" i9 b2 L6 {7 H; | [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面
* s( N' \ c" B) N8 x; N2 j4 v2 Q( J+ X' O$ s( ~
int Plus(int one, int two);; C) Z2 ^1 x5 j6 K+ `' l: U6 ?5 `
: p e4 t7 R2 B+ t }
; j! j- h9 l. R4 x4 H) f
" B# R+ @# ?" c8 X* I}" k1 K5 |' M6 W0 X) ^$ ^1 T9 m
( t2 b2 @/ j6 }' [- J |3 y5 w
1 R9 j! U: P1 H# }, t" O' v- z$ A, B
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码
; `9 q0 u" \; R1 z7 {) b0 E6 r3 h; v
using System.Runtime.InteropServices;
( k4 p2 q; t. u0 B
1 C( \" ~0 a& Q, ~- anamespace MEI_AddCom) J' G) f' u) q" j$ U
& T6 r H, X1 \1 [- c% M/ o
{
b9 E( `5 k' e3 O3 K8 n0 E6 [; e) \% h" r' d
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]3 ~4 S5 m( ?* [# ~
/ j l, n4 R8 }0 Z
[ClassInterface(ClassInterfaceType.None)]
0 t/ Z+ e9 Y, ~3 y6 s: P8 z% [" Q1 @, Q
public class MEI_COM_T : MEI_COM
( G5 n* e3 z7 O: L" a" t
8 n: t' F8 m- g {- ? H# ?6 m. v# |
0 b$ E7 P# T$ j$ ?- |2 U public int Plus(int a, int b)
6 ?) C5 |; H0 _# f' u+ B7 D5 S# e: m$ @$ b3 J# K) E
{+ a4 d7 u% @. n3 P7 q5 Y; d8 R
2 r5 L/ k* J8 x; n+ h0 B
return a + b ;
5 r" L Q4 r C6 X2 a9 T3 U
" o/ T' K$ ^: W2 c6 w }
1 A5 r2 {7 y/ ^; k) T
" m8 J4 z x; z }
- k' \$ V! T% X0 n+ x6 d3 \
6 D' k* |$ t3 @$ Y4 N' {4 _% c}
4 W- p* ~! d5 E6 ]3 s7 P) J" O- }; X# L! C) [# S6 Z( i
% f" e/ Z3 ^& E
6 n! v, P7 o! h2 ?' u5 a" W4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].: R0 y, E/ E, O1 ?( F
8 o9 X9 w/ ]& q右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册
/ [& }# W9 S- q/ x S! L& |. f9 v9 y' x' j% K
- ?0 n3 Q0 Q, A; p5. 生成->生成解决方案
' \" {6 l) ?$ d5 k# e$ E$ @ 注意 这个时候 生成 非常缓慢
/ j& B5 Y! O# n m! ~ 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
2 y% i, a* o5 l# A1 W
" q# r7 i' l: \5 x4 Q7 K( M% B: R5 u: t4 y! |2 J) y" m# l, C
---------------------------
! w4 j* M6 x! y0 Q( U/ o( a, ?; K) j) j4 G, r
1.调用前要先把com组件注册才行.$ Y' ^3 D9 `: B
7 I3 O4 A# g' n( n Y+ `
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
: X, I8 D* `4 M. Z$ Q: S以下说明如何通过C# 注册、注销COM组件。 , \& ^. q0 U C* o* u
0 J3 n5 [ ?, {) @# l0 J
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
- A7 d+ _7 V N. E0 a7 z0 G打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。6 k; R9 l+ A+ {3 E) I/ a4 Z0 S
创建完成后COMLib项目中将出现后缀为.snk的签名文件。9 v, b! N, _2 F0 @
最后,编译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文件。
% H6 Y; K. [9 z7 [7 n7 ]1 s卸载COM组件:
- e* { b# m- t与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
# f2 g- N' O/ |! u7 N5 e8 o! \2 z8 t6 p: b) D
# V- N5 A: ]% _% A' N' | _
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序: N2 d* Y6 c. J2 ^1 ~1 ?
8 O+ e, @+ s! S& z8 V7 D名字取MEI_UseCsharpCom,点完成' t. Q# Y9 K* Y3 d& G" g4 W
: ]0 X1 H @2 K6 ^ H
把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.5 B+ D; o( d3 z3 t# q
. U( S1 D7 v+ Y. l8 @
我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
' w2 I8 ]& m: x- e3 q2 H- ]$ \9 I4 d
& ]+ R& Z) E" n7 ~3 B
#include "stdafx.h"
/ p8 H1 @$ J) s w#include <windows.h>
, J) Z$ t o) t% Y& R6 F#include <string.h>
* _6 j2 m- v# s# g/ V
7 X+ a% k! f; f2 r#import "MEI_AddCom.tlb" named_guids raw_interfaces_only) U6 W/ q% y5 [; t6 F% p. r
' l: _+ T& z" b3 `& J- o
char* WcharToChar(const wchar_t* wp) //wchar_t转char*
/ v9 J) X4 T8 P{ " F% `4 _8 X1 r& p4 W
char *m_char;% U7 J6 F& n7 f9 s/ w& R# G
int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); ( ]1 J! b5 @& M7 i
m_char=new char[len+1];
2 T1 p( H5 j2 ^' Z0 T7 o& p; M9 q WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
8 D8 P5 D& j5 {$ ^; o m_char[len]='\0'; ' T( V3 j4 a7 [0 ]1 i9 C4 @
return m_char; 7 e) v8 b) {; n) [; Z; O3 h
}
) _3 \/ T4 i9 X# Lwchar_t* CharToWchar(const char* c) //char*转wchar_t/ Q! x% P; o' o+ E
{
# j$ N& M# J$ f; I1 A wchar_t *m_wchar; x# W! k M/ C4 g4 P1 g @# w
int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); ! B# i: {% B9 \6 i2 O' l7 o
m_wchar=new wchar_t[len+1]; # K4 d1 b9 g9 P; l4 @* n) a4 d& \' y
MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); . y; I5 ? _! q
m_wchar[len]='\0';
0 F% n- @) X) } return m_wchar; 9 m C2 W. ~; p' t! N
} * l% |9 N0 r9 l' l/ T9 @8 g
8 ~) X% Y: C# {void _tmain(int argc, _TCHAR* argv[])
$ H- j \; k/ z9 k/ k7 I+ B. f( Y/ F+ l; c0 }# R& E
{2 C0 z" y2 p4 \' p6 X; @1 z
& U _" f- q' o& N
CoInitialize(NULL);
1 }: ^. D" _8 U2 N* @* i' D6 Z, }' p% h
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
, C/ w6 `/ D, n; U% b4 o
3 V" H5 ~1 Z/ d' ^2 ]# ~- y% W9 { ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
* ]- e* _5 r+ I' G) w- G1 U6 L4 f
# ]# y/ V! T7 X/ F+ ?+ f //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
/ L# q/ Z$ D; {' y
0 Y# t* h$ m& _5 P( K //来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
4 {7 e7 T" A1 T# @$ |- r4 J //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
- U) w. A) Y! I! T0 i1 e- [' g) b- {. r2 R
long a = 1;7 d7 Q0 D. _6 o" s3 z% W
/ Y: {) l$ K- ?
long * lPtr = &a;
' L( d' G: U2 \5 O! W- j
% f3 L9 c( D6 u; X ptr->Plus(1,2,lPtr);2 Y; N1 H+ O5 W5 g
. F5 P4 B6 K6 b" | x1 z# U+ ]) L4 q8 U
char msg[132]="";
* `& O* i4 x% V; \1 N( ?5 h" ~5 c sprintf(msg, "%d",lPtr[0]);
; |7 h- {1 Z* x3 i) N6 R) m: x. t; ]) ^* C* r& ~$ R2 i; i
LPCWSTR str=CharToWchar(msg);7 n r0 U4 l1 l
7 c. b% x5 Y( g- Y7 I
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
8 _8 M2 L L+ F( E! l7 l8 [; }: a0 B! A1 i# f+ i
% [; ] S4 p5 N% F6 R
}
. T2 b9 e% j& Z. w
P+ m0 u7 x/ \* p此时就可以正确运行了.得到结果3
$ P" ]8 Q& ~2 a
1 \, _4 i, Y6 p! f如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
, @, T# R1 R, I& c- a- H& A# t, E( ~/ g/ r1 e( C% Y
1 d* S: e: Q# I! Z! \0 e- D
--------------------------------------------------------------
2 m b4 `3 u, q! [/ n8 U* f5 } {C# Npoi库 操作excel 的代码网上很多
; ]& |0 F# }9 r% `
# s( x# \% Z! K6 L// ----------------------------------------------------------------------
, `) W7 `8 O, [- c! [0 u" U1 V4 A// 使用Npoi创建一个简单的xls文件,写内容- Y* T# i1 I% y! p6 x' s; O
( h3 D j. E* D' f
using System;% u3 @6 N6 u/ q5 x3 [) i
using System.Collections.Generic;4 a X1 t8 ?% c. J" D( P
using System.Linq;
* F0 y, |8 |% }using System.Text;
$ e' V: i2 _/ w4 Busing NPOI.SS.UserModel;1 w' F. C5 Z5 n) Q
using NPOI.XSSF.UserModel;
6 ]. ~! y5 X0 N& X" A. d( ousing NPOI.HSSF.UserModel;6 c( @$ c+ [* a6 Y7 H, f
using System.IO;. u1 `: H6 t, f* {" Y4 a- l+ q$ J1 y
using System.Data;
% R- |! b8 t+ Z7 O( h4 q6 J* c6 B& I# ]" _' b" a5 ? c
//using System.Windows.Forms;
" p1 M9 S7 x4 y4 O
- H o% n: |* k; c! snamespace CC! p7 s' D: |7 W+ B+ R" T8 E2 y
{
9 c' u6 o) v# l1 k5 O" [
0 t# m5 c4 [- p* W6 \: } class Program. v/ y5 U: D, E( y8 w" \
{
' o9 w* I* o( Z0 \" O- C; q
& c3 D0 r+ \& e1 F- I
+ ]& `- W+ y. u. E7 L7 } static void Main(string[] args)- G _& w- V0 k! ?* V% _. w* Q
{
# M5 S) d+ u7 v; K; N4 P& ~ //创建工作薄
1 U3 z* w9 H, C" z: j HSSFWorkbook wk = new HSSFWorkbook();
! a# y! ?! W9 f //创建一个名称为mySheet的表: o, o) ~5 \7 f. l0 A( P: U
ISheet tb = wk.CreateSheet("mySheet");
. u! M; g& D! l( p: ~- Z8 [ //创建一行,此行为第二行0 j* b, T' `, _0 `$ n& o; O
IRow row = tb.CreateRow(1);! L! M+ W8 k8 c$ k+ s& h; H
for (int i = 0; i < 20; i++)1 u/ G7 l2 ^3 D& y1 K8 a
{
+ b4 A) t0 v$ E3 B" z6 x ICell cell = row.CreateCell(i); //在第二行中创建单元格
' V0 q1 X# {: u& u) b cell.SetCellValue(i);//循环往第二行的单元格中添加数据7 S& }& k: {8 m8 m
}; v& g( _9 D! h q0 i& n
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!" Z9 u1 X, }2 \+ M4 c3 J* W
{
) J3 @9 }+ H! D; b7 H$ G$ F' C0 ] wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
6 P; d: E! e0 r- y) ~+ o' W+ J // MessageBox.Show("提示:创建成功!");. x. u4 D; S8 A7 e# P2 A
}
6 o" w0 T: J2 R& y* ^( j9 ~. Z# _. K( C
}
, P6 ]! ]. _$ Y7 D* g; C# d8 O7 m! h+ m
( z I* P! f2 u! L/ e
}1 e8 B2 F. D8 v ]
$ O X4 \) ?7 [+ S( w% o8 R; W. E3 b+ l, m& c) z6 t0 D
" i/ P) a P6 e9 R. Y
}
/ Q9 k* T3 X$ O. r$ ^( b+ ]) a" }6 j O1 `1 h9 a# J E7 a
// ----------------------------------------------------------------------
% H- d, c# L; f; ~% J// 使用Npoi读一个简单的xls文件
& x9 C9 l0 e1 w5 x. S4 ^- h! ~$ ~1 }/ O6 |
using System;# Z: i$ l8 S* B* N5 d% t& M7 [
using System.Collections.Generic;
3 e5 B# A, W5 ~& Rusing System.Linq;
0 _" Z9 O: z( e" |3 l+ T9 N( w$ Lusing System.Text;: K: s3 W9 r8 x$ Q3 Y
using NPOI.SS.UserModel;) I( X/ O, q/ l9 L! R+ h
using NPOI.XSSF.UserModel;
6 l1 x* A3 ]+ u, `% \& R, Dusing NPOI.HSSF.UserModel;( ~; x' @; T7 D
using System.IO;
6 `4 W/ e) d4 X2 O& n& p$ j; susing System.Data;
, m- R% W0 t7 R- @9 H8 v
B9 X" y3 H2 ` m: |4 Snamespace CC
# `6 l% b) b' D{
) s# k' P1 T( S' f1 |; \
$ V2 g4 W J) l6 @* O class Program
l' j3 }" e, B: N9 R5 j {
. u* y8 h. v9 }. D9 E9 j' Y3 Z4 [
( v! c( v A9 j8 @ static void Main(string[] args)% R; Q3 z2 l" t7 y8 }$ T
{
9 H R' A( g& M/ A6 _1 x8 N; G4 ~ StringBuilder sbr = new StringBuilder();- U6 r: \' \. f- A, o% s
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
" m& i; T- G R/ x* y# r {5 H- g4 B; B3 ^8 C/ Y
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
3 H" ?/ Z: _ e, a for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
5 d& u7 h& u1 R8 J3 x) S {0 ]& A' `' v' _) \/ |5 I; d) q; o3 A
ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
) K2 z$ G1 h# l" z: p9 w7 C5 u5 R& u: b for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
1 Q% ?! @2 ^( E6 ` {
1 o3 u# B, B. B( J. M IRow row = sheet.GetRow(j); //读取当前行数据- T$ I0 a8 a+ V" G. d
if (row != null): W! N* _) O, u4 S6 ^/ V
{
- g' Q( _/ S8 W- y9 Z sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限+ Q- K3 g2 D5 D0 W# Z# ~, m
for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
$ L, i" Q( R% s" }0 c {
& n& C$ X" L+ r& \- y* T2 Y ICell cell = row.GetCell(k); //当前表格$ L" t* G/ O B/ C
if (cell != null)
, B2 x( z8 P+ W3 R2 u) J {
) k" w# E8 w U3 @) L9 p' q9 y sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型* F; @) X6 r N, Y2 I& I
}
7 E5 P) i) E1 Z. ]" y }& t' w* c+ L8 z. f; E% K, c4 O
}
9 x4 |4 J7 G7 K0 M Q" j+ O }
" v m7 g. ]) f }
4 C% O* c7 B* ^- w) b }
2 p K% R: u9 D) K$ V- K, N sbr.ToString();1 G+ B. A% Y, v: ?2 e
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中6 T( T' ~) D' ?
{" K3 b1 a' I0 y/ n/ d9 G
wr.Write(sbr.ToString());1 }) h7 h6 C' O }
wr.Flush();* L' Z4 v9 P8 j+ D; ~
}
) h. r: X6 ?" J9 Y$ E: W
% w$ A) K( [; J- N0 |2 C1 i
" q; E! Z7 L6 C6 | }
5 _3 Y: s- n* _' Q4 c$ H8 }' ~5 ?4 y6 w; P8 J1 e
9 I1 o9 C7 q& s8 ^, t }
+ X5 a1 S; |% k" Y4 }9 x
- I8 v( d, }: l& W7 q8 n1 [0 H) s* m! v, i4 ~% F
: ~9 X* }' f8 L; `$ }9 a* S
}
: e0 }; e& B# T |* _2 o: q; G" ^
6 @; L$ M8 P2 d6 D) h& e C l+ u! f; _/ F+ S
然后 自己封装 给 c++用
6 }7 B; a1 B( _, x9 H: K
9 l4 F/ n4 e3 i2 p* `( t. B7 B6 }* R3 R8 B- Q* } U6 K5 ?
; X# t- L8 y2 D9 g
9 g, a2 t# f& V A: b& x! ~% W( x* ^+ S$ l, W3 o1 @5 T
. T0 z6 t6 A: z
6 T3 {. R/ G# h/ r/ F% @
: b" g4 p& t/ q: i$ n
$ }; q T. k N" }2 J& t# g
3 c) i, S, I% F, ?' A/ o! @7 R2 P+ J0 X# s0 ?$ W
# N8 ]% q& k1 g2 w
% W# R; S8 G" Y
* Y7 {; s# Y" [; ~: W, s0 L# I. W
4 c' O# ^: R! E( s5 s0 z r5 d% C4 h
: J- P% l) ]( s w9 W- Z: H; K) ^8 D8 {( r& b% ]
" k: R0 G( u, O/ w7 ]
6 e& L( A. T/ d+ Y+ p. @+ \1 L9 K# V0 O6 M, U
% T& e1 K. ]* ]
1 U( G3 ?( `' a6 B6 K2 B
0 W( m; U7 J/ z7 z* R& D7 @
|
|