|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢$ a( K0 B8 K7 z, m
net 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)
/ d1 V; V6 G$ Y6 Y+ a这里我用c# 生成 com 组件 让 c++ 调
5 |9 K0 N! c+ ?8 a' J8 D5 I" b6 _, |- P4 o9 ?# C2 m
首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)& c+ |2 d5 ^6 L. u2 `
C++调用C#的COM组件(DLL)$ ^: q' W, U- G: V2 f9 O
! y% {+ | q9 n1 _下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7./ \% S, J9 `$ K. D
首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.
2 _; _7 t: G4 s5 u+ f- r) S) ?- I* F) K! g7 w: S
3 f9 Z/ L) @9 |8 R2 y9 s
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom
! e& F/ ^! V+ R. C; i. z/ x6 O% V( |! `, U3 g! B3 q
2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数! \! \0 o$ @6 a9 `
7 w$ ?3 ?7 g& N5 @. s* C+ x. I具体代码:6 a' r# R- |; o7 {6 O. c4 Z
/ S# w, z( e* W$ X; Q, s$ f
using System.Runtime.InteropServices; //记得加这个命名空间
0 H$ G1 K7 I" Y m0 ^5 h$ D+ a8 Q; w% c
namespace MEI_AddCom
5 M" ^4 v: j4 ~8 {8 b% W, \; d! P5 | H3 m) z$ I! Z: V9 s
{- k: N9 o8 D \7 d' O2 s
3 ?) _# B! X @5 H [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.
/ e0 z( _ {% G: n
" W: O8 Y2 F+ H1 x% q0 u //点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生9 ]7 X$ {. A5 @2 E
5 q0 l3 `# I) r& A+ Y# u [ComVisible(true)]8 p7 W8 q/ g7 B
% s3 u6 ~ \, E/ f9 W# h& a( u0 u
public interface MEI_COM //记得用修饰符public3 N$ t8 B o# R% ~1 C S9 g
' [9 m( C0 c7 J# ` m) a5 L
{8 Z7 S6 |: Y7 Q1 s
: [! j& A" v% G/ ]3 ? M3 B [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面
* |: R, @- M5 ]! X- y9 s
0 e$ a0 u2 z9 s9 C int Plus(int one, int two);
# U' A8 q; R+ h1 s& @7 k
3 r/ G% U# d) O$ O. y }
+ ]. h8 S; |4 q! x% h7 a3 c* [, Y" A5 A# r: I- N2 F: s
}
$ }, A) k0 Y: t+ i; _/ w
1 h8 t& k: \# J% C/ F
) r- {* m% ^/ x, F. ~9 n O+ o% n. O- Y- f
3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码5 p- c. ], D+ m3 d& D1 i7 G- K
" ^+ T5 B: @5 c1 ~using System.Runtime.InteropServices;
+ M6 _! K6 z+ |$ _
( [* r' |! I. C2 F; L6 N: gnamespace MEI_AddCom+ Y/ M- q& V# O* ~, P& a% J
, E2 S5 Q' [0 D{9 @2 d# A1 L5 _3 {6 d0 u7 k
! g. j; q' \8 m6 c: {3 p [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")]
7 _3 d9 _0 I2 x* x! i/ O: E: B' ^# B' _" j
[ClassInterface(ClassInterfaceType.None)]+ d6 U% o0 `& u$ d# \" p; b
9 s0 ^/ @/ K2 E# a public class MEI_COM_T : MEI_COM% V: G! u, a, J2 U
9 a1 x% m1 y4 h- K. f7 X2 ^9 W9 J( h {9 w0 p1 f v3 W2 ^% i, D0 ]
! S" j- u. s4 |" A+ g% F public int Plus(int a, int b)
) h. X7 E! A8 p# b' g) S, h# g- Q6 }# q
{
1 P/ b: C- L/ D
$ e9 g, R+ o7 F% G" ? return a + b ;, a( `* D, N( y7 n( h7 e
1 f( k7 A9 ~1 L( S/ V$ [4 g' e2 Z% }
}7 t8 Z% {& l( F% o1 B
: y. |# ]) d, W4 `: [ }
- `/ v! w& N3 ]* n t
9 ~/ U `0 I* r. z}
f @/ N/ n4 ]1 a: O: ~0 s" o( x9 P' M
% `9 K& Y. q+ r' c/ d' f' j; v- c7 z
4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].0 M& R1 m& o* I7 n e
7 O6 Q7 H+ V) A/ n% u右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册! g+ O; L4 m$ Y4 A- }- }1 s
; c2 v$ J3 V3 G
1 U; r2 Z: `; p* T$ ?- o7 W2 ^
5. 生成->生成解决方案
- ^6 @+ `) l* [! e! J( B: } 注意 这个时候 生成 非常缓慢
, {- F t' Y: q ?" h 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
% z8 M4 d+ _% i" ^6 X- n% z4 s4 l8 G1 `. z; g# H; I
9 |& P8 f: r+ V---------------------------
/ o& X. B: @6 ?8 k; {% Y
1 f! G& S: Q/ I) n/ b" G1.调用前要先把com组件注册才行.
6 E- Z8 K4 H8 {. E, ^* w( c; z3 {) \ g; V, F* I
使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
: v. n# |( O* B1 s以下说明如何通过C# 注册、注销COM组件。
4 `8 g3 G5 z0 ?2 V( W2 n- T
; R% t! T; }$ T- ^为了能让生成的DLL能够进行COM注册,需要进行强名称签名. _7 S* r, Z% E( J( \1 Z
打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。
! l. G+ q0 X3 X% c$ Q+ O创建完成后COMLib项目中将出现后缀为.snk的签名文件。
' _2 u* E2 |$ O/ d: g8 b0 }+ l最后,编译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文件。- w$ Q8 {" n! H9 L9 w" l
卸载COM组件: : m" ?. l$ v7 l) U1 N
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
3 n$ k% K% X' j9 }4 ?
$ Z9 m, R3 x* l& M7 Z/ }4 Q
9 J- p% i& h' H0 f `2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
2 F* _( x5 T* t6 M* b y# q, ]5 f$ N) X+ |. n5 }7 c, H/ h5 A& w# |
名字取MEI_UseCsharpCom,点完成2 o+ [) y% f/ _! `
+ @7 J' e- Y& L; F# p, w把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.2 M% ^8 m: K+ {
0 `0 i5 [# S3 F' N% A( o我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:
& \/ B/ @2 Q5 U' l+ b; _. q2 f$ l; F. Y. u, w# X
/ Q o7 F5 h# q5 I
#include "stdafx.h", h: P8 n( r- ?
#include <windows.h>" F, M* V# k7 t4 V7 U# F
#include <string.h>
6 J7 \3 J0 }' O5 I
+ K1 t: ^0 f1 y: I& K#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
3 c3 K* o4 S! J' I) @; Z- M3 G: B8 b0 ^7 t; n- B
char* WcharToChar(const wchar_t* wp) //wchar_t转char*( Q6 l H( j5 k: C N- Z0 A% {
{
* z" Y- ~- d2 F# O1 z char *m_char;9 L6 M, M8 a3 M$ `' _
int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); $ X- D$ S/ r5 C# [1 ?
m_char=new char[len+1]; & S' ?6 k: L) l5 U2 w- v
WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
! T9 T0 G, s* t# P) k' e+ t m_char[len]='\0'; ! X* ^5 j m: q# a+ H
return m_char;
- t. {+ r5 A1 p z) r* e2 I} - Q( v A) {% ?$ O* x/ D
wchar_t* CharToWchar(const char* c) //char*转wchar_t
, a3 ]' b8 _4 {" [& x2 L{
- l/ b4 C3 F& }1 ^' Z wchar_t *m_wchar;
( f8 B/ B- f& E0 c. n$ H% M) } int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0);
1 g' b* `7 \8 _7 ?. S m_wchar=new wchar_t[len+1];
( J; x2 d$ i6 H l- u MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len);
! C( ?; L& d! o0 y m_wchar[len]='\0';
& l3 k8 H$ \& A- A7 f0 ` return m_wchar; 1 P4 p7 c, M6 ?% H- E
}
. e6 z( A1 i7 ]% l, g n6 D; k# h1 H- v9 e( ]; |- U* X5 l2 Q
void _tmain(int argc, _TCHAR* argv[])' o: B9 Y" s3 t+ c
8 r( i: e1 n& W' L0 [{. N4 W0 c5 n0 y$ B* j! M( h
1 u6 h- q9 G& g* \5 B. B
CoInitialize(NULL);4 o# s, c+ y ]( S0 {9 @
* h( \5 y7 s9 i0 K MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针
- g6 I( `4 z- k6 M9 c- b+ t) L' z4 E$ `5 L. ~
ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名# e! F8 t1 q9 x# u
7 t4 T u) R' i% h //这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接
6 e% _& g, ?+ C2 k, A ^+ d) g0 l6 O5 E
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.' G5 ]- ^3 Q& t/ u8 ]
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
8 }9 F8 h$ C, {; Z8 C/ \
& O" r9 j1 A2 o long a = 1;5 U9 p7 z1 E! C4 Y5 A* Y# f
' q u- \* ^6 T: c4 V8 o9 A; P3 A! t long * lPtr = &a;
* h3 J3 y$ r' v/ \+ f8 D" {* n
ptr->Plus(1,2,lPtr);- n( ~; F6 M+ w6 c
* O! [ K' ^% K: Y6 a
char msg[132]="";
, t" `; ?1 y* o5 H2 x sprintf(msg, "%d",lPtr[0]);
6 f$ Q8 a6 G9 s- [6 W8 s: j
' `/ l$ O& X; t LPCWSTR str=CharToWchar(msg);
8 X" d3 Z; Z; W6 d6 L
5 p8 d# U8 M8 T& Y, ]) t MessageBox(NULL,str,_T("123"),MB_ICONWARNING);
! B; {' t6 g! z
2 [# P- R6 o1 l/ `9 H; [' K; `6 _
( W8 t" |7 c+ ~7 L; ?}
& y5 U, D- N7 j& g! i: K! ^) P- [$ _
' Z& N" e9 f4 E5 Y3 w- |* |6 u此时就可以正确运行了.得到结果37 x% \% f. Y" s5 a1 ]8 }
: @5 q6 m% E/ D* z$ Z) S如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.
4 e, y( ~6 A! A; j* n( a! w
3 u. _% F" A3 g& y- x0 E2 ]" l9 U& O! B' k: A. e" {
--------------------------------------------------------------
8 _ K# _2 u, A' k/ E4 HC# Npoi库 操作excel 的代码网上很多
; N1 Y8 j+ C- v. g# ?- j, {! `/ r( e0 {# ^2 s1 w, A
// ----------------------------------------------------------------------: {5 _1 T0 m2 @- E" x8 R
// 使用Npoi创建一个简单的xls文件,写内容
, B1 _, v+ B% S2 T, o
' g- @8 {1 r/ ?' E- ~9 k) \using System;5 O" l" E" U4 j
using System.Collections.Generic;3 O, Q E4 e- m0 P, H' E5 {, X; z) `
using System.Linq;
- ]: Q% t6 Z9 [8 `! R# Lusing System.Text;+ I* p4 v5 A) n4 `. X5 }0 ^3 E
using NPOI.SS.UserModel;! l+ A4 v& v! ^! u0 ^' E
using NPOI.XSSF.UserModel;/ b5 o2 n2 @6 C1 j
using NPOI.HSSF.UserModel;0 t+ Z2 ?& d- ~
using System.IO;
4 J6 O- k5 g% v) H6 @8 y! Wusing System.Data;
6 s* l& L- d$ _5 h' n' m$ f4 l% b
! t. \, l; r6 _6 \8 x9 \& U, q7 W2 b/ `//using System.Windows.Forms; ( H" G$ G+ }" \0 ~; c
' B+ i" `( X3 o0 d3 Gnamespace CC: w+ J0 `9 X% I4 r
{& j; X& r& z! G" z3 D9 |
: W; [3 i4 W1 ^- |) F class Program! p5 O, V# T2 I
{- V+ H+ \4 ]& ^. m* j8 @. c
3 P; y7 c7 X" {" a: D' v$ h7 a
! B4 M/ d" A: e' k, s* E1 H static void Main(string[] args); l+ D ~0 L2 D7 B
{4 Q+ \& k5 Q9 F' K8 Z) c
//创建工作薄
4 N W4 _- W1 {# ` C HSSFWorkbook wk = new HSSFWorkbook();
9 d& v8 g$ j3 |. H3 ^ //创建一个名称为mySheet的表: C2 t w+ y4 p R5 j6 J
ISheet tb = wk.CreateSheet("mySheet");
8 Z! f. n; @0 \2 q //创建一行,此行为第二行* p- f, q$ ?! J" |& a, \5 k
IRow row = tb.CreateRow(1);
' `- p& Q/ ~7 D3 v2 x for (int i = 0; i < 20; i++)
. o# k$ j3 \' G t9 A {2 Z' J4 G3 V) S# f
ICell cell = row.CreateCell(i); //在第二行中创建单元格+ _8 _7 @ C- V4 P/ C6 |+ E9 y2 V
cell.SetCellValue(i);//循环往第二行的单元格中添加数据
7 U& n! N* P8 s" H4 q }
: E; J+ C& `) h i: F5 y using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
9 L( K3 @2 s0 F% I! O {) U) i. g! F* h0 N0 ?. T
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
: E$ H! K. G& N0 i // MessageBox.Show("提示:创建成功!");
0 @. l& A+ D% A. o }: U I& n9 T" [
, G4 n( R, k7 {( Z7 [' F( p8 W
}9 J7 [! A% |* Z( h( h0 q
+ N% W2 Z$ X3 L4 h Y
# [3 R1 f( G& }5 I. H }; i" F* X/ @$ k$ i' t6 ]8 i. G
4 N0 A8 c' s+ Z
5 s4 k# ?' `# L0 ]4 n: t
4 z% I+ o9 U- p! t}3 i6 l6 O0 g% y1 \: h6 B1 Y
: Q" x [6 K0 o4 |! D// ----------------------------------------------------------------------
9 U: ]+ g5 q* d( j2 p// 使用Npoi读一个简单的xls文件- k {: Q, ?; h8 X
4 s6 p" \1 Y# Q) f, \. Wusing System;5 v5 R9 A! p! ?- J: \3 V6 G- t
using System.Collections.Generic;( I/ S/ [2 x7 l) Y$ k( F, O
using System.Linq;# V: n. T% C& }, j8 ~3 L$ a6 q
using System.Text;
6 H( b! R- _5 A |* ~: ]( n. m& iusing NPOI.SS.UserModel;9 Y( T- c6 B4 j: ]; G' k
using NPOI.XSSF.UserModel;
$ y# E" w- C T/ d. B) husing NPOI.HSSF.UserModel;
0 |" M; k w8 ^0 ~+ i# Musing System.IO;
) f; Q9 l' Q1 f0 E. P- ?using System.Data;
/ R2 B# q) x3 @
0 _: O$ l' g4 X7 a# e4 O/ Vnamespace CC
8 I1 `8 D" W1 }7 o; ^$ R; z8 \0 J' I{4 }; v. V3 M! a5 d# j; n' T+ T6 L* [* O
& W- {# l7 N" t' W( o* g9 ] class Program
% o! q4 t7 k7 s4 G; u9 Z$ _ {6 W' U0 x& j1 h9 U
3 |# {# ~- O5 s& J4 I
, i5 }; [+ N# @1 g2 ?9 I' R static void Main(string[] args)* ~! x7 k% y( x8 A: F
{& i$ R! a4 y) S5 ]/ l
StringBuilder sbr = new StringBuilder();
& W* }( G3 d# c6 q6 y Z using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
: R, k- a% t U# z9 y' M6 r {9 {4 V/ J. h4 M0 [' {
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中& i, r6 ]* i6 q; B$ w& H
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
" b3 U* i+ ^6 c; V/ H {
! \4 `- k. u# R* J7 Y ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
( T; z5 d$ B# v0 P; i3 E for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数- T1 W6 i, `3 Q
{
1 S' s1 w, `; x3 Q6 {* H" Z IRow row = sheet.GetRow(j); //读取当前行数据
" z5 l3 ?" A4 u( W& j if (row != null)
- |1 U' q @$ I4 ~ {
5 o8 ^+ e- D8 z' ? sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限( v0 Y `7 T* j, p- ^1 U3 |5 H2 D
for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
9 }1 l! v: u, S$ C, ~7 a/ D+ a {
* d, S2 e* B; K' q9 x4 Y ICell cell = row.GetCell(k); //当前表格! x5 n1 Z, w# K7 g* l K
if (cell != null)
$ ~! p/ R* R5 [! S# J5 R) I: D {5 O4 `# n% e. ?; i6 x; ^: r' O1 m
sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型
, B/ I0 [5 Z7 L. F5 X1 y }
" N- X9 B) a1 F! `8 d }
" A- A9 }+ ~6 A/ e$ K }
. _" S/ g6 @6 {0 P6 @) _+ }4 H" O }0 [) p6 j6 N7 a* A; Y1 V5 S: S* ?
}8 [5 P$ e1 @4 e4 v) x
}9 ~# |/ Z9 E) ?( h- \# ?- ]
sbr.ToString();+ ~) D( u( t' B- c, B W5 K3 J7 u
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中3 ~# Y3 H5 r4 Q# L* b. p( S0 s2 L
{
* Q/ e% P5 H4 K- ?* r t wr.Write(sbr.ToString());$ U$ n! \( h f e" Q* h; i" C" d4 z
wr.Flush();4 T& H/ c$ k/ p0 z- L8 ?
}6 E& A7 V# i% K7 F
: f7 Z# U2 z: F
; @% y7 R% X% E b7 W& U }5 q! m6 i2 Q3 M* i: h, F3 `+ q
5 n* G3 j9 w0 w1 m+ O' m5 N0 X# ~
}
; K: Y) N+ i& K% @1 G- M# k: N
* s" W4 C* r Y/ e) K0 o
" {# h7 G1 V* v1 F3 j; h7 E2 ?. g
} I* j% l; I5 f/ V
' c3 i8 Y9 _+ R0 a% Z
' `$ D" S, p; `5 Q9 _9 m然后 自己封装 给 c++用
: S0 w. ]& N! _. N* k/ c2 y, a' `) Y, F) {! i
* ^. l* I$ b: G& h$ x! A1 G( [0 u/ G2 M
5 _" }2 a. q! y/ d3 D. u) G0 {# x' b) g
9 y/ k7 r- C, \9 Z" t5 j* q4 f# R. x2 s
( v7 z3 Q* l1 D6 O* l
' b+ O! \. z. q# V5 q
+ y8 C' g) o7 X( s4 E
, Y& f/ @* {. \, \" B) h
+ z' ^% R, U: n/ q7 W3 I+ S! M2 z3 e! ^* R. V
4 K. G8 H. h; O! J! E$ B- ^ `5 \$ t1 j; _# i6 j+ g
9 `4 e/ y4 t* j: N6 q& C
9 Y0 G; ]/ m9 u
) y4 w7 k* _2 c# [ l
! L9 n' o3 K. H. D2 C" }* ^! N+ ~1 o# u+ N( ?# ^# ]
* r# e) G F* v8 F- L2 Q
) F6 Y7 f% Y$ O+ }2 S0 ]
8 J" g6 B1 ?1 C) N% ~ |
|