|
|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
# j( u( \! x% @7 n3 b0 w1 Bnet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)
6 A7 r' C+ d% ~9 o( |这里我用c# 生成 com 组件 让 c++ 调 : S2 h B9 [. A" s
, m$ |. x- D0 O5 t* S/ F首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)4 k! W0 M+ e6 {0 h6 A
C++调用C#的COM组件(DLL)8 X/ D7 L& D# l) T
! t8 g9 C$ D- R& K
下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.4 \" ~) m F7 _- U
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.9 |/ \ z: T& P$ Y! b/ ]' R
/ S9 A; X+ Y3 Q" _4 D
* U/ I3 m- X) W4 |4 X6 t1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom3 g' V/ @( m: N6 F6 @" M3 r
- P, D/ o q A" b2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
7 |( ^1 e7 p/ I4 L( c2 o% t0 L+ r' @4 T/ a- N# [
具体代码:
. _ b& k2 O; q& J: Q/ `$ j8 g, M& a
using System.Runtime.InteropServices; //记得加这个命名空间! q; E+ _8 k) Q' K" }8 y& b' ~
. _5 m6 m0 D! H
namespace MEI_AddCom
! F: V: C: V2 i8 z7 P' o
& |2 u6 k# \4 @{
( n$ l! T a/ Y; |. O6 n7 k4 H
# M/ ~$ O2 S2 d: d5 W [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.1 B1 I, L4 w" ]( B
8 n5 \0 W8 p" R# @, N
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
! E4 R" c/ w+ R% m; e* h% d
+ b5 m1 e, ~# b8 _3 F [ComVisible(true)]
) X% ^2 C# g9 c6 G, P- N1 N. V9 {* [3 ?" s% b
public interface MEI_COM //记得用修饰符public
' t Q8 K0 f) g# r7 o* o
`8 z6 R% Y: M" V. @ {0 m+ L. W8 i8 _* U; \2 _1 `/ l
- F# }% M/ P" ^$ l
[DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面, v( B, Y& C" ?& x" ^
1 x) J/ B+ e+ l- X5 B5 j3 }# h: } int Plus(int one, int two);0 p! B+ f# _- M2 U( L
) ?- c$ ]2 ? R- a; D. Z' J: X
}! s; X. W( } K- b
8 T8 p- @5 u- }" p: \( }! _
}
) v" s y+ L8 F3 h; M/ `2 |
. g; O7 w9 b6 c% b
0 ?* t. t) B+ |5 J6 ?; R, l1 [. K
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码
) ^2 ~. C& T/ R& I$ m; b6 L8 `( f: w( t0 H9 @7 P
using System.Runtime.InteropServices;; r- Q6 w4 C* ?+ n, ^
# @. j% R3 s( Y# i5 B H& Tnamespace MEI_AddCom
, w4 S0 v- b6 l: b) D. Q1 ~7 {' f, t+ l7 E" y
{
6 z8 `- N2 ~, D/ K
# N6 n" h' D5 f [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]1 O9 ~; L. p% a. h
( `- a6 Z4 a& G& [: { [ClassInterface(ClassInterfaceType.None)]3 H2 {( P7 L1 s) S
4 s, ] H5 c! C j; r8 z
public class MEI_COM_T : MEI_COM
6 \$ R+ [( Y# X$ Z) t4 z# `0 k4 F9 X/ U. Q
{! ?2 }- a, u2 Q$ S' Q) I$ r
/ J2 g0 P' m+ ]) y+ c public int Plus(int a, int b)2 _, r4 t* T; C( X
) t5 o' A ~/ P. ?1 I" L" c {1 ]# C4 S& d" Q, g
" Q, ]* [" C& u( h return a + b ;
D O3 T8 m }; Q1 n$ `% c4 V$ T& K
% O2 R/ S$ z! A1 t }
/ w( {( R2 D5 b0 \* Z
. K3 a5 D4 Z+ v }
8 t0 I* G5 V" n, Y( D' n
% Y$ V2 h# }9 V; R+ M0 ?( t3 S( l}
6 Y( t" W! G9 k6 D. A, h
, l9 z. S" U. Y+ U1 a) ^5 X. c. n) R$ B2 ?
6 a8 p- @, ^# Q5 B" E) H
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].+ ]5 U' S) F4 z" B& }5 M6 R1 A' H
) A3 c: O% N0 n右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册& k2 S& ^, l" @3 I+ L: B
4 O* m8 I' }, [
4 G$ N4 \- X5 w* I5. 生成->生成解决方案5 _$ e v0 ]3 } B% w
注意 这个时候 生成 非常缓慢
7 D$ C$ s+ D8 U: f% @ 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
3 c6 b; J' P8 V* {. H0 v4 |0 G( S0 X5 n7 X1 ?& L
, @& ~/ U: ]& s$ d---------------------------- V4 X1 h4 T, P8 c4 u* }5 r" X
" |5 M& t) c5 X* ~
1.调用前要先把com组件注册才行.1 h g! @. U6 L1 C
! }, X: `3 ~4 x/ U% f8 t# M
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
4 v& g! B3 B0 ]1 Y3 `9 m" a3 s以下说明如何通过C# 注册、注销COM组件。
/ `4 \. O$ F% J3 ]# s/ _' m
+ K& B9 B; A$ J' r9 t, I. ]) g* o为了能让生成的DLL能够进行COM注册,需要进行强名称签名$ C5 ^! @* j1 T6 q; j7 H+ b
打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
/ p) q4 A8 b: I9 U( k创建完成后COMLib项目中将出现后缀为.snk的签名文件。
. J. w6 E0 c1 n; h7 U9 U0 R最后,编译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文件。
: R$ ~' i3 K6 G) r/ A卸载COM组件: . Q2 B8 V& b3 p2 [3 {! E+ `
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
' V1 R7 m k' `1 E7 d% L2 s L e" i; ?4 |, K: k
- D$ x. I9 }" h) l2 u2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
1 _' M* Q! H) D6 }* u# p2 R l3 L3 b5 |0 O- \4 Z
名字取MEI_UseCsharpCom,点完成- K" j% f* |3 J- I, _" b7 R4 N
1 A' g1 v' d1 S0 a& {把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.
% K5 ~8 }7 X3 J( Z; B, a7 C$ x
' _' o: s% `( ]( |. R2 q M! Q我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
7 `" P! A8 X. D) O$ s& A* q0 A. b( n9 X# A
# [9 l& r7 f; E y1 m
#include "stdafx.h"' e% e- s5 x# o* t2 R; L0 B
#include <windows.h>
' l" Q) K0 j( R' [% {#include <string.h>
7 c* B& \+ Q$ ~
% Z) ?7 O' h) U2 v, ]& S% n& h#import "MEI_AddCom.tlb" named_guids raw_interfaces_only2 [; E, L* V4 i N8 l& g
0 _$ F9 K: d4 w
char* WcharToChar(const wchar_t* wp) //wchar_t转char*
# @& D, c5 P( g) q! u{ 6 \, g& D& M5 D3 @. e, E
char *m_char;
4 J4 D9 g Z6 S+ z8 E- I& k int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL);
' F# g6 K4 m) O9 Q. s0 u m_char=new char[len+1]; / e2 [% j2 [7 p) g
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL); ' M/ Z# L7 ~! p
m_char[len]='\0';
$ \. L& u1 G( L- U' a( m return m_char;
; t& d7 E2 `5 J2 w* [4 f$ {}
$ i" N9 k# j2 u( Dwchar_t* CharToWchar(const char* c) //char*转wchar_t
4 k4 i& {' ?, B{ % t0 ?, t+ t' @- x' X
wchar_t *m_wchar;/ L9 E; _5 E) y
int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0); $ [4 R1 c/ I' \) X8 V- j
m_wchar=new wchar_t[len+1];
( c& r6 Q: |3 O: o9 [! Z1 P MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); ; d* [6 ^8 n/ {# y; ?
m_wchar[len]='\0'; 2 b, p9 b! j- U5 j! a. D
return m_wchar; . o7 I! Y! s7 z+ R h
}
9 m" w" M* e8 k1 V7 Z+ l+ M# z/ ]7 v4 n; V4 D+ C8 x
void _tmain(int argc, _TCHAR* argv[])% N* E! v4 u U% O& B
4 _+ C$ W2 O& q h0 s8 i{
" F" U6 k$ \. e1 N5 E. V% R. G: P/ @% i
CoInitialize(NULL);2 L& }' D# q$ U7 d& T, j x! X8 a
. B3 _% M% I2 O! x
MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
# s1 ~. T' [; r, s$ g; g' E: M! ^% J( I) e# s6 O" K2 t/ A
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名
, Q8 Y V" z" M2 M5 O* H7 ~# U. F& z6 W0 c% o8 ?
//这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
* X }% X; b7 X, }8 g; w2 u6 D$ ~& V4 n4 W1 K
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.
; L4 O* g) o; X/ v) U //这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
% y' J/ ^2 u, K; E- [2 v; L) H% `
. L$ D+ e1 r* b2 [% T/ P long a = 1;$ F* P1 [3 A' A0 e
3 |( j4 u2 P* u0 E7 S8 u long * lPtr = &a;& \# L, u; ^; `
0 R e# o7 |! o: A0 E6 t
ptr->Plus(1,2,lPtr);
0 \0 ]& M# c7 G9 g% Q: K: t
- v3 K% v- P+ e! Q) Q$ i8 { char msg[132]="";
/ K$ ?- s( M. s4 e2 J9 b5 X, @ m `8 F sprintf(msg, "%d",lPtr[0]);
0 Z8 R* n6 @2 r& V1 L( g+ t+ m* Q$ u& R2 i1 Q) v: C/ r/ Y
LPCWSTR str=CharToWchar(msg);/ {* I% h5 W; z8 T1 D5 V+ @0 z8 B
; V& c$ Z8 g$ u MessageBox(NULL,str,_T("123"),MB_ICONWARNING);9 F" C4 G& O% E. g* }- _- D* S
# P4 E; ]) Y( _0 m+ Z, f% K0 f
# p/ M2 s. A7 ^" a}- R* V! ]% @8 r: w1 x) T
5 ]# n9 }- w! H0 @4 O) _) {此时就可以正确运行了.得到结果3% b' |: n) m8 C0 I
C% P$ k4 e, X% L$ g r6 I0 j9 |如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
! l' w& B: C" j, p5 v
- z1 @% t. M) n3 c
9 o$ l' Z6 l6 U0 q--------------------------------------------------------------
3 F" B7 B: W5 k9 \C# Npoi库 操作excel 的代码网上很多
" W K4 M+ q& ]* }/ [! S' d9 z! q$ Q! Q& D( V/ S3 D
// ----------------------------------------------------------------------
) T/ ~4 ~2 D* g9 k* _9 I/ \0 T6 z// 使用Npoi创建一个简单的xls文件,写内容
$ e2 M H: {) L$ T' G6 C" _2 U+ w5 d9 r4 h6 n) B
using System;
# [. }6 d2 W4 P1 E& uusing System.Collections.Generic;/ Q. q& t# I; c6 j9 A
using System.Linq;
( h3 ]% }% n) _& g, p* Yusing System.Text;
) x, d& o Q7 B% J. Fusing NPOI.SS.UserModel;
7 X9 r& D" a; \% H* iusing NPOI.XSSF.UserModel;& c8 e5 r& l2 q6 n+ Q4 X' \
using NPOI.HSSF.UserModel;7 _6 Y1 u+ b( o( ^/ i- B. S5 K
using System.IO;
% b2 X0 L o }, z O" cusing System.Data;/ [" ]& `7 H- Y$ Q# i1 A: H
* X( N; Q+ x4 P9 J//using System.Windows.Forms;
7 d2 Q; H, E, r' V! Q% o" O6 `4 P0 A/ _' H; k: h
namespace CC( F# H: W0 r. _, o
{
/ T+ `" o% g9 S$ N! }+ M; H+ }% u3 `3 K( P" M
class Program
$ q1 J! z9 X, j1 s {
' u& s/ u1 q, p: r8 O# a
, p- k" r1 \" E0 T; r7 F' I- s2 K$ u5 e: g: Q2 h
static void Main(string[] args)
. N, [% S) R9 I( C' m, u {
# m( X1 W5 S6 @% R //创建工作薄
?2 V1 l/ e1 u7 [8 s HSSFWorkbook wk = new HSSFWorkbook();
* l! c$ f K9 _; ~: Z" [% G //创建一个名称为mySheet的表* r/ `: z, @# L+ O
ISheet tb = wk.CreateSheet("mySheet");
/ s6 j# k/ w* \4 ]. l //创建一行,此行为第二行
6 m+ N Q9 A6 ~3 z5 t1 k0 a6 s IRow row = tb.CreateRow(1);) D- h- H, F3 x, z; S
for (int i = 0; i < 20; i++)
9 Q7 ^0 K$ f# n {9 e2 X2 k/ K3 i6 v* z5 o5 @
ICell cell = row.CreateCell(i); //在第二行中创建单元格
) @. N$ _" s( D/ b% M B cell.SetCellValue(i);//循环往第二行的单元格中添加数据
$ R. |( b) K% S; z. I4 h }6 I9 i; J. l3 E
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!# ~3 m5 q8 _5 y W/ \
{
; y& f% Q+ ^4 G3 U wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。0 Y: M! b/ `* x2 r1 V' G$ r0 I! e, W
// MessageBox.Show("提示:创建成功!");# R- P: U! g# V8 t; D- W
}* v; u4 q/ P1 g1 ^; M" u- a2 u
! ]! Y: o# o2 w5 f
}
) _ C, k6 l+ Z8 B/ ?
8 s+ o0 @1 `/ p
" y+ S+ r: W% c0 M }
8 f9 y" I) I5 j- E5 E
0 t( m0 v3 S5 M
7 q( s0 n1 J, n/ M1 K/ P* K2 V# W. R: J: t4 ~
}
9 u+ n$ {* Q0 T4 u( I4 Q' z" d* S2 ]: f8 ]( B8 a. a u
// ----------------------------------------------------------------------$ f" p# S1 u8 x2 x9 x
// 使用Npoi读一个简单的xls文件
, s' {" C' { _6 ]! I% q7 B7 t% R: r* s* \5 [' H$ c% j+ P- k/ m
using System;
2 u# H. n/ i8 Y0 z8 d! gusing System.Collections.Generic;7 _, z) ~ V" n" v% ?$ a
using System.Linq;
4 Z" E! ^3 T f: ?4 T9 a3 Musing System.Text;* x; D$ x) ~* ?6 T1 V. {* ]
using NPOI.SS.UserModel;/ v' t6 F( {5 L6 u+ z
using NPOI.XSSF.UserModel;
: Y' H- I) e P# J2 M8 m- Gusing NPOI.HSSF.UserModel;
7 c8 ^# T# f8 Z0 F! A- o% ^+ {using System.IO;( f) M+ F4 F% a
using System.Data;
2 O3 T7 x6 o" ~4 L5 ?0 g, R; d8 S1 S8 l
namespace CC9 z0 J% h6 \4 j, [; n; X; i2 o
{
1 U: c0 j3 }0 D1 f5 i
2 f1 Y0 `5 D( \2 t( c0 c class Program
( d2 [4 m8 S; d1 L {
4 |: c$ ~. ?" \/ j" ]3 t4 |9 R! T1 A( C$ t
0 A( J& O: M1 E V4 K* _
static void Main(string[] args), |5 O ?7 j+ |% Y& W! u
{
- m# {) I/ C) a6 H2 G& Y StringBuilder sbr = new StringBuilder();% U/ g" O3 {, Y. T% J6 ]; T
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件: b' {* Q$ T6 x# ]/ J" R
{
! D) D3 Q% T( @8 j4 I! w HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
$ j& ^% B7 D m( B for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
O& Q) `: j- w4 Y, r3 j z, e {
$ Y3 h& S- |. F4 z+ z& l- u ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
' K3 Q) M8 [( p& p# b% m$ C. }8 ` for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数2 ]/ g" ?* }7 t
{9 P6 v) [+ ^5 [% U/ o- G
IRow row = sheet.GetRow(j); //读取当前行数据0 m4 b' D; R( B. h
if (row != null)
! {+ X" \- Y m2 ]. N {
4 R" V, G4 D: R/ O5 S- u5 L) K3 o sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
2 v1 d$ \, V1 m/ X. {) i for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
( H+ b; ?9 P2 d) R {' Y" N9 {$ O4 ?. h2 }1 H6 Q9 k
ICell cell = row.GetCell(k); //当前表格
! m7 w/ g" c0 k3 p+ S2 i/ v if (cell != null)
/ W% S- W+ [( f4 @3 Y {
% D @* B1 J8 v; `( n2 H sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型4 A- c7 k& ~$ W8 n5 H8 Z f
} z+ `; r1 V% R# O
}7 V1 f/ y2 O& G# D
}
( X$ K% j0 Q0 ^ X- _0 } }
& @4 ^9 P# a; }% m+ j( d" B }/ C, G6 g7 @0 `* Q
}9 k# G8 ~ h/ Z7 y2 n, Z
sbr.ToString();5 [4 T; g: D9 _/ [8 ^
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中6 w+ R- P; W0 w E
{
6 T6 q8 I7 m9 ]: H) m wr.Write(sbr.ToString());5 w: v9 d: o* P/ R) m9 Z
wr.Flush();
- _ f0 ~2 r: b ^5 G# a( v7 } }! h H0 Q* E/ A w
8 u& t- R/ a2 Q/ t8 M% H' t$ R
2 ?- B; Z0 }* I0 I! ~9 L, w# s }
8 ^. n: V/ z$ Y& }0 ?9 S0 b
& ]' {' G8 X- q( ` k& O5 C: v& R E- d8 X4 {! X& f
}5 z ], k i! Q% o0 r; G2 C6 A
* {8 z* _* {2 k" q7 y4 I
* c3 E) o7 e# O* Y2 u: ]% X% ]' E7 Y
}
Q3 s" ^* M' `+ `, Q; n* t6 y3 n5 j6 X
/ w2 n+ _! O( B Z
然后 自己封装 给 c++用
7 g Y) _. Q0 n! r; N$ [, f. k" H: F! V6 m
6 K. }' K7 I0 S$ U( F' W g' w/ z' V/ A" c" C
& V% z3 P! o4 m3 V" t( _% i) u3 r
& D) p }% P" T9 r7 T' u
# c# K' ?+ l% J8 p+ U7 z- a9 m5 U* j+ M$ a* }/ V$ W
# o U* I. @1 T4 E
' J3 X7 _( L! Y* L+ C$ E
2 r& l/ E3 L4 v) H% v2 l- f( N2 ?. g: u+ A
{7 i+ h: g5 N
2 P, b4 @6 g. m" C( B) t2 }: ]
% F( @8 r2 S* v, H* f6 J* f$ H
" i5 H3 Y) O6 B/ e
. | f& n6 `: ^0 A
6 J+ v7 ^, M8 s- s M5 @7 i3 N8 g7 z4 E& @& h
2 l1 m- V) l8 u n8 [
( \: x$ y; _1 a( P( w
0 m2 q6 g- g8 z+ m2 h; Q3 q: }2 g( l+ v. r
% O. e" ]4 N( s( C
|
|