|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
l/ o/ f; v$ F- D% e& xnet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)4 j% L" u% P( R
这里我用c# 生成 com 组件 让 c++ 调
3 _ Z: S1 b2 E' c( y _) v! z9 E$ i
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)
- h' U G, _- w1 ^- ~; Z0 ?# tC++调用C#的COM组件(DLL)
9 ~5 @) k, P2 F" u- y) L, v2 t: s5 B' ^: q
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7. A3 L/ y8 t/ y& a6 O" ~
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.5 }3 I0 O% o5 z0 o8 t
! d- z+ W# K" k# O/ K% L2 L- F1 r7 U" p+ o
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom: s: _) `1 X$ ]# u8 G, X
6 W# D! ]% h2 K' B# H4 `
2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
4 {6 M/ s" D5 l0 ?6 {) R; h# d! U
: t/ e& `6 |" J0 |- W具体代码:
0 H7 ]9 S. d; [% w
2 h H( j& N/ H% i, f6 {' O% ?using System.Runtime.InteropServices; //记得加这个命名空间
9 n1 F3 O' d0 l4 U' e! j
, y3 s( h4 u* ~, P: Rnamespace MEI_AddCom+ E. Q0 x( `9 G8 O
% b3 X( J6 s5 f$ G5 t{
3 ~$ A, ] u' ^; ?% ], a
3 c; T X. N8 J4 N [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.
9 D5 V3 ~3 K& L9 t$ a$ I
8 k! v0 \3 N7 H0 m/ M" `1 B3 I2 |- E //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生% s! V. `5 O+ R0 w/ I t
) u3 |$ _5 E' y
[ComVisible(true)]
0 N0 a# D ]: P$ V! L5 t
3 H9 [$ H9 c5 k$ p8 O9 Z public interface MEI_COM //记得用修饰符public5 R8 v% ~! H0 j) Y6 B* a8 X/ Z
' ~! g; F" l+ A# j3 R: L0 C. {& K& L' M8 ] {# W( A' h" \ q$ M: \
0 L. v, W7 K* f5 L6 V! N [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面, w* H4 A. N' ~8 ~8 N0 p* r
# r$ W3 E+ b) o int Plus(int one, int two);
& D* X+ j7 I' h" T) l" F2 f9 \! z- c% {
}% g, h$ u0 }% H: p5 x
( {: S3 J9 X. u}
$ {: ^6 l* y# K, R, p: \
" t- F" m! S) Y- t/ \6 i; F" ^/ t, c1 y. ?! V+ W( k
: a# c( x9 I, v% ~. P# i6 X9 S2 @" ]( J
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码4 e |3 ]3 _: Q0 B4 F
/ r, f2 C8 l4 Z5 x) h
using System.Runtime.InteropServices;- t7 ?; c$ _7 j* c1 g
/ |% f% A) N5 z
namespace MEI_AddCom3 I- _# t C7 O( I
: a2 {0 I; U4 n
{9 Q$ q: V8 E% p0 a
7 G. p; n: p6 u9 M% o6 r [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]
: ^8 G; i8 H" Y5 t+ P, P: n1 a$ a v! V, |2 c
[ClassInterface(ClassInterfaceType.None)]
R$ a) I+ u- a
+ Z, y4 |8 j6 x' U, W3 C public class MEI_COM_T : MEI_COM
' w% Z: q$ ]1 |& I
, Z: s4 h# |# D; R: R+ F9 \ {1 m6 H6 M1 ], O/ y/ f3 [
8 |7 G3 T" J# F+ E$ j, V1 ?. t public int Plus(int a, int b)1 z8 K8 j/ Q/ f8 Y4 r
2 s4 ~3 y7 N( E
{. t- c9 j1 U" e8 p
/ \1 `$ Q u' Q- l, `
return a + b ;* q$ J. d& H6 Q# t# C/ @3 M
% t8 _, a' W2 p+ C3 v) ]) B! V3 O }4 y+ l! J; S' [8 k R1 G$ x
* w6 E, E5 Y$ e0 {# C }
$ P- z i+ Q6 l4 n
S/ r! `9 D# N}
+ D( }1 E; E' a5 L% C2 G+ |6 l( M: d' J. C
' @9 D& ~( w$ T W( v
8 H) x! V- B7 K2 c$ }) O# I4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].
8 d" i7 T) g' {0 U2 K3 ^3 ?
* M5 o6 a. W( b9 w9 k右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册
4 {5 d# R; o [
! Z0 R1 A$ h/ V9 H. ~+ i1 I
8 U: a: y. Z3 n6 `' o/ T, t/ p" V5. 生成->生成解决方案, z2 g I% s# A5 f
注意 这个时候 生成 非常缓慢 : r' y4 @: ~- g4 ~. Q1 A7 l. M
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
8 ~( ^1 ~ Y R# p, J, p! @" F7 Z+ z
' O. P3 W9 {% F. x
---------------------------
" }) L# L: @1 S. W' D
5 b6 F) Q2 u! T1.调用前要先把com组件注册才行.
" M1 ?: {4 y1 O& r, y$ V! G! R' k3 }- B
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
* P6 J2 f$ m) J+ d% o$ {+ \) Z以下说明如何通过C# 注册、注销COM组件。
+ p- ^' y) M$ c* S* k+ v' S
8 | C. [1 G' j/ H4 U为了能让生成的DLL能够进行COM注册,需要进行强名称签名' Q2 f7 j. f; n) K) c) }- J
打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。. K6 I4 R* c2 D4 V) p0 r! b
创建完成后COMLib项目中将出现后缀为.snk的签名文件。
" Y% s \, D2 c2 T/ V# t) s最后,编译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文件。0 a4 `* z( d2 n
卸载COM组件:
0 c- R3 Q' p! k, E与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
9 C7 h$ b6 F) C" K' d6 W5 M1 Q1 {+ o# t% u3 ]6 Y) S0 m, t
2 W3 H* [+ R( N2 }2 G3 h7 g
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
/ r( z1 p. d' C: Z+ K/ M" X9 o: K0 A1 \8 ]( F* Q& L% u9 i
名字取MEI_UseCsharpCom,点完成$ c2 ?! f! l5 r' A/ P& C+ w4 B
# [8 C( H" _4 ]5 A
把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.
; Q8 M6 g/ L# d% m% J
2 r6 [+ f G' ~- O我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:9 B( y) v5 {4 |' U, ?# j% g
/ X1 e5 F2 r( j/ q
X+ {# a" Q( O* c" h& ]
#include "stdafx.h"
% ^- b, m" g: {: }+ X; C) R T0 I#include <windows.h>
- H c3 `" d3 E7 O5 r#include <string.h>
* E2 Q6 [' H8 P h- i6 c* B# k) n' x- d3 z v- _$ Q
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
5 w8 g- u n1 K# t7 w* j7 i
. ^ D/ q4 N, Z: d- Zchar* WcharToChar(const wchar_t* wp) //wchar_t转char*
$ x% D) ^ P# e/ p0 q. j, H4 o{ % W# ^5 f* p: `, @
char *m_char;
, T, b$ g. K9 l int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); 9 ?7 D; i) _3 n! @0 [
m_char=new char[len+1]; + J& d* {. R4 u4 q% k
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
& U2 r3 B% S# [; m0 q m_char[len]='\0'; ( C2 `3 g' S% J, F, m5 }
return m_char;
$ V8 E0 r! X3 \, d' J}
4 j8 B' G; U; j1 Kwchar_t* CharToWchar(const char* c) //char*转wchar_t i% `! F1 l" M0 l+ u' i' v
{
4 t9 M8 u: G* j& N& O+ ]! R wchar_t *m_wchar;
( Z1 b- @ m1 p int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); 2 |4 G' L% C& v1 [( q+ u* K
m_wchar=new wchar_t[len+1]; 8 s. V, x( x/ T
MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len);
/ j+ @: K8 b! P2 H5 j m_wchar[len]='\0';
& ~' P- e8 d% V5 I& s, O! E8 D return m_wchar; * o; i+ o8 {9 O: A6 X
}
1 |, B: G% n( G: t9 Q* N' ~, I% r8 I% h/ [3 S# R
void _tmain(int argc, _TCHAR* argv[])
6 K& n/ |% N0 n1 U. j! |( O: Y, K4 E$ p Q
{
7 E1 i5 W) A5 n! i$ X3 d
5 ~: D( U3 ]' w+ N, x) J CoInitialize(NULL);8 N( c7 o5 d! `9 G, H" z
0 A' Q: @& k) I1 G/ p" {, R; z MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针" l7 n5 }1 O8 P$ x5 j8 ~; ]/ {
* ^5 M8 o1 `# W" Q2 Q/ d8 C
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名, W! ]3 H! p4 j; ]( ^! ]
& v7 c( X$ W2 j //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
3 Y2 c! {1 x+ i. N5 e. _: t b8 j5 C! x- }( _0 H8 s
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
2 Z G0 u) }- {" u& C J. J //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
7 B' l2 ^7 Z0 x# \9 b1 U5 b7 ~9 |2 v: u! _1 @+ g1 J
long a = 1;
5 z! L4 p5 K6 n! Z
& x2 ~& R' W" }$ [9 n long * lPtr = &a;
' \! i- w9 R. X+ q, u" U0 \; j8 z: T6 R$ D5 w* z- T
ptr->Plus(1,2,lPtr);; R1 k; e, v# G% {& K0 h9 u/ Y
& P; j) a. E8 g- k8 R0 w3 u% a$ W char msg[132]="";0 T) F3 k" x. K0 f7 ~
sprintf(msg, "%d",lPtr[0]);
- a$ X# o8 v' O, d/ E
1 h! ]- v6 t' p( G9 b LPCWSTR str=CharToWchar(msg);" v& N9 \+ p) X
+ V; f& ` L" i h MessageBox(NULL,str,_T("123"),MB_ICONWARNING);8 G9 D4 x) G# ~
" z: t* q6 j* {" H/ E
4 C( t6 g& v9 c# S5 J}$ L. d* X: J- J9 Q
$ m! D b4 i9 c7 y此时就可以正确运行了.得到结果3
# J# t. _7 q7 ]5 \4 {& j. X' ^ o" N* d( u. p- K9 n" t+ H8 F
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
$ d! K0 n! e$ X1 l2 l& |5 ^, K5 G( G) q5 M" B* w6 C* Y
' ^" e1 s8 H% @ I7 M7 \8 u$ P--------------------------------------------------------------7 X' j% [- q7 i1 N7 D2 i% D
C# Npoi库 操作excel 的代码网上很多( L* b% K+ b6 Y3 T1 B
7 `1 g6 ^ ]+ v1 o! H3 m! b
// ----------------------------------------------------------------------! k% _& S2 i3 J0 k# Q
// 使用Npoi创建一个简单的xls文件,写内容 Y; c# e0 V* D; V
6 \4 |1 C3 q" u# U
using System;9 t) t' } s+ D' j/ e
using System.Collections.Generic;
+ V3 R" \0 t& K3 p. C$ iusing System.Linq;
- t1 ?. z% g9 V. Husing System.Text;& V1 _, w2 n5 p3 V- u0 K9 _
using NPOI.SS.UserModel;0 i0 Z- S! F- `0 E
using NPOI.XSSF.UserModel;
2 z; ?2 p) @! d8 o3 P, Uusing NPOI.HSSF.UserModel;2 t! k" R% G- V
using System.IO;
( o+ f( n1 N4 Q4 w1 k" Z) J' V( nusing System.Data;
, ?4 W# X3 A: ?5 B+ C* B1 A; a" J+ L7 a5 u& z
//using System.Windows.Forms;
. ]. ~0 ]5 w! B% _) i7 x) j
1 L; L M2 n9 n7 R* j. V: G Enamespace CC- C8 O1 h3 B4 m( c; I
{
- k/ @: d0 C2 F% O, A& S# E) }7 A! ^) F q
- c1 H% y q: s; ` ?# K class Program
5 c- P) M$ l1 V' p1 E. J2 b" z3 W {
* [* `( }% ^9 u0 ^( M% \$ v2 M$ p& Q& D
% R( y. O$ o: S: P4 A( h: j! E' e6 q# m# t6 Z8 F
static void Main(string[] args). i, {& D+ g1 V l
{2 m& O& a! p+ F) q- }
//创建工作薄
1 D. ]/ w- c9 k3 o7 L HSSFWorkbook wk = new HSSFWorkbook();1 ^) ^, J# d) K5 g3 }1 _" r+ L
//创建一个名称为mySheet的表. }- r; O' J! p, P
ISheet tb = wk.CreateSheet("mySheet");
2 h! p5 p' E G; U4 @ @0 ]6 x. t4 X //创建一行,此行为第二行 W6 w a2 p! k& Q
IRow row = tb.CreateRow(1);# }$ O9 O3 f8 }1 D1 X
for (int i = 0; i < 20; i++)
& g: C( X) b( \) T( u {
7 ^+ r6 G- c8 b5 ^% b! q) p | ICell cell = row.CreateCell(i); //在第二行中创建单元格
$ z5 b4 s1 y/ m* ^ cell.SetCellValue(i);//循环往第二行的单元格中添加数据
# q; A% M5 d: e4 w, |! z }
: P: j3 Q* B7 ~1 ] using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
]2 l* ~4 \( K {9 d5 I9 M" x% T) G! z& O# D1 ^4 X
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。: C( _7 I9 R9 \ |6 t
// MessageBox.Show("提示:创建成功!");/ |" a+ q" A, b. D9 H7 G/ g
}
2 R/ x5 P3 f& J) o2 A
1 |% I( ~% v7 v8 _8 D }
3 o) @# X0 ?# [7 s5 ]2 K0 i2 F" M3 x. G+ I+ o* L
+ c' n' S4 w, t/ Q5 ~5 X+ A
}* h2 i0 Q. b! |: V
4 f. C! {; h+ M+ w) @2 M8 E: G( Z% \
4 D0 ]* W* W) s$ d* Y6 f8 M% v6 P6 q
5 Z/ z' H( O! p" X5 a( G}3 f1 B. s" s+ @% G) ^* g
! W1 z; e0 Q4 O. ^, U0 P! F// ----------------------------------------------------------------------
$ _: u; ^/ o' ]9 k( P" x! `// 使用Npoi读一个简单的xls文件
1 ^2 k) r G( Q. X" ^7 V# e
$ z" \8 e9 E; \3 {1 t9 busing System;" e: L) c; U5 k7 H1 {- ?$ x
using System.Collections.Generic;
( ~# Z i' ~+ _" E4 O+ T% L- eusing System.Linq;% K* @) A5 ^6 e K/ v
using System.Text;
+ F8 f: @3 g- h1 iusing NPOI.SS.UserModel;. X0 N' l# }5 [2 F& f) @
using NPOI.XSSF.UserModel;# Q+ x, L# ?3 K1 f, D9 |! j6 d
using NPOI.HSSF.UserModel;
0 j. p8 ]) L% \' Cusing System.IO;# g7 S- C0 {# T, }; d
using System.Data;
4 A4 n r [$ D6 a- }9 f! c2 O
' e) R3 x% J3 k1 H- ^6 g9 x6 Bnamespace CC/ r# U" y$ S' d! }
{* n2 L M) G, w+ J0 A
" o) G# h. T' X% v class Program
. Q+ t7 X$ y1 L {' ~# Y. C% l4 n; _3 x6 ]' d; O
8 n) t* T& J- V( U* N( W% n+ A$ k9 T0 V! u1 [' \! _2 f
static void Main(string[] args)( ?0 Y# b7 i; c. v) O9 Z; h
{
2 M1 V* D: X/ ]1 | StringBuilder sbr = new StringBuilder();) ]/ J8 A/ w5 W! e9 x6 y% _
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件6 n7 B* O% H2 g/ D
{; K- h) ]5 X8 w. B- n
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
/ a5 W4 @1 y p J for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
0 E, i- i; r" N( \ { V4 g4 R D' i3 Q2 E" ]
ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
L( x' f5 h" X: l. y for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
# n7 j" ~+ A' ~7 O {
6 g9 N: N' T4 ~# r% x% t" H" ] IRow row = sheet.GetRow(j); //读取当前行数据9 g4 M( t: [% j8 R7 f7 G
if (row != null)
' A) ?! O6 V0 h9 ?8 ~: ?+ _ {
5 |& A( i; a. \4 a" W sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
% n" y# y* P4 ^" h for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
7 G2 ]8 ~+ y3 B {- ?8 Z. S, M* f0 A3 j- P' d9 B
ICell cell = row.GetCell(k); //当前表格
; @. h i* `) `' o if (cell != null)0 M3 D* A8 _& U: B. u7 _; p
{
2 q. Q1 E& D) ]1 E* t G1 j sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型1 ^/ Z( g# Z! {
}* r" }2 K7 W! X6 x4 j4 F
}
; e( g' V0 `# X8 `/ o' f }
/ x/ x$ s. J( e- p/ | }6 h7 Z. ?- j0 u. R
}
4 c- P |7 a. O$ _* H; B }
% O/ z/ ^# q+ X6 l: K$ p& t0 d sbr.ToString();3 k# Q8 T3 F. O6 ~$ a( p( K% B0 P
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
) g, X+ d k2 `# ^. C j; ] {& |# l, u( L6 O( H" l' \! F
wr.Write(sbr.ToString());
* ~ S' s/ T9 K% w wr.Flush();
, a+ T% p: R1 ?. ` Q4 r7 f }
% |# L* ?4 u8 B1 U0 k. }
0 |! I! l. D6 ]6 Q2 ] C7 g" |4 t( l& P2 U) k9 j- {1 u* \& c' J
}
* p4 r* H2 _9 H/ Y ?" R0 N; O d4 f
: L" E; m+ r/ c% x }0 O% }5 u4 C1 }% U1 w% j
3 f' P. I: b3 _ p6 P3 ~ s
" P2 Q- A* R9 m" P1 ]) _8 y$ ]9 g4 c" [- O9 U7 t
}
$ b" O' ?0 m; `( M1 o- I' @, b2 w7 a! J
* s, a5 l7 V* r. p
2 c4 t9 {4 g. d9 u' N然后 自己封装 给 c++用
; s2 A& a/ i0 m E% U9 e, r
1 E# j$ a2 r5 X6 R/ Q
% V% O% s; I$ |% u0 @
7 }. V- F* }4 }4 w% d
/ ~; X2 |$ p+ |# T( U
5 ~4 l. C" R4 K9 A) f4 e: K6 t; h2 u( N! }
1 r- Q/ o' Q+ z
, ^, Q: a* {; t6 S( [3 O9 @' b
- y" e, R9 @3 v- z# d3 m U
3 m; h; [+ F1 T9 W- a) Q8 V! B, o5 [/ _# b
8 Z) Y' n2 T1 i: f
+ V) M( v/ Y: G7 B/ F, ~& I. L$ `2 B
9 i. ^0 I6 ^! n+ a) G% N$ X% n1 Y
" k% T, M; {5 ]! G% o# G! B7 X* I I% C7 p; n+ U
0 r s# {! @$ p2 t- \2 W' h3 T- J
# B, k" h" J1 r0 P) E- {8 {. G; ^ }& ^1 q3 I' _6 V
. f- ^0 ? J& x
4 u! F1 N0 I$ P9 C, C) [" c
+ R; ~ D7 M6 p) d |
|