|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢+ q8 Q: K4 K: `; h2 P
net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)
0 K2 W6 L" c* v; U- |8 T$ O这里我用c# 生成 com 组件 让 c++ 调 % @) q/ \+ } r' q W# ?6 x2 _+ M5 k) @
" C: t$ ]; ]* _6 o首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)+ y: Q; {$ }) N% E
C++调用C#的COM组件(DLL)
4 M7 _* s9 Z u$ n5 R4 s+ W5 v: w5 F- Q: e7 u B& E
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.; N# A8 L- {2 H+ t. u
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
9 Z7 Z. K0 V5 C; L
, a- M$ h1 w: S, R2 [: w
0 [+ ?7 e7 y- u7 i3 y1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom
8 e4 w5 I$ F9 g( q2 b) b o0 k# z- I3 Z/ c$ @: l. ^7 z
2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
: G4 [* M; f n2 r/ t. G
" t- i7 D' [" X5 t, l具体代码:: F5 z* ?9 `2 R" ]0 E+ y
3 s$ j5 z! I- [. @
using System.Runtime.InteropServices; //记得加这个命名空间( h6 Y, Y0 m* ~! {* O
# V9 I5 q$ L' s+ a
namespace MEI_AddCom
/ ^: @9 m) y, v9 M2 I% ]* T$ E
3 q, i* G5 y `9 O+ K; X{# O; F& ?" a$ f6 ^1 ~5 f
9 t! w* ^: v6 ]8 \" @4 \) r) _ F* \ [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.
: a, A, z0 H$ g1 \; X& i: _7 _. s. b% g6 K3 T7 A
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
! l5 @+ C; U$ Z$ o& |3 O! r3 {
o( u& }/ Z1 n+ _( @ [ComVisible(true)]
( _9 I8 h: b8 x
0 k1 C# o! }1 a3 R public interface MEI_COM //记得用修饰符public0 ^' U1 E# n$ d2 Z- O
( g7 c2 B) v5 n+ ^" @. f
{
, R" H6 p2 ?! c3 c4 Z" f: W8 n) V4 |. Z0 \+ g: L$ [' Q z
[DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面( k1 m4 d- s4 X. X
8 p% c3 z) t6 j! X, l7 e int Plus(int one, int two);" c1 Z9 [1 I J9 P& L3 c
4 p( P6 U" r& B$ c( M }
8 ] k, _ Q: F" R" Q3 a
% }) ]! a4 ~( ~! F6 _- [$ r}( q+ k r$ j9 T( x
: b/ M5 M* N# P3 p( B
) E$ y/ E2 S) \- H1 B9 u; c: J7 i
6 m$ _7 X4 N( z) G
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码% s- a4 t' R- O1 `# E0 q
: K4 x5 @+ f! G) j! M/ _5 K
using System.Runtime.InteropServices;
+ L @8 U- b: Q" j
3 y" ~; B4 `" p; V# z2 w% A, @namespace MEI_AddCom
) H5 U2 h. I q& n1 _# b: j& K7 {. x8 K% W+ r
{7 x: a7 h# S$ y7 n! T
% A( Y. n1 O* m
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")] f1 l! [( C6 ^8 U, h9 S5 L( x
) x2 W$ B+ Q# u/ n" d
[ClassInterface(ClassInterfaceType.None)]7 T; k% h6 p$ F% S7 c
) I1 m# o1 \: o- I4 q* \% R- ]1 O
public class MEI_COM_T : MEI_COM0 h( i* n+ ~! K% v \0 g
% b9 V# N5 z7 X# s+ }$ Y+ r {
! h) G& H& b8 D* U$ q+ Y, x% }( @; Y; d% S: l1 _/ m
public int Plus(int a, int b)
: o, u0 h7 |/ ]2 K; R0 W
G' S/ s7 r8 ?4 @+ O$ p {
- ~( ^1 J8 B. y4 r3 O2 \. K1 q1 \7 t/ m$ x% f3 X. R
return a + b ;
) I% ]% ]$ M- W9 ]: Q. x' X4 S0 A% r9 ] P' ]0 |
}% F! N2 Y( I8 x0 `2 G1 g: v
. m% t- K1 e& K, r }
8 t% W) E1 D2 v/ x5 z" t5 `' U# ]3 s8 p N
}4 V- T& ~6 F1 u' T$ m7 |
4 M$ @. ~8 Z' w5 A- l8 G( ~0 A7 L! G
; R/ A5 x, k" b& I8 ^2 Y
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].
# R0 L& L% v4 l( V, `1 ]+ H% G. s; u( v
右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册4 q! ~/ a1 R) q6 r# A, i) ~% n
8 t( R1 v5 z' w- B9 Q
, f. w/ D7 ~* Q$ [) h% c+ {& W5. 生成->生成解决方案
k. v, a7 g8 J- F* q* P, u 注意 这个时候 生成 非常缓慢
0 z+ Z9 r1 `/ r' K* j1 N 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容, l" m R3 H+ M
" ?) M G! B( J- \6 F: t' g' I1 K: a' C
---------------------------
( f3 j5 o: @: Q: C
: }4 J; p7 d3 @! x P1.调用前要先把com组件注册才行.4 E& A, o! x2 w' {
' r; C, n5 p' g7 ~% j+ F
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
[' ~7 ^- S- k( W以下说明如何通过C# 注册、注销COM组件。
9 H+ Y& n1 j3 x h- y0 T3 h5 H1 s% D) v: x
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
3 U) `: \/ s1 v- N' H打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
0 _4 k0 P. M2 [7 r5 p% P创建完成后COMLib项目中将出现后缀为.snk的签名文件。1 I5 R% v. K2 E% m
最后,编译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文件。8 Y0 C8 B% Q( k5 V. p
卸载COM组件: ! a; y, l3 o9 I7 ~7 I5 R8 Z9 _
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。/ i0 x8 w7 b- F$ o
7 }, c! d8 D0 {) d
- |/ y1 Q2 p- v/ s9 p2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
! u8 D' B7 U! ]3 q- l
; H% a; G0 L, n5 d- Q5 o1 P名字取MEI_UseCsharpCom,点完成
' n( ]; p8 j' m# x$ R; e: L/ |# P! V' _' N
把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom./ \% t; C3 ~* Y$ s$ u
R6 r, o3 j: ]! C# P* M
我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:" n3 P1 p. P9 d, m+ g, |4 N- r
. q% l- X/ @7 F, _1 g& f
$ P; p1 P- e! [3 `: J$ v#include "stdafx.h"$ C: p5 i/ t6 b1 N- _( M
#include <windows.h>
# `5 C- h* l5 _ E) H# Q#include <string.h>
6 F) _1 U h0 P) {- n- ^: r# V4 g m1 E
#import "MEI_AddCom.tlb" named_guids raw_interfaces_only& X- e( O+ o) D' \8 x' p* d
4 s4 P& C+ x9 e' e' i9 Fchar* WcharToChar(const wchar_t* wp) //wchar_t转char*& |& z0 [+ F1 N# q
{
0 V$ r5 f& \3 ?6 a: C char *m_char;
! N9 b& o, U% a0 h/ E int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
3 n; h5 y; U3 Z" @: y" w m_char=new char[len+1];
9 K9 Q* T. b9 Z: Q$ o* A9 K" i WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
) p% O$ F; z9 O' q P m_char[len]='\0';
8 G# ~" M, w! o return m_char;
' _* c& p) ? b0 k9 H0 [}
9 {, _. I* z2 @* V6 n( y) swchar_t* CharToWchar(const char* c) //char*转wchar_t0 v& v$ {9 E1 |( d& h
{
* X8 d2 x a) S. ~. r wchar_t *m_wchar;8 d5 Y, b0 b+ W& t) H# u
int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0);
" w4 ]9 p- k( p3 J' V+ b$ a) \4 d m_wchar=new wchar_t[len+1];
- ~; L6 x$ k& J MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); / h( ^2 L3 Y8 b `) H& {
m_wchar[len]='\0'; 8 n$ ?* A8 C% W1 E3 [4 K1 @2 w
return m_wchar;
, i1 C8 W: T3 R+ c. R5 E6 r} % H; c5 k1 j8 h- S& s9 D3 `
1 X( ]* \+ ^# Q& E5 F
void _tmain(int argc, _TCHAR* argv[])$ |& |7 `. G( n5 _+ o. V! h: D' n
! S: W. S6 e0 {4 _' Q1 E{3 l: }' p' e( ?: s7 A
8 ^# O3 U+ b B0 |2 l7 g
CoInitialize(NULL);* N. _# W( c8 T) N
0 T0 b! }- e' g
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针1 a2 D. J, [1 }, M% j
' f7 I# J/ ~1 b0 b' p/ N; i, E
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名1 t2 u# k: }% \9 g4 {7 R
. _& }2 p: h9 q& Q: k1 A! s# q" A+ C //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接$ x+ ~3 y0 _$ q2 S$ E$ P
" K8 ~+ h q8 H
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.& n) F7 Z1 i5 j
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果0 O4 H D# C; |0 Q* M
5 h/ c; K5 h# T0 ? long a = 1;
/ I3 j- v% C4 o# e+ V2 O3 Y" g' \# E
, l, t3 l/ G3 P" B s6 i4 u( u long * lPtr = &a;
2 C: R+ v8 |6 x9 q$ h) ~* h
- Q2 P8 r+ w9 I6 {5 @4 _% X' j ptr->Plus(1,2,lPtr);
8 j5 M7 R6 V% U! ? x9 O
$ p$ A6 l+ g. i char msg[132]="";
& S5 Z$ [' \$ s4 C1 k4 y sprintf(msg, "%d",lPtr[0]);
8 Y- r- N/ j) `
$ \- B4 [; Z9 s LPCWSTR str=CharToWchar(msg);
, f' ~5 b4 j0 ^1 e
* z' {) o. J( i$ g3 s5 B- @% e6 P$ d MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
+ Y! v% \3 @/ w* X) `# h) d: z6 u+ X, [# j
) m l. ~" o E7 r" ^}
' Y/ a- o0 t1 O# f+ a% y# w9 w5 j8 |
此时就可以正确运行了.得到结果39 B( L% O$ A S, Y+ m
. a1 J, \4 x7 Z. E* d
如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
9 C: O: L' T5 W F: [, u7 Y* S, z7 P
# B5 `0 G9 j+ J; [6 k2 c
--------------------------------------------------------------
, p8 b5 z" P4 EC# Npoi库 操作excel 的代码网上很多
- G1 T+ p: p5 N
% o! m6 _3 L R' e' O& f4 E// ----------------------------------------------------------------------! f& w7 {" d6 z7 l4 i+ K! N
// 使用Npoi创建一个简单的xls文件,写内容$ o S7 k: [! T' j* d+ Y
. s1 O8 k& B6 o3 `using System;' @- A: W5 {, c
using System.Collections.Generic;
q% S( |/ W. f* U/ c; x9 lusing System.Linq;& P9 } t* q+ e
using System.Text;/ @- u4 m5 v$ x/ W/ c3 V
using NPOI.SS.UserModel;
- R: R+ v. A' ^5 N# x+ w- tusing NPOI.XSSF.UserModel;& c$ ^( c# c8 n& X6 v. {
using NPOI.HSSF.UserModel;
2 t! F# t" i/ R( eusing System.IO;
8 v Q; r: D" R- n: ?4 k) @using System.Data;
1 o$ w3 P# w$ }
7 M. U; g$ s' H% \4 U* n1 b n//using System.Windows.Forms; 3 Z* b7 @& y* W) c1 A4 r3 u
- T: G9 ~; [6 N9 [( j
namespace CC* p, o/ C" i/ m i7 C2 U6 n
{& k8 ]8 x! ^$ R* u3 S8 \
& h: ?( x4 i3 R: N7 k* T# C class Program
: V8 s1 ?6 T0 d6 T {5 z2 z" a: U6 ?8 [3 n6 R
8 o9 M0 Q7 b$ x0 f
- b0 C; ` b# N
static void Main(string[] args)6 h7 C. s2 X5 E" @
{7 u6 F! Q+ O4 A
//创建工作薄
, s/ v$ B8 s/ Q8 ] HSSFWorkbook wk = new HSSFWorkbook();2 \: `* S8 a, }
//创建一个名称为mySheet的表
6 \( C: x+ o) g ISheet tb = wk.CreateSheet("mySheet");
( E" N- p; r a8 b; T7 p9 m //创建一行,此行为第二行
, c" z6 k6 d4 A6 \5 k IRow row = tb.CreateRow(1);
6 X- d# a4 Y: i3 m! k for (int i = 0; i < 20; i++)
" ]& V) W3 I8 G7 Z9 |6 M {7 g8 X, P& ~; @- P: f
ICell cell = row.CreateCell(i); //在第二行中创建单元格! @+ y- V; p8 e* |# f
cell.SetCellValue(i);//循环往第二行的单元格中添加数据& I% X& p" w4 h# V" C/ h' Q
}9 ~! l) n, H. l8 |
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!* j0 T5 ~, ^% l# o h2 V
{
2 e5 w$ m# b9 C- ] wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
$ ]0 ]& | n" I* w2 P // MessageBox.Show("提示:创建成功!");! G7 E& t) e9 |/ ^& @+ b1 ~
}
0 I# H7 t$ B4 q! ~" |0 o% p/ G) A, i: V4 t
}& U5 v6 D4 v, _5 U! N! k
+ s, X! R7 r2 N7 O
3 P- [7 Y D% A* Z, L4 W- j
}
5 I0 B( u: n, { I0 Y6 S$ F9 Q8 ?7 s" G* R5 z
8 R9 B. A/ M4 J3 l7 f0 s4 s9 {2 B, ~8 S+ q5 k( s8 f
}( k# I- A2 e& e9 p4 K7 Q( D
/ _# N: \. F8 j( q7 N" N9 P' `// ----------------------------------------------------------------------
$ y" A8 h: r' Q// 使用Npoi读一个简单的xls文件
" o% H5 J6 k: f }7 u; y( u/ j; q+ k9 Y F4 c8 e
using System;1 I8 D7 c" a( c/ C( G8 e. P8 h
using System.Collections.Generic; r( e a/ Q% o7 G
using System.Linq;
9 q- ?4 y p4 C1 Z8 g5 b8 H6 i/ T/ jusing System.Text;+ j# M M* |' \$ C
using NPOI.SS.UserModel;
8 z3 r3 F; U+ Ausing NPOI.XSSF.UserModel;
. U) V: l; x2 h" tusing NPOI.HSSF.UserModel;, d' R- Z! l0 F
using System.IO;. A% u4 E" H. b% R! n3 k+ V
using System.Data;
% I. g- P0 R. t: `) F9 Y1 o5 g5 H% N$ S& h: _0 v
namespace CC5 \8 C' Q( y* B' h q
{
! k! ^* V1 k6 p5 r5 |: b8 u; o4 B9 K8 L+ E# v
class Program
& c0 l- ]& j8 J3 K {
2 G0 g& R: l3 }4 v
; u- h' J0 s. a; b# o
/ C/ C; q) Q6 V. `( J7 l& L& M static void Main(string[] args)
' [$ S- |: O" z$ i {
6 B1 K/ m& B5 ? StringBuilder sbr = new StringBuilder();. m; F4 p8 v/ p! q5 w, i4 S* t
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件) f/ Y" g! I7 |- d; a q" V/ i
{+ y. C) J( u3 U* ~# U1 }( a
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中9 Y! Z z/ U, e# g t- `4 O6 K
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数* P" ^! {. C, Z5 ?; D
{
+ M( a* R6 Y& C4 [# W ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
7 z. ?; D. ?' k! |' j for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
! m) c7 M* N: S+ F& h7 ^; M4 f# A {( h4 k* `. B2 b e5 y
IRow row = sheet.GetRow(j); //读取当前行数据
& V' F, L R" S; c8 R i: P if (row != null)6 `1 ?8 F' W$ K& o
{
l2 S% l8 a' t0 N6 c3 R8 w sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限9 ?* @; v& q' |
for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数7 T& i* G6 z( M3 k& Z9 C
{
5 R/ R8 p7 I0 @. }5 L$ O ICell cell = row.GetCell(k); //当前表格, Z1 L8 y$ d5 o- g9 Y% x: r
if (cell != null)1 C4 q9 M9 z. a" o4 _9 J
{
: U$ | e6 P$ B" ?! a" Z3 ] sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型; l* u" E4 \! b& w
}
0 L6 b: ^: K* d9 K1 b' K }
9 v6 C m! Y( H. v2 S3 ] }
9 n) N8 b4 o) y% v/ x }+ w; C1 k) e- M2 q
}( W8 x0 _& Q0 l3 l: X- K% ?1 S
}& q/ Q. [4 H8 A3 a" _
sbr.ToString();
$ u" r6 i+ g" F& {4 ^6 E* E6 ~7 g using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中6 x1 H7 Q( o4 B( v6 e0 o# S
{
* l3 M; ]% `" e, [9 P1 j8 _7 @ wr.Write(sbr.ToString());
1 l" a: x2 K3 K: Z7 m% |7 \' z& r wr.Flush();$ i; ?- S E% L) R+ J3 A, Q
}
4 f4 T- u8 o; M: ~* |
1 |3 \/ ~( D; s0 r9 `
+ W r6 Q8 Z1 M! y: [- [ }. I _# y$ y2 @+ M
: X. D+ S9 z `, q H
& Z9 X4 H2 W7 C4 E+ P+ T }" B) M/ ?2 ^* R! B+ C7 w6 _9 Y
5 v0 ]+ v) o( w( ]4 L) W1 H9 q" d
! g! _5 k/ O v9 g( u' o8 q& o# d; F* @# T4 ^
}
( K: R- {" ^" A8 D/ R' J2 {, N, k: M; P
: [8 l0 s2 d5 U3 I+ ^: S然后 自己封装 给 c++用5 F% e4 s! Z: D! j- J6 J8 h. Y$ y8 y
, x6 j, K4 A6 V1 w, C& W4 h! s& P5 _8 a
% H) U5 Z4 ~9 }5 J3 L% U
+ {, N0 k: G# P- S& }$ u: W
& l7 O. @& k' t- V: C0 r6 D. O9 v, S# W7 A
! x( V! D/ j0 @) B. i6 a
+ V$ O3 v3 [$ m q4 w* X, f
8 X* X+ L. [- f! Z; R
) c3 W1 W! r2 {! ?9 w8 Y) E
+ H% k; [ X+ M
- b7 x! Z5 o4 `; @
# h n& w- A0 K& S- {. L3 _; A
7 x- c$ a% W5 G& I9 y$ X, b* U1 G4 d0 \& t
* A+ E# e8 T) }* z) }
$ T# }$ x8 `8 a9 m: w8 h6 L C f( o+ o4 D, d( Q. D+ ?4 U
+ h3 M: b8 N6 D
" ^9 |& T5 g- h$ n5 G+ x. Q
3 D& i% | h. A$ z- S0 V; [0 s C$ `) a4 U+ _ G! y# H, i
! f: e# ~# E: [, l& h; L. a, [& U( Q6 o1 h
|
|