|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢) N5 D! ?' R; ^" M
net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)8 y/ a, W$ `" D$ _8 w1 S
这里我用c# 生成 com 组件 让 c++ 调
8 e+ k3 i% f' E- L& P8 u p4 l4 d8 |8 j8 D
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)
4 U+ ?$ n/ S2 z0 q* YC++调用C#的COM组件(DLL)* D0 \! c$ S( j% m
# ]# ?3 ?' e" F% [6 D下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
- g" f. c! f2 k% F4 W6 o首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和." w0 K6 F4 ^9 }9 D$ |+ N) Z3 _
O7 L; u; M" ~5 Z
) n8 M* F$ t0 A7 i3 a
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom0 {4 |, O- L( J( G- K/ V( R. m4 b" Y
+ O0 c/ N( C3 b: j- J- m( Z
2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
8 P9 y0 ~, S& @* U* ~! C8 y
" }8 `. a' D9 z0 \' P! ~! K具体代码:- w) F! J( k1 {, p% D1 n# r8 ?
* C6 X$ y( t: f+ i1 ]1 L9 Ausing System.Runtime.InteropServices; //记得加这个命名空间; D/ I# L) S- c2 T0 j
, I! v7 @5 `) x, D+ c" {namespace MEI_AddCom7 \' Z. V4 d# m2 i7 z$ G. C8 Z
8 L' K4 }1 V4 L5 @+ U{
2 T6 `$ q- S0 {& h3 n+ | y5 {4 k, _" R) \0 q/ g3 Y
[Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.) e7 _0 _, }# }. h# f6 d, R: T6 V
; i8 h, i2 k! t$ M m; B1 o: X //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生. S% t) m. S6 e' V; Z
9 e. K& l+ n1 N/ u( _% G [ComVisible(true)]9 d0 Z: N# f7 U; R/ K
( P h& y# v& R: f L1 c5 b
public interface MEI_COM //记得用修饰符public
, Q0 z$ \; l6 E9 _/ \! r" C
/ e8 z9 q+ U+ c# q5 z& ~4 ~) a5 O {
. `: g! P1 L( W7 C+ r4 _+ F( q# p- a
, c; w5 ]$ D& q/ a- W [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面' M* x9 Q0 b2 @# J# U; P
& n" L4 Z" @6 y! P0 `6 v
int Plus(int one, int two);
* s* [( b6 H! t+ O0 }; U( W) y+ P5 A- F$ `5 h
}. M% {. Q0 w0 F" u4 F$ {: j2 E2 g
$ F2 W8 E) J4 V- F" m( R}2 q4 W: K7 W) o0 f
; x/ e% F. f W( Y
# p% P, j. p w: h4 J9 M6 x
$ O4 s, O7 m% E7 Z. [- _9 F* E! B3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码
( X3 |6 ^& W# V/ y
5 D/ s# f S# Z+ U/ e* x5 i; dusing System.Runtime.InteropServices;" z: ?) ~+ ?$ F p7 u4 {# s6 Y
+ |6 }1 A! M& v- h
namespace MEI_AddCom
. k' s1 s: N! t# N$ n2 l9 C3 ^% g
+ L. R0 ]0 s V6 l; S, J{
! B% r& X% }$ J6 f3 ?& j8 `% d) ~7 F% Z4 _: f
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]
+ z' m0 _0 N- h @4 J( y% z5 p# k/ S1 ^/ i; u; c8 m* I7 ~ t) l, m D
[ClassInterface(ClassInterfaceType.None)]
/ C i \1 T5 V( i% q) B" b' b; p
0 D0 y7 k P# o E5 Q public class MEI_COM_T : MEI_COM6 t5 v- s9 b# \
F8 @' Y4 r# a+ i; O {
2 N& g9 r, _# V( n5 V
, W/ w! R1 D, Q9 z public int Plus(int a, int b)
3 } E1 X1 T9 ?9 p0 s e1 s2 }9 k
{
3 u: V: o+ G; W1 D. ?
1 ^8 |% B0 m' N, |& X) b: [% f return a + b ;& A) m5 d7 Z, A! F% @
* K" e" V8 U: T( i: { }, `, f0 Q: M/ ]% v* g
( [( P1 `, @+ L: X4 C9 C7 z+ M+ D/ k }/ i3 R& Z6 i" I
7 b& m% d0 l' c6 U
}
3 P4 a3 \0 \6 S+ h0 s+ I
8 j [, }% _, @; n! o+ ^/ k" n
4 n3 ]5 Y) Q4 n% H7 D" J& U
$ ]7 f( b& X+ c9 N& p4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].
% j2 M1 ~, t& } Z5 b/ n3 A
: n$ w6 r4 d( x$ I8 [) f- ?右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册
; l, J4 y3 R2 o: D+ L! _0 ]7 W k
* ^: @5 C5 E8 z. `1 S6 K% }2 K
5 b/ |* `9 ~: o2 F9 T3 [! C1 ]# [ I5. 生成->生成解决方案0 c9 a/ Y! _5 V4 k& J3 u K
注意 这个时候 生成 非常缓慢
# g5 L4 m t* A7 S. l% L 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
/ W" c9 _% Z& ]# U5 c
, x7 E8 r' l3 M0 n+ L
* J I4 h0 V4 a( \2 ]5 u---------------------------
+ t6 ^' u7 A; a6 y+ N9 t3 v0 _; j" Y) Y" r p5 Q# {$ e
1.调用前要先把com组件注册才行.9 _: H, W9 ~8 t6 s4 F
9 I, w. v# x3 c. M
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。: I7 H A! y& ~+ @/ e( V" g
以下说明如何通过C# 注册、注销COM组件。
( l/ X# u+ Q3 {% D2 i1 Z1 Z7 n$ k" W
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
- h1 ] C' g% P# C! J打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。3 b# d& J' I3 c! f( d* Y
创建完成后COMLib项目中将出现后缀为.snk的签名文件。
/ Z1 @/ ~0 }! S5 T$ c) V' u; 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文件。
. { |3 _ Z2 Q$ ~' S3 _% [卸载COM组件: 2 ]% O( K/ i: K4 G1 Z5 i2 s7 ]7 h
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
) B6 c# p/ e: b$ P9 _, T6 T
) V+ T8 `2 P5 j0 s6 |2 q5 b$ { z2 o X8 n$ K; {
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序- c0 a# [6 ]3 E6 S8 ~+ x! x+ a& j
. t- C) \6 V w% b9 K) B$ M; P. B
名字取MEI_UseCsharpCom,点完成
7 u5 C! ]% N) k) e5 N( g2 d, z1 p P' C4 t; P
把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.
* W! M- P! Z) r' u3 ~, z7 S$ r) Y( `' {+ @8 h$ \% w0 V
我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:$ T6 {$ p5 q7 ^3 l/ I% M
4 k9 P4 z& I3 Y* T6 L9 m, Q$ j& H6 t
#include "stdafx.h"$ P7 d8 ~. q8 i/ C8 R6 I
#include <windows.h>" ^' K9 v# G) Z2 r, E1 X# O8 O5 V, F
#include <string.h>
+ l. H' E. j3 X8 z1 o2 {/ U. U* ]/ A* w
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
& e6 R# l0 s8 W/ I1 p( X
+ n g* Q/ a( q0 M p6 ^7 |char* WcharToChar(const wchar_t* wp) //wchar_t转char*
2 }) f; b* U/ K2 r& A8 f+ L3 q{
. f) X x3 ]& C9 f+ k char *m_char;
' G s+ h. q4 o- V; n, Q int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
. i; r" e6 u3 Q$ ^2 A. ? H. O: ] m_char=new char[len+1]; % K F$ H: l! g, g
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
/ s1 W$ @6 [6 o9 G8 c1 g) u m_char[len]='\0'; 5 b+ E% G+ ~% d: w; y% V/ ~; x2 Z
return m_char;
/ ^4 ]" m0 k9 T' ^}
1 A, f5 w) }- Owchar_t* CharToWchar(const char* c) //char*转wchar_t4 q n1 { C4 h; T/ q7 b5 q7 p' K
{
}0 i" S; G( l$ X! e wchar_t *m_wchar;
( }; o# n1 Z& h int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0);
' q* d9 w; B) @, K1 O8 r% D. G3 Y4 ] m_wchar=new wchar_t[len+1]; 0 X) B9 o2 \) Z! Y( s0 a
MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); 4 K+ o% j: m) r4 S
m_wchar[len]='\0'; $ r+ i6 P, u8 W& E. k
return m_wchar; ! j" c, W+ g% c! ]) Z9 X+ }& E
}
9 o7 |9 _ ^9 Z. b6 K& d- ~3 q: N: v
void _tmain(int argc, _TCHAR* argv[])
( @7 g& S( i. k" s0 J
+ I* Z$ \7 t* _# a( x/ w+ N F{
8 G% K R5 d: y2 N4 Y+ c) M( v
3 h9 ]8 B; h! e# {$ B& N CoInitialize(NULL);
* [9 Q1 e& Y" ]* X* [
f1 a. p; @! B* F MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针( g- r* [# e5 [
1 T8 f$ M# z6 u ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名. {' _) e. i2 m7 L4 W9 }" n
* t, Z" T4 Z1 v* L% m //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
5 [8 b& L+ |; m. |
/ Q- \% h+ L6 j/ {) @4 ] i //来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.; w1 @ Y9 g! M `; ]
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果* D0 W/ R) x. w# s0 v
1 C/ ~% g/ |) Z" ~6 a2 |7 {. S6 U
long a = 1;
8 b0 L1 x" P' d2 q, E* y6 P7 {9 `- h7 t9 q
long * lPtr = &a;
1 c4 v3 X+ Z Y5 W
J9 q/ @: x: ?/ e ptr->Plus(1,2,lPtr);+ Y1 R5 m: H" s2 J
; d9 M2 b; m8 u h* R8 R" F) Y8 T* |
char msg[132]="";# n! n) H" Z% V, d" @0 f& r1 S& z7 T2 ?5 v
sprintf(msg, "%d",lPtr[0]);( H9 ~ o( Z4 m* \# x H. N' z
; e7 Y/ k' p% H7 ~$ @1 @- x
LPCWSTR str=CharToWchar(msg);
' P u. P5 F: ~1 \* g$ B& Y' W
# H) ^- B* k" B# F! G* h: P1 ? MessageBox(NULL,str,_T("123"),MB_ICONWARNING);4 a; q; q. W* q6 X! F( [5 L
6 |+ `$ N: t$ R: l
) D2 S- i3 K: L6 @}0 P( @. G+ ~; a
0 _# k- Z, E, E* p, J
此时就可以正确运行了.得到结果38 H- T1 j6 S- N6 G6 s
% Z& N" j( y. n4 l. T
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
0 U8 ^! z) n, P0 b( A. S. l( M5 ^) h
' g0 o3 k, Y. b1 B% e$ S) k9 ^- F9 H; {5 D J
--------------------------------------------------------------
5 v. h9 i$ h$ C7 xC# Npoi库 操作excel 的代码网上很多9 c' U7 Y9 S* R4 j- [9 j
: r% |( l3 }& U l
// ----------------------------------------------------------------------' [% j) v* t' P8 g8 o0 y
// 使用Npoi创建一个简单的xls文件,写内容- u( d6 C. u* q$ F; z
0 C6 @' \9 C5 Z0 _9 M. \" h3 R! j
using System;3 u P9 \1 o: n6 Q% _! m( ]
using System.Collections.Generic;% O1 x9 U3 z9 w( n
using System.Linq;7 C4 J- w' A1 _
using System.Text;2 t, K9 R+ X4 Y" T9 X/ i
using NPOI.SS.UserModel;
' j, G. {) h: s7 }2 P. d' C# Wusing NPOI.XSSF.UserModel;+ J2 s4 x; W( A- r4 |0 N% c( p
using NPOI.HSSF.UserModel;6 ]+ k3 @4 w7 t. Y- V7 c9 `
using System.IO;9 B2 |' a1 l+ |
using System.Data;
3 D) p5 ]. I2 C' P. @; s
$ Q: n" U0 F- W8 y7 ?//using System.Windows.Forms; - `5 P4 A# g2 ?1 h3 ]
! K, ]7 `: u! A t5 ^6 [namespace CC
; X: G# D0 [7 t& f{- S% O2 y8 ^3 W* Q. b0 k- H
; H: h, ~; X7 g9 Z0 | class Program
( j7 j! S7 `3 k {* h, H% Y: M' A/ [
6 ]. I6 @( Z* B, I8 @% O% N( x: B# |. Y Y& l; J8 `0 ^
static void Main(string[] args)
' l! q5 d# _ P2 O! L {
* E1 D4 L) v8 t; G5 A! v //创建工作薄. m8 ^. ]9 W: J/ s5 V
HSSFWorkbook wk = new HSSFWorkbook();
1 ?9 f$ ]- r! T0 A9 l" X2 x //创建一个名称为mySheet的表
" i1 s1 q1 h0 c# q/ B ISheet tb = wk.CreateSheet("mySheet");
% K+ H# D2 j: _( y1 N: Y //创建一行,此行为第二行# t6 n+ J# n3 p/ H
IRow row = tb.CreateRow(1);0 ~9 M0 B5 B ^0 Z( e5 ?
for (int i = 0; i < 20; i++)7 b9 L. E, y) A. v
{
5 t. i) N/ p( v) ` ICell cell = row.CreateCell(i); //在第二行中创建单元格
/ u' L) V$ U% ]- o4 a" C/ F cell.SetCellValue(i);//循环往第二行的单元格中添加数据
, v' g) S4 d" w! H( B }# ?, n4 p. Y1 E
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
! u; j! V1 R+ @ {
# d: u/ {/ v1 \- O: j. f wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
' T5 J5 l% A" ~1 p( U6 c // MessageBox.Show("提示:创建成功!");
+ a5 E+ b6 G! G9 f2 O; r8 ^ }
0 }! H5 n" ?5 d! y* [9 L
: i( B: U& H" b }
+ O& ]( M1 H w6 u, I# U* \5 s1 D4 w/ B; h1 R. |( N8 X' V
Q1 q0 \& l8 E' v% V1 v }
; `8 R4 V3 e# D0 f9 P5 Y
0 @- b# ^5 T. r- d7 x" K; C" i- k. l( s1 n
* a6 m# e. o' ]% W v
}
+ Q: r( z% o* U+ O. B+ ?/ e5 `. ?+ P& V9 F6 ]% H# Y8 Z% z
// ----------------------------------------------------------------------
8 y, D& C5 g; F5 k// 使用Npoi读一个简单的xls文件
' h+ u6 s7 A' q+ |2 z
6 }. v1 ~4 }, U7 Zusing System;2 D" o& p. J( O# E
using System.Collections.Generic;/ e" e# y1 Q6 }! }4 s
using System.Linq;, N- ~& {* L4 K9 }$ h( g
using System.Text;0 K4 n& D1 y' ~& t! f0 {/ M# E
using NPOI.SS.UserModel;9 r5 t8 s3 S) }+ i: A9 k- C
using NPOI.XSSF.UserModel;
( T0 |2 k7 v5 ?using NPOI.HSSF.UserModel;
) ~1 N( E0 p' y8 _& B4 D {4 dusing System.IO;3 z8 d6 V- X0 G' P
using System.Data;9 V7 n$ K- j; A; W
0 t8 {( h) m {5 M* m! wnamespace CC
8 l4 V( M" ~! q0 [{$ m/ [3 m" C" w' ?& p
4 I; M' Z- J4 J* [. ^, Z
class Program
1 Y( |4 v8 A% V0 M2 e {
$ [$ r! E- U, z) d' D. _) {& ?6 k3 L" z/ P' h2 t" J. Y6 q
- U, I3 Z- M0 J static void Main(string[] args)3 N3 f5 D1 s# ~ [6 f7 r
{; t" i- `1 J$ O( X. N
StringBuilder sbr = new StringBuilder();
. s+ Y! G+ e) G, q% S9 q using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
4 F# i% c, s; [. @ {7 {: d- o& ^; q$ t
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中3 C$ N; j4 o/ D' x) v- }
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
8 V$ O' |( R" i& T {
4 J" C$ a; w" W* R0 g& w/ T ISheet sheet = wk.GetSheetAt(i); //读取当前表数据9 g. m: [& p! G# g' l( j" F
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数. D! ^! p- ?0 x1 S) z
{' X; f$ ?! Z& W$ _; l+ H ~4 s U
IRow row = sheet.GetRow(j); //读取当前行数据
) m: Z6 P- u3 E! i F if (row != null)
8 P9 |% _4 _) R8 o {' l6 V/ N7 @4 B9 Q' R" V
sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限3 ~1 V3 j C& z' q
for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数, C* Q( @. ^% F
{
3 _5 j4 C: q. S+ v5 P) Y3 k ICell cell = row.GetCell(k); //当前表格1 G" I/ p: c. U( ^/ j5 l& Q
if (cell != null)
! ?% Z' d* M7 P! h; g5 g2 R8 e3 P ?) E {/ b4 }# o3 B# _7 K- P1 ?4 O
sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型
& H/ x) b0 t/ E. B6 C }2 Q6 N1 `/ s8 G0 |9 A0 ~
}
5 J0 J4 \) n) `$ G# d }
V8 K' M0 C, X# f* b% | } K* t8 y$ j+ a; h7 ]* U" R. B
}
7 y1 e( v7 v0 @! B; v! B9 f }) x, t1 [# d; ?1 p) I$ S
sbr.ToString();+ b7 Z' _( r0 L, ?, W
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
2 r' v8 ^: k: P* P { p" [3 n$ K. T7 `* z
wr.Write(sbr.ToString());" z( ]) M' c+ i X
wr.Flush();" c, d o7 w/ X/ u
}
0 F) z. q8 M0 Z7 q& A3 Y. `0 n1 [
% a4 w, m: @ G3 b" W1 @0 q: _: j W+ J7 o* a/ `; v
}, t A0 O; J& [2 G& g2 a
' f& `+ q+ f# ]. {" S7 y8 ?: @( ^& z* B" ]: }
}
# I4 a* K. v0 D, ?0 o' r, q
! w$ k( P6 |3 o% Z. K$ h, ~
& k# t! G8 g( \9 D; P0 w) |: J" t0 G5 e! Z
}
/ X' B$ A/ A, g; a% P/ i7 h5 @! Z' P% w* @1 }, m6 d& @3 L
; @- O+ |; o4 ]$ R: T3 C% D/ o然后 自己封装 给 c++用$ y6 u2 d1 }- q
2 G: ]5 M5 R# B$ j( X- G. ]& C4 F
4 m) ` T, U+ c; I7 A0 x- H4 G
k q0 a: x+ O2 v. e8 J9 r6 V
: p7 y# j+ C6 U! I
, {. V/ r4 D2 Y5 a
4 Z! L$ i2 M" ]+ C
( d. z' c( d1 l+ Y! r& ?1 @' N* i- D, Q ]6 E/ b, ]( \
2 E% v* _( |+ W4 Y) {
8 G" c% \, H! o- ?+ k. a7 v) @9 A+ l" Z5 X. M5 Z4 Z2 z
- x& X7 k3 [$ @. F: F. ~* [; C1 S1 l$ O+ d, j9 R, q* f
4 r" j4 L" y* ]* \. s9 t! a
; D- N1 @' d& t* w+ O8 j3 K" A" }+ v, W) L; Q& l
" p$ u2 c1 J T. w# C* \1 n6 F( r& X" j5 E6 b ]. N# g' ~1 y+ L' Q" ?
* g; B. ?% U7 {& Y7 U4 ~
8 J. A$ H1 _& S% a" S% o6 p0 X& d5 Z, ^% y' x# A
/ c5 D% ?; t0 C
+ e2 b8 ~9 j: [- a# j! k8 I
|
|