|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
×
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
9 f2 }0 z+ T; F8 enet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)9 q: b+ Q* M7 @; A' X5 ?
这里我用c# 生成 com 组件 让 c++ 调
g+ v( h9 O- h6 e7 s* F% K
- n8 O; d2 V1 F1 X: p8 b5 W首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)
5 {) k; V8 F- N! O7 GC++调用C#的COM组件(DLL)) t3 R+ n/ U, z. a9 M
/ l& M- [; ] g0 N! A
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
2 f. v: f& l2 T! P: ^4 Y首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
% j: O ?0 v6 C" ~, }& Q) G
$ M ]$ N. [( M7 T6 z7 V7 o) v
& g- V) [8 p4 k5 P( V" `1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom! e' p- r7 M0 n7 \( M. l
# L# I3 a5 A8 p6 k2 y! F5 o% @/ A7 N
2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数8 s) u3 u/ ?* |
7 B' z7 B# s1 I, {; o: u) ]7 s0 l0 U具体代码:, @& |' F0 i: i; F* C% ?
2 H2 j& W- c7 V g0 Z( Musing System.Runtime.InteropServices; //记得加这个命名空间8 `8 ?; }; M6 A* K8 @
& ~* ]* a( a6 m1 g S% G4 L* p
namespace MEI_AddCom p* A9 U( Q% \+ s$ P) i+ l
# H! v2 l ^0 O O{6 w( V' q8 M1 }0 Q
/ M& l0 J' W2 Z2 K7 [) X; j% ~ [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.
) W8 R* D: N: V. d3 f" {5 l( N9 o" ?* R8 ?- T" |6 x
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生6 v5 h3 l% _ O
4 J0 T+ t- }5 a5 Y1 M [ComVisible(true)]
* j3 `! S2 W3 r+ l2 [, k
' C# W5 G/ _1 [* P public interface MEI_COM //记得用修饰符public
8 l5 B; `% y8 U2 W% W8 _% ^. ?; [+ G% G. [. B' ?- }
{+ u1 L( s2 K+ H9 V# B
5 G; ^& T* ~$ f' I/ d, V [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面4 T0 s* z7 y: @
9 P, y7 ^. [# Y9 }" m
int Plus(int one, int two);
1 H6 ~! N8 p1 p4 b8 s0 X0 a3 f, ?* e4 t1 v; \' Q2 j
}/ F& V! v8 M& E& U$ }2 L
$ e8 B) }' Y7 w+ `7 w% F. K
}6 M7 h: S4 K3 m
. l$ s, \; ^$ S5 Q0 [+ d% d
2 T* T! L! n8 M; c1 P. i: h/ C( f* R# K% ~, N
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码
6 ]$ X9 ?- p3 C- y5 S2 ]! b
8 d; i! }% Z9 Kusing System.Runtime.InteropServices;
3 c; w4 w7 p4 c* O' w. x, Y4 F) @" v+ ?- n. t6 _
namespace MEI_AddCom# W- i- f/ A$ l1 t: {
5 V8 t. r9 x }- s6 B
{& x/ a( H: P4 F
7 j# ~* f8 f; w& L4 ]
[Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]
' K s/ ~6 X: G* a# T' a) A4 O5 G6 [; F; V1 {( ~. x
[ClassInterface(ClassInterfaceType.None)]
* k" ?8 `$ h, S' P8 o' l/ }( S; r8 |* y
public class MEI_COM_T : MEI_COM5 X. C6 q J" a* v& y" H8 ^" t
* {' o; y1 c' V& |$ ~4 r {2 i6 N" ]( P. w! G! \, Q5 K8 }3 f
3 R+ l- ]- T$ C public int Plus(int a, int b)
5 t$ ?) }6 v, `+ a
, m) ~5 W3 ~3 C3 w3 @ {
6 ?% b' U- z; `& Y, ~1 a
/ D; @: V* S" U+ L- V* c return a + b ;+ ]' _, h; ]6 t
# Z1 D8 u) ~0 Z( `: H* g }
+ N4 y: V- ]' T% X( Y# W1 B! R' R) Q4 t O# n0 @; p
}: ?7 J- r4 j( l; s* {1 ?
% n3 c- t: u. V% h1 t# j3 S+ y}
/ ` c- K3 d0 u1 w W' o
" _, q0 s$ U" x/ {8 ], [6 I6 D6 m4 n) T( } @0 n
" }' c8 M, a9 w/ P# i* X& h: x
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].- D6 J' }* W" L- K- p
$ t. E% J0 h" J: @3 J右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册# D3 ~6 {5 f! R
6 N3 O2 u* B# P5 D: U$ Q; f4 e! g# M" C
5. 生成->生成解决方案 ^+ W( z2 B2 `2 q! H
注意 这个时候 生成 非常缓慢 # E* t2 p: m; n2 m) Q
直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
3 I# `* {2 s% v- F2 K- `1 c3 K7 o( @+ W4 P! Z; Z) N
9 E/ Z6 R1 p3 [: j. z
---------------------------; }# Z. e* {4 \9 y, l# h3 w; r" `) g
' x5 R' J) b1 {2 `
1.调用前要先把com组件注册才行.% E- u- A4 h/ [
# I' E; a# }3 V9 n6 D1 e
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。& Q5 A6 }, l5 o3 D y+ q4 P9 _
以下说明如何通过C# 注册、注销COM组件。 1 F% b# P+ I( u5 v
5 X3 p# ]9 i/ T& `2 p# m0 i7 Y
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
% y) {0 I! |# ^3 R打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
! V- K8 }! m9 L8 q' D* i0 ?8 G创建完成后COMLib项目中将出现后缀为.snk的签名文件。
Y+ V5 W5 S( j" n7 t最后,编译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文件。% o/ f# U) e2 n$ a8 n% x
卸载COM组件:
- |( A$ D# h, o4 ^与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
4 r& e2 V3 L. G) h G2 m3 E
% T1 w& K3 ~7 V8 G; m( {
# U4 e3 f. f+ Y, `0 \' m6 c2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
" `( e6 E& F7 m+ j$ p8 m/ U/ u+ J' D% T; `7 n
名字取MEI_UseCsharpCom,点完成
' O. {8 v0 C: ?: m* j/ t( j' ~8 D
2 G8 j$ R: ]. F" A* ~把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.
. c( b' _/ B: X9 Q: v' E5 d8 K; ]; J
& f" P* O5 d% p* Q, j' o, N o我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:# _, W, f( h# r% f/ T
% T- W( P2 ~2 R; D: `" k- o8 D1 z% i% o
#include "stdafx.h"! o4 ?) ^# F4 Y% _* z* ~2 W
#include <windows.h>
; C8 a' l U2 F/ s* `; N8 A. A#include <string.h>. @- h5 W! \, v4 c
% l: f, j8 }- n- Q#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
( Z n6 m( a8 f6 }9 A2 B2 N( W& q. N Z% \
char* WcharToChar(const wchar_t* wp) //wchar_t转char*( {" Y( W+ i2 O" i5 Y- {
{
1 `2 u+ F7 `# q! w: ?, Z6 L char *m_char;
J8 q9 Q6 i4 r$ v l+ D$ V int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); ! r$ W8 J8 D1 ~' D
m_char=new char[len+1];
+ q" Z) y# Z- O- J3 Q9 { G WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
; p# k* z" ^ {& x; R5 ] m_char[len]='\0'; 6 w" M' K* P4 o& @7 O
return m_char; ~6 A- d a7 {# `
} 6 B2 Z }, L: e9 w
wchar_t* CharToWchar(const char* c) //char*转wchar_t
7 I7 |) B/ d) y6 M' b7 o+ C6 u{
7 |+ |1 R2 B T, c2 q wchar_t *m_wchar;
: m" A! o" E/ G% o0 v int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); j$ `- G' v; x+ Y" F- k5 o
m_wchar=new wchar_t[len+1];
( n% t; \( i( G! p- J; \ MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len);
9 C) N& @- }" H Q m_wchar[len]='\0'; . Z L0 j( t; v9 |
return m_wchar;
) l) }4 I1 Y7 T% r}
# x# T( @1 N1 c' H" c5 C3 h% K* I5 o; v: e' _1 t6 G
void _tmain(int argc, _TCHAR* argv[])( w- Z/ s. _! J1 J
& P2 F( a; R; S7 x9 b{
( X3 ~9 O# h y' s! F- s/ H( {3 {% W
CoInitialize(NULL);
$ r1 M1 E% M: ~2 Y0 T
/ O% x' R4 W9 Y+ K' @( C MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针' E( Z8 Y$ V8 X6 }4 W# |
4 R1 i: W6 s/ H s# r. W3 n$ P
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
" L4 E2 U$ ]) v2 I
# G; m9 p3 M& d2 } //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
+ w7 D& ^) Q( C7 T6 N7 Y) [3 h
4 D I' {* V7 H' k+ d& ?$ R //来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.0 y0 s: }' r( B- [" j
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果# U. v& C0 `: p9 M& A- S2 S& u
( N d! l. H4 Y! S& g b w9 }
long a = 1;
, B7 I) _$ T0 c$ l( t+ I3 k
8 U1 p9 r% s: o5 j long * lPtr = &a;
: H1 @: ?( L* {& H+ s& ~4 n- U! A; N% L0 I! \$ _. H) M
ptr->Plus(1,2,lPtr);3 R! o, `- {: `
; \+ t* J |: ?5 y+ W; J7 d0 j
char msg[132]="";' m; E/ T! j3 Q
sprintf(msg, "%d",lPtr[0]);- N8 z3 V. A, Q' F {$ U$ |
" b9 u: J$ k. K, s/ C$ Y
LPCWSTR str=CharToWchar(msg);
' X, ^* d, R: Z3 v5 B9 G# k( A0 u. b
# o/ t- q4 i7 {* q/ s) R MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
9 K; u- P& x6 `5 y' [1 O. Q+ [$ w M0 K$ r4 m
& ?. q! k) X/ Z- G( z- }
} k7 G7 p/ |2 k y
3 I+ ]- M9 j/ G& r3 N! H' S
此时就可以正确运行了.得到结果3; c" |' a4 v% @* b
' j+ l5 A% F6 K/ [, [如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
/ q/ ]$ L! }, E! W
3 s. b! ^6 G! l7 |3 v |- Q' [: ` e/ k
--------------------------------------------------------------
0 F6 h: n5 B& n7 XC# Npoi库 操作excel 的代码网上很多
2 }! x" [0 w; F
( I, V+ G$ b/ U// ----------------------------------------------------------------------
* t+ F* X& e: E( X// 使用Npoi创建一个简单的xls文件,写内容
9 g/ m ]. o! ?' G9 B6 ]
3 x. z1 |: P. f# a& s! `using System;
+ r+ i8 S6 f% `9 v3 w) T% l, busing System.Collections.Generic;5 ?8 @1 m6 M- a; ]# Y& H9 _3 T
using System.Linq;! Q8 A# @; y6 B) H) |$ D3 n
using System.Text;
$ W% i2 a7 L* E0 ?, `7 F: ?using NPOI.SS.UserModel;
+ W: I- w7 J5 A2 o8 U1 n5 Y( Musing NPOI.XSSF.UserModel;4 f3 P6 {% G) T$ q- y
using NPOI.HSSF.UserModel;
C+ v! x+ s1 v4 vusing System.IO;
7 z% O7 ?7 T- T y) A- Musing System.Data;* ] w7 U% _5 C1 x
; w; \6 M; l& \' a2 p
//using System.Windows.Forms; 5 o8 z8 _# \! \+ J! b/ D
+ m1 d. ~* ]7 s& C+ `
namespace CC3 ]" X7 {0 ^# w9 u, w! I
{
. f- R3 B6 n7 t# h
3 e2 J. K2 q( o class Program
7 e" z: E' k( a) P {& ~; v: z+ m' |5 A
4 m: P$ {( [, d$ ~- Y& w; }9 C2 V- G" u
static void Main(string[] args); p7 n2 X6 G8 u- P* w
{1 @) x3 O2 J: a% k. t" z* \$ F
//创建工作薄, E& k+ y# n4 y% c! D3 D2 G( V+ s% M
HSSFWorkbook wk = new HSSFWorkbook();
0 c% M+ b& k0 |' k& I+ n$ ]% s, z //创建一个名称为mySheet的表; v5 X/ c; `" G5 S# k
ISheet tb = wk.CreateSheet("mySheet");
$ h7 N' k/ w% m, ` //创建一行,此行为第二行
6 Y. d9 `0 s/ u: J IRow row = tb.CreateRow(1);* p! x/ o0 G, K' a* ]+ r
for (int i = 0; i < 20; i++)
3 t$ V0 e" |7 k+ Z# ?7 v {
% T5 L% p V( q2 ?0 w ICell cell = row.CreateCell(i); //在第二行中创建单元格% ~" p' W4 ]1 k" d) w
cell.SetCellValue(i);//循环往第二行的单元格中添加数据
2 n ]5 b9 E m }, _8 ?1 V: {: W3 k1 l, v2 V
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!% M X5 V4 {! h$ }) A5 N% X
{5 i, J* i; C4 p* Q; A0 X
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
7 \* T% j& {9 Y! J // MessageBox.Show("提示:创建成功!");
& g! \: T( |: S& I# c! O }4 b+ O" u7 a! x' H+ q/ w
. ^6 o, p$ l1 m- o6 j9 I } Z* Y/ V* c/ c
9 L' l: }4 ]( E+ [5 C: a* K. r+ ]" m+ x+ M6 {# c( |7 H+ u# g) j
}
$ N1 Z: }# k0 Q7 V3 D# s) S% f' E* z% i
' Q& O1 ]) m$ s# |% ]/ O6 R; A; v8 S1 ^0 T |% \5 C
}
7 W$ I) Z& {2 Z: C p; C0 K( w( o* @0 V5 D
// ----------------------------------------------------------------------9 F1 q. ? F& P$ U8 F/ M( k; w3 j. {
// 使用Npoi读一个简单的xls文件/ D, t# [7 M/ c. C0 I4 w4 f& a
* T2 G+ f: P, N* ~/ r* w) x8 Lusing System;
! R. k: U' e1 J$ a) [; N5 husing System.Collections.Generic;! h! v; i8 @$ I0 v# n+ Q: ^
using System.Linq;
O% |2 @0 m' `4 u) _using System.Text;0 C- X5 B4 O9 d8 q4 N% J
using NPOI.SS.UserModel;$ O) \1 R N: m1 P$ ?+ M" w
using NPOI.XSSF.UserModel;4 E/ U+ u S% O1 ~5 [
using NPOI.HSSF.UserModel;; U$ h" ?8 i+ l+ d) ]: S; h
using System.IO;
" m0 U. M4 {. E. ]. q- u% musing System.Data;
& ]+ w& F# G( V M* p* |6 g7 f/ d/ Q
0 ?7 Y* i k- u. H1 E0 Wnamespace CC, {3 ]1 V1 i4 |" }
{8 S$ \1 I4 l5 h
: Y* B: V& S) j7 A! K+ m
class Program& H, M" k- k4 O4 \
{
' z1 l( `. z2 L3 R9 P1 u* A3 Z" J3 [8 j* U4 }- h" T1 k: c
6 V$ S/ z& i4 w static void Main(string[] args)
9 g4 W B# a3 s. s' A7 H4 N {
- s7 ~. L8 c! O8 Q StringBuilder sbr = new StringBuilder();
2 t& c) d: Q: y" g1 | M using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件7 [( }9 Z+ \( D. x$ ^
{
. B7 E$ U. e7 n8 Y! i5 m HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
" t) p7 _* n/ T! z( @2 Q for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
% l$ ]5 V" O7 n {
8 C% d$ }" M0 [) Z) | ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
# G5 g$ n1 i5 S, ] T for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数7 ^0 M- \, X4 g' ?
{
5 O, d$ @- |" z H) U IRow row = sheet.GetRow(j); //读取当前行数据! \; E( s$ S" j0 m' w9 P: K
if (row != null). K- ~/ C O2 b- y8 o5 a( N3 s* W
{
' D, ]4 C: [) X sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限; K, I) `& X* F0 d
for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
* r. |/ h( q8 B, f* S {
6 J, }# ?. {2 b# w+ j: K5 A ICell cell = row.GetCell(k); //当前表格. _3 t5 q* E- x
if (cell != null)) c8 D3 g+ l. }8 I: Q
{
3 a! }6 z. E/ t3 S& m sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型0 k* [1 d- s# b% }! S$ {% \- m
}7 l1 F8 `8 G- `. R( R( H: ]
}
( d4 [6 N" Y1 y0 ~* `& u. Y }2 I, Z& F) c U4 \! P
}
" o* E/ K+ M: ]% C- z0 y1 V$ G) a }2 d, p7 q2 N/ t( q) R
}
* t, ]* J; b0 [& g: Y' G$ B sbr.ToString();. c* f7 F% g$ O% G
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中# g! r x3 \% Z2 H! V& `) n
{
% m) }; e4 q& W x3 u wr.Write(sbr.ToString());
5 p4 \4 M2 |& h" l( y0 ?$ I wr.Flush();
( O" |; T8 b, a8 _: L. ^$ \ }
! ? K5 N- |( h9 N
' m4 o* u# S! j% i3 h* y: T, r( v* N" Q: j/ p* N( h
}
" m/ \6 o# x* w( F1 f! n0 V
" L( K' { v/ F! {/ l# [' ?3 M v! V* F) c4 S; ~# R, |6 e
}
% l5 W P# t) |! Q( Q
9 r# \* Q1 _- d2 U4 N% {& P, B* f+ {- Z$ Y
: h0 V: |3 t) q% ?# {# _
}( D" c, }) E* S
" K4 A) Q, r0 s$ y
' x8 s& p$ @. A; a然后 自己封装 给 c++用
- K! m% G" l3 P, ~, j8 {
% b% l- q" v2 Y. p2 I8 u
$ P# I' ?( ~/ A* b& e. g8 P( \- c9 `2 A/ N4 e2 p
( P9 q0 B4 d7 ^/ F# A# F# h6 g
; k: J( h* V# ^% T, X8 k7 e8 ?) l
6 Z) a4 t: r3 s6 w' ~8 j9 x+ e
; j: G$ F* D/ R* E2 l: y' b9 X3 u# z% B* [/ Y# w9 P/ f
& i+ Z8 t& J& t8 J
( h/ \$ s1 e# m9 O2 G8 i; ]0 d
. K+ I7 ~& J- p, i) t% e6 R* {
" i7 b5 f/ |, m' ~6 Z+ u
h1 y9 B0 t2 a; E' {# @9 _# F$ f9 \0 ?8 v: z; r
/ c" n8 J; L! u( Y) [! l0 b8 q
. ~8 v3 Y' [3 g3 H( b+ N% P* z7 x* y4 g' a1 W4 g1 B
% N3 ~& A* a4 E2 X% p, n6 ?( F3 T' }7 A5 _4 J
0 i" R6 d, r4 L* L& h5 g& M
: Q. |3 ?. p- m2 s, m1 {2 M2 I
@5 q0 \: r2 G% r% A& s
, `8 G8 j0 @' A, R) E1 @" \ |
|