|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
3 x" v i! ?7 F* H! xnet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)
$ t, c* }9 p2 s6 z2 z# u这里我用c# 生成 com 组件 让 c++ 调
% q7 `6 H9 d4 ]" O& {
" B/ p/ Q+ z( T9 j8 s* A首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)9 ?) z9 y- A( d2 B( ?. `
C++调用C#的COM组件(DLL)* i B6 K3 z. _8 W" t, N
+ h$ }+ m- }& l8 ^/ J2 g# A& R
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
2 I3 ]" v; [6 Y3 y; _4 [首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
* y. Z6 u, B; N% _5 \# b: l) u/ a$ z8 ^* V1 ^) h
( C7 o2 {% M$ u; V4 @! a8 h1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom
) g2 h0 g; o0 d, H% u0 a9 K- O
U' ^9 V& {0 a0 x2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数4 \# r' m$ |3 J& a) ?
5 a1 a* V( S7 {4 n3 |6 E0 s- G
具体代码:1 s1 I* Q8 s6 l( L! K2 Q, O
( |. Z3 }: m! ?: z" g) jusing System.Runtime.InteropServices; //记得加这个命名空间
# `; ]: Z, M, j- @- v- Q3 X; d$ \
namespace MEI_AddCom
- O, D# j% V2 l6 `' b* \$ w8 _% P) N! ]
{4 @# \$ a- w: [
: @1 l+ w# r8 I$ c h [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.% w0 t. ?1 a& D
1 s5 s j. K! v5 x5 q
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
V% \- o2 ~9 _' Z2 X* I9 E4 D! h) V. a; {9 K+ R7 g
[ComVisible(true)]
2 F! L% Y* j! S. W: K. S0 n* F2 m3 b' H' H& e a4 L3 Y; B
public interface MEI_COM //记得用修饰符public( F" m5 @! s7 D _: ^
4 N9 e1 u. b! e2 Z
{
$ a$ Y6 [% q* w% u$ E1 Y E# ]9 e+ O" N& N9 |) Z: i! \4 o
[DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面8 @$ Z! ?4 a! b) q- R; P
! M: h/ {$ H# O' a' |6 [( o: w7 j+ K' R
int Plus(int one, int two);: J/ a7 N9 {7 H# s9 J5 _3 v8 C
/ I' S& t* S3 u) }1 K }$ m y3 D- i W9 v0 q- `
1 X1 G P; U" q. H}
/ j$ U+ Y3 u4 R! d+ \% M* E
+ X J' N2 e1 Q4 l0 ^3 [+ L& B" Y6 a! M
$ h# R' J/ m M) |2 T+ M) U3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码$ D9 M& V4 Z/ W6 I
( ~% v& x$ a* g* }6 d; ]8 Dusing System.Runtime.InteropServices;
; e: G8 G2 \/ r! h8 k0 ]5 {6 @0 \ X3 I
namespace MEI_AddCom
7 r& r8 @) G% D
, y( X9 P& f0 Q) V% T2 b" C{/ y+ Z. v" z8 N( z+ h, V
# H" H) z- {9 [) F
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]3 i' N) ~) H- k! y! c: b
& i5 E! D/ [ Z- D# `7 C/ i. r
[ClassInterface(ClassInterfaceType.None)]1 t0 s' ^$ \/ |; L
+ h. y3 g P; K9 d C public class MEI_COM_T : MEI_COM
# N. Z/ C4 ~- {0 r# J1 l& C
5 K: H8 B- _# M/ i2 B {
( \7 x* ?$ v" M; ~# u9 K7 ^& a) y y# S. T5 k( h d
public int Plus(int a, int b)
2 I" j# C2 H% O% q6 {8 j3 o1 i% H6 g( {: v: z0 D7 }' U
{
' b. U2 W! v" R% K
2 l, J' J! d, r: a$ a return a + b ;
! e$ p9 y" i0 I1 h
" K( ^% M* B% z# y: I7 L }
8 {. d* C, f4 y8 I! N" y4 x
( q+ B1 d! v( A; j$ Q, D& p }+ G4 \5 O3 o& D+ [+ Z
, x" m6 O! n$ o1 ` w4 w
}
; ^! |( p' x1 |' _. n+ g z2 O( x- L4 p# }# h9 ^4 m
! }' }$ Y, h% A4 t+ \; O. R1 Y9 T! y( d, |7 L3 l% |% a' h
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].- }0 p9 {; T# W% B# ]
, I2 ~% { `6 M! x. k! r右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册6 z* r- O! Z5 S" e6 F& A
+ d& T2 L0 v* G" k$ _) r
$ K% a& ~$ t6 t. L
5. 生成->生成解决方案
, z H1 W) U) v4 x6 h8 W! w6 U 注意 这个时候 生成 非常缓慢 ) D( C) M4 N6 c( }: M, ?* C
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容8 A: A V w! E+ L" h) E5 l
; o8 Y& }3 t4 \ z/ |4 P/ m
( l P3 U/ ^1 B% n, N; ?---------------------------; r) W' [# t, r
# U/ U( Q$ ?; T
1.调用前要先把com组件注册才行.9 V8 o, u9 k, P: W
: a7 w2 V+ {# e' V/ t8 g: [
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
0 Z& N9 [4 D8 x以下说明如何通过C# 注册、注销COM组件。
* l3 Q% L3 i: q" L0 d; h& ]4 t1 {4 \' @7 C5 g+ e/ U/ y( O
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
" h+ l* I4 W! S* S" S打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。! ]7 R" v: |, ~2 U
创建完成后COMLib项目中将出现后缀为.snk的签名文件。
( F. T# L+ y' l7 r: j6 }7 H最后,编译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文件。
. `: E$ z: Q/ M6 Y3 J m9 A卸载COM组件:
3 E9 W6 h& |2 u$ R( [与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
' f* H9 R) m5 G5 Q; k: l; e. ~- U1 d+ o
; V( @) V0 e& W' Y0 Q# j9 @/ ]
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序+ {' ~+ r# R6 \, ^# L/ `
2 S2 l8 \% C. W1 S- c; v
名字取MEI_UseCsharpCom,点完成& W" Y8 L" I$ W, T9 ~
( j+ C0 [0 ] \+ v9 i% w$ y" C把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.
1 p$ ? f; _5 B# j4 t8 h% t( g" j
我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:, T a$ e; A2 r' k5 J
: Z* c, S+ |' p) x a$ I F; _: @
, X; F8 b- `7 o; Y0 p' ]
#include "stdafx.h"/ o4 {: f5 F9 \
#include <windows.h>
& h8 P/ ~: O9 x0 o#include <string.h>
7 N& l$ F# s) N) f( I8 W
( @. |3 K7 N- {6 I$ q#import "MEI_AddCom.tlb" named_guids raw_interfaces_only# o- G9 w' a1 A3 Y B" R4 K" y
' z+ F$ [) `2 Y0 Y2 Lchar* WcharToChar(const wchar_t* wp) //wchar_t转char*
3 E2 i5 U4 `8 ^" s1 }" ?: N, H{ ! i; U8 d" z6 t. B4 |! e4 V
char *m_char;
5 l; d4 `- B" [& J3 M int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); * H2 g L) r* V
m_char=new char[len+1];
" j( ^6 `3 W* e& U# T$ G WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); ' P( y/ |8 z7 N& B5 b
m_char[len]='\0';
7 D4 J2 E5 ^0 j& [ return m_char; . T0 m" ]0 d) ]3 O& O1 |& k
}
3 Q# R( Q2 g1 d' l( kwchar_t* CharToWchar(const char* c) //char*转wchar_t
$ Z4 J3 B* d, Z7 p{
* ^: c7 C; u7 @4 p6 Q wchar_t *m_wchar;
8 Y& ?4 a1 t1 Q& P5 W x! V int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); ; D0 Q" A8 d+ F$ N: ~! B- f% r! O
m_wchar=new wchar_t[len+1];
; n; U9 y: {5 U: K; | MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); + Z ]: R8 m, y; t/ z
m_wchar[len]='\0'; ' E! l! h( X* F+ h A0 ]: D9 Z& X
return m_wchar;
, D `( D' Y. t4 f}
0 Q7 e7 m; Y5 W& |+ i& ]
4 A i" s; ^0 C5 ]) o avoid _tmain(int argc, _TCHAR* argv[])
4 P }* Y1 A6 F) W7 d6 S
% V5 H9 {# i) [{, d/ z( @4 S# g' ~3 f' t/ P. U
4 ?( f& @2 t, W5 K; ~& Q CoInitialize(NULL);* o! _. [( y3 E/ G3 i6 N
, k: x0 m8 s" B+ [ X, t2 }& y/ C MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
5 Z/ O! V: v# K
+ P9 O' C1 {- A/ P7 _$ f ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名# t) }" L6 x: j, L4 H$ U1 A
! G$ Q% C6 x, h4 T8 W- `
//这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
. t, }& v- s- k+ U# S% v1 e# O( C/ M0 w/ J! ~6 `% v; b
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
6 {/ e! v; H: G! U //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
0 H0 p6 Y' N* X; _! j7 ~, b% q. f+ ]$ c: g( F
long a = 1;
2 b8 X& W2 K S" C/ x. E6 z" r
5 C8 Q* h5 E9 l% G$ `# x long * lPtr = &a; q5 V4 L% a, X! N" m; g
7 q4 g8 g$ G0 g8 H$ b8 s( ]$ ?" D' u6 h ptr->Plus(1,2,lPtr);# H6 U& X1 c2 S% w* A9 Q+ _# ]
7 {$ h; F* W) O2 U
char msg[132]="";2 c( g" r8 C8 F* Y2 D" s) {
sprintf(msg, "%d",lPtr[0]);: d* t. G9 ~' s+ c% Y6 U& J! X; p
4 t+ w B5 n3 e2 z+ C LPCWSTR str=CharToWchar(msg);: m+ S8 \- F$ T6 j3 b9 @: |% r
3 `8 M, i3 j3 u8 e( y2 B
MessageBox(NULL,str,_T("123"),MB_ICONWARNING);: l- q* y4 S4 t# ]& v# p( @
- s6 z/ G) a' l% _0 M
1 e2 b/ h) q+ P7 H9 j( V. F
}) e) J- B% o6 l& ]0 U7 f
" K( S! p! H' V) A( _$ y
此时就可以正确运行了.得到结果3
: X; |/ @" G+ n0 B, s1 s* B5 T% Y, \% J) t
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
/ E6 K6 l' ^& Y5 x0 M, q% Q( U) S
) `: f0 |0 k. G2 Z% @) p- ?! ~7 K7 P0 [* `* s8 J
--------------------------------------------------------------1 G6 G7 `! z* ~8 K$ d0 A+ M
C# Npoi库 操作excel 的代码网上很多* V- Y R6 K/ D& z6 [+ F% T
5 K4 }) q" T0 z$ H7 e
// ----------------------------------------------------------------------' L8 [) h& h5 b8 W& {' L( X
// 使用Npoi创建一个简单的xls文件,写内容
. t" b: m5 J1 C7 k) |$ M' ^- z
/ g: e5 ` Y5 d% D4 k0 rusing System;( `* |% F2 @9 n+ H
using System.Collections.Generic; t: M6 r5 T, `& e: Y+ r
using System.Linq;
" i: Y. p8 A: e0 d! _. n% Tusing System.Text;( }7 G8 b) j6 X; V0 j$ A+ K
using NPOI.SS.UserModel;% w9 x1 R+ i( Y" v# c
using NPOI.XSSF.UserModel;
' t+ s% J: ?5 S+ r$ N9 uusing NPOI.HSSF.UserModel;
3 u2 i1 c; b, v; q: ^! p: i! {using System.IO;
: V' T B+ a4 j, y# [using System.Data;( c9 i8 m+ i( @7 v7 s h# ~
& d9 q) k# S: y4 W$ y
//using System.Windows.Forms; / N* p0 V) o6 E+ C9 k8 z' I/ Z0 P" f5 c
. ]; h: Q3 q7 {$ p, U" Xnamespace CC5 f; m9 [0 ]/ A" \
{5 _7 L, S6 @- u, h9 Y4 Z8 a2 o
* e. N- V; u' U
class Program7 ^. H# N% S- {9 c' r5 ]% b
{
; d6 u$ D' f2 a7 ?5 z$ u* p* n
& n! W; [1 h' J0 U- v. G1 L
4 r7 m. U5 u1 `6 j static void Main(string[] args)
6 I n* G$ n2 v/ E, Z {
2 r" v( w1 h6 q2 x4 l //创建工作薄8 A7 B! E$ J; [+ j( T
HSSFWorkbook wk = new HSSFWorkbook();, P9 _; _. O& h2 S2 f
//创建一个名称为mySheet的表, z; v+ ]/ P. p+ Y; o% v' ?1 c5 [
ISheet tb = wk.CreateSheet("mySheet");" a2 Z& x; h3 l5 c8 C
//创建一行,此行为第二行* \* R" S% @2 P N4 ^9 |
IRow row = tb.CreateRow(1);1 ?! s) ~8 e2 e+ S+ O' O
for (int i = 0; i < 20; i++)
* y o) T! K3 w {
4 h! L- E( v; w% n& B8 J0 J ICell cell = row.CreateCell(i); //在第二行中创建单元格: O; r8 u. j) S' Q$ Q
cell.SetCellValue(i);//循环往第二行的单元格中添加数据7 g6 F" ]0 W/ `9 I
}
( @ ~: F+ P% G0 R using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!7 z+ h; G% a" x( S- d+ m- y
{
% i& a! ]! j$ ]" N$ _ wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。& y+ r: K0 W5 r: V
// MessageBox.Show("提示:创建成功!");0 @2 L9 o5 y- }: S
}
7 A" _/ x! f a$ S6 z( q3 i2 P: E
7 H0 D) m2 j+ q: N }
$ E1 i! c7 Q3 K' E* Y
+ h6 {4 n5 n! o$ N& k, x. s& F4 J# r1 A) h
}7 H: E# R! C5 g5 e
J S( L6 [& f. P* O1 q& S
' d0 b* g4 _2 y$ o0 u1 i5 y) k$ n/ G9 m5 U+ X0 K# j7 I
}
, G! I7 u u# v6 [8 s5 U0 I1 r: l, Z* C. m
// ----------------------------------------------------------------------
! I0 a9 F5 x3 W4 ?! N6 w, n// 使用Npoi读一个简单的xls文件
6 l& H( I. N! S
: L' ~2 P2 c7 ^! Iusing System;
A5 r( w. P2 Uusing System.Collections.Generic;8 w# h- d2 F! w# n. o0 o! v
using System.Linq;- j; V f) A4 V. x9 }2 }
using System.Text;+ w6 D' K$ n7 c
using NPOI.SS.UserModel;
% m( } p0 Z3 _3 ?+ Z+ y5 Z, T0 w9 susing NPOI.XSSF.UserModel;
4 G. z+ Z+ J$ A& Qusing NPOI.HSSF.UserModel;2 p r# R$ c, r
using System.IO;
/ b9 M% q: @1 a. X9 yusing System.Data;
0 v. z/ t+ W, r
, S8 Q# R% B" |3 J2 ?namespace CC9 v) N6 g! u+ w5 d+ y0 w$ I2 x6 [
{
& N" C; N/ ^5 _9 q! b- r2 s* |2 H. A1 W
class Program& H2 S0 G# e! g* d- y
{
/ }( t7 q+ K9 K6 d
) }4 s8 _ f8 a, e, W' L. I/ h6 l, r( G- E) W/ C: L$ n) y
static void Main(string[] args)
5 i( a- g: O( A3 D5 ~7 q {
+ B$ Q" t3 \9 C& W B# a StringBuilder sbr = new StringBuilder();
; M9 X; I7 j2 u using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件/ ^# e# {: x+ E0 o* E
{$ T- Z! ~9 K; w0 G. m
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中) @9 T U$ H5 D4 |$ D
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数3 D! p7 e/ n6 V, }
{
6 H V' x" \- N+ Y. b ISheet sheet = wk.GetSheetAt(i); //读取当前表数据' L1 R0 _) K# k8 h+ ?
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
. l8 G2 o" W/ O3 Z2 b- w! Q$ W; [ {) T" L A! e( x1 E
IRow row = sheet.GetRow(j); //读取当前行数据
, `! y; W+ \( G: [7 J if (row != null)
% {- a( w( k: V$ z3 E% K8 Z7 [ {+ A3 T% a6 Y4 p* B$ V& W
sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
3 K; Q; n4 k' `& P& Y9 x for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数1 ^3 u, Z! U3 m' [& g6 R* {9 t
{
8 k. B+ o( E2 X* U' O6 ] ICell cell = row.GetCell(k); //当前表格" C2 O' b9 l7 l/ ^3 A) `7 U/ Q' r
if (cell != null)
) K6 \! b# w) |" T {
- j3 Q4 b$ f( {# g2 ]9 j sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型
: l) n# r7 t! ^4 P* T( x; I }; E0 } y D) W I/ w7 B4 N
}
! C0 N9 Z+ L [7 a, W% H }( J7 \$ y9 z$ h8 K0 {( E
}8 h* F! k+ ]: u1 F( V. |
}8 i8 m$ M$ U! M% M2 a% U* m
}/ D5 o2 U7 ^! P6 f& t! }7 Y: t
sbr.ToString();
3 G# L% a6 g: I( T- O using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中" Z0 A4 ~5 H2 o; o* c
{
7 Q8 ?. Z+ R8 M& U wr.Write(sbr.ToString());8 H1 p7 H$ F8 ~: n
wr.Flush();
; w& }; z6 L( u7 A4 c- K. a }
; ^) [2 P/ W( k
1 F L- O5 g1 t! A c/ p4 b2 }! @" L
}
! }* W, `1 m) t; d/ a6 T3 G4 [4 K; n6 n
6 t0 \' h3 Y0 H: G+ S& j; n3 Q }4 E4 G2 k8 w2 u! \. H- x0 O. i4 }
$ e! M3 d2 f, J! }$ |" K
* s& ?! z4 `8 z9 n+ x
5 @. B1 n1 n$ b8 G5 l, N
}3 E v. g' O2 q
! x" N9 z& T7 t0 c; m# L: `
# Q6 U+ r2 ]5 j* w0 E0 M% C! h然后 自己封装 给 c++用
. [2 @# A2 m8 h6 l% m' q/ o
1 R/ O, i+ V! C8 ~+ W+ B7 _+ A |, U" o- N6 ]) G3 u. I
" l; J/ T) f5 x+ a$ K# \/ k+ |5 H* _( ^* G: J. I
. T$ Y, t2 x2 ~! ]1 G# S; S9 G
; ]6 R7 w. {, Z5 O) w# Y l" H# h4 O/ U
5 @: J/ ~+ T0 c D2 x
4 s2 m3 T8 \, X0 @" {- Y
& t) W! w' ?# ?) s. C
4 Y# G2 }' S$ n% g- `$ G* D$ B8 n" K3 t ]" x- _
2 U# r) @3 l2 ~/ W1 o. O, n! m
) y! _1 g/ I% X6 ?3 ?* N6 q6 }' f: ]) c4 w* [! d& D$ l8 U" ]% z a
& }6 U1 D6 r1 S2 Y
& M4 Y# O( G, B9 f( U% A5 t: Y; Z% E2 R5 R
! j8 r, F: ^6 W, W
8 F" k5 ~# X. X: T
' ~! @1 F3 N& d
% T c9 K) Q1 b8 h' a1 ]. R+ r- d3 Q* ]4 d& o8 Z1 Q h! Y
|
|