|
请使用QQ关联注册PLM之家,学习更多关于内容,更多精彩原创视频供你学习!
您需要 登录 才可以下载或查看,没有账号?注册
x
C# 或 c++ 不用安装操作 EXCEL的方法:c++ 对excel 的操作 非常不理想 要安装excel 而且读写速度也慢
. T7 p# |. J$ S) C3 Q! C( p+ Lnet 有很多 免费的开源库 比如 Npoi库 (Npoi库 支持c#、vb.net 等语言)
; @! ^: P' j2 M8 e: `4 }这里我用c# 生成 com 组件 让 c++ 调 q# o, F0 p* G5 D- w! R
2 u+ ?* E r4 M3 b8 y5 {( g/ O首先要学会 c++ 调 c# com组件的方法 (和com注册的方法)/ x$ M1 ~( [# M% i
C++调用C#的COM组件(DLL)
0 R: A' T* o* v0 d. M
4 P; {5 d# a: ^" K( g2 j下面我举个简单的小例子.我用的是Microsoft Visual Studio 2012,操作系统是Win 7.
! ~0 r4 g$ I/ C ~6 K2 `! i首先创建一个C# com组件.实现的功能很简单,就是返回两数相加的和.6 P1 ?( Y, _* _* [" M. r2 n/ a! c+ |
# }$ {& a, c$ y% E) \+ O
3 {% l5 V, c' r0 G/ V1 ~
1.新建一个C#项目 ,类型就选 类库 .取名 MEI_AddCom
4 X6 Q. ~" r4 n' t$ U+ h; a+ k
$ ]5 \" t- d6 H$ Y5 ?1 z$ x0 w2.在项目中添加一个接口,取名MEI_COM.C++调用com组件中所有的功能只能通过接口来调用,不能直接调用类或函数
/ K- S" }" m# z5 K9 m m* e& _% R( o$ t4 F9 K
具体代码:
" k4 K$ n+ L* c* X4 C( B& j* @9 }) E& [' a; C
using System.Runtime.InteropServices; //记得加这个命名空间
5 F6 {/ w& y4 v' X
d+ C/ Y+ s0 X0 V9 Z+ Gnamespace MEI_AddCom$ I* Z) v+ u, T) \1 e
4 ?! _* y( P7 |" m* ?# j2 f) I- c{4 p4 _ \2 u8 o n8 O. j1 \$ g
; e A4 s5 P- n2 H. F [Guid("DA07B88D-29F0-41cf-B3D3-611010E6F3FF")] // guid的产生可以通过vs自带的工具.点菜单栏上的Tools ->Create GUID,然后选第4个选项.Registry Format.
$ \: w+ y b5 Y; G2 b# O9 j. ^' o& w G: B) T' G
//点按钮New GUID,再点Copy.这样你就可以把产生的guid复制下来,然后粘贴到这个地方来.当然那个大括号得去掉.后面需要用到guid的地方也用这方式产生
/ t# T7 q l5 Q* ^
$ w- T C* e1 [( G5 ] N( z [ComVisible(true)]
4 f' q6 Q* h- R' s( |2 R/ u6 f3 a' |$ |5 b7 I- j( q W' \) S" n7 E& K
public interface MEI_COM //记得用修饰符public: @+ {. C6 W8 j2 k' s
4 M6 |. Z2 N. ]) _
{, M+ Y i( @. F. z3 F3 z2 x
$ L) E% P8 y# K0 V' j0 Q1 E [DispId(1)] //如果还要添加其他函数就继续来个[DispId(2)],[DispId(3)]加在函数前面
& D4 D$ }, U' ?' \% `8 d p! a, p! V/ L4 W8 m- N
int Plus(int one, int two);6 n, d. L8 V+ h; d. \3 w0 C) k
0 L8 n2 {! X. l: U8 X# I% y% u }
% V: c0 t, n$ {6 O# u1 A+ H0 p# f0 N, p; r
}* G& r4 g: c1 d4 I
9 Q ^: W7 v, f2 Y" T$ K2 @/ S' c. G- i. c
- z9 @8 k0 y; s( E) l% \% ?3.添加一个类MEI_COM_T,继承接口MEI_COM,具体代码
8 T# H0 \$ z* n" B3 {' f; m, j
6 V% q$ {0 c! r9 |using System.Runtime.InteropServices;* [+ w& x2 B: s \
" N" m9 d2 l% i4 Z; w
namespace MEI_AddCom; A1 \4 q% w4 v9 R1 J8 e. M8 X8 j% q
9 L" r5 n. R* i" U! y
{
* K+ j, e( v& h" g2 q& r9 S: N9 B' ?
M0 \+ |5 r; T4 m2 v [Guid("04F4DC83-8883-4a03-BDBC-92D8630ECC1F")], g& O; @& L, i7 ]( i" d5 V/ Q
1 N, N7 k& ]8 ^; E1 P, I [ClassInterface(ClassInterfaceType.None)]$ Y/ a, g& a! _+ D" A ~) d
3 ?, ]3 Y# C2 Z4 o7 w
public class MEI_COM_T : MEI_COM
; a9 a4 n% k* a! ?( t- O, h. d3 D C) c
{1 d) @/ H/ u* Z- V0 q
% |7 j9 n) e' A$ b public int Plus(int a, int b): h) \: L G$ `. J# u5 T
* |* `! k' U1 J {
! [$ Y b8 k1 e' S/ U6 d0 H6 e* a% g1 |% o3 w! h
return a + b ;4 q" f6 r' S( g, c. X0 ^$ L a/ y
8 ?5 E4 {; B4 j( A! _
}+ L8 z" H7 t, Z
% l( O2 U- g. ], d9 \
}
2 u$ s2 _1 |6 x6 u- I% l- U' [2 N i3 t
}% f+ O3 r, J9 k! `
* R! c& O1 P1 X: R7 E5 [
[/ v* a0 r5 n" P
y3 p: O; a& q! W4 \5 r4.把AssemblyInfo.cs中的[assembly:ComVisible(false)]改成[assembly: ComVisible(true)].
/ j( U( e3 y/ f% \( Y: s$ O# d Y+ [* N$ Y, |
右击项目名打开属性窗口,在生成里,选中 为COM 互操作注册+ y0 o; @6 E( v0 }) p3 J2 Y& A
- a& U* M% V0 Z- a: O w1 N; q& l& `1 u( ]
5. 生成->生成解决方案
! v) [4 `) O" p+ y 注意 这个时候 生成 非常缓慢
/ M' F! G) h2 z7 b% X% s, i 直到 出现 成功 1 个,失败 0 个,为止才 操作一下面内容
$ t7 s; w: x2 b# I; [/ l& T. f \6 A* b
3 Z3 S$ t+ U1 g i+ \5 O( E) u---------------------------1 \ {$ I- L5 ^& a8 W1 C4 n Z
8 a& \# P$ a! ?! ^3 F" K1.调用前要先把com组件注册才行.. _1 b3 ]$ Q" v( I: [+ I9 B
# ~2 R# j& T* P9 ?. Q- T使用C#创建并注册COM组件 C#不能直接创建COM组件,因为其生成的DLL属于程序集,但可通过“使程序集COM可见”选项来支持COM。
9 _2 a- P& N7 C7 R$ z以下说明如何通过C# 注册、注销COM组件。 2 ^. H* W3 I# _" U/ f( L
) L! A2 ]2 j/ `3 V8 {
为了能让生成的DLL能够进行COM注册,需要进行强名称签名
: v, b' z9 O- c! ?0 P/ ^6 [$ {打开COMLib项目属性,选择签名,勾选为程序集签名,通过下拉列表选择新建,弹出创建强名称密钥窗口,输入名称,不勾选使用密码保护密钥文件。) Z. a# C- s5 o# h' }
创建完成后COMLib项目中将出现后缀为.snk的签名文件。
9 n& j( t- }% q/ b! T' i最后,编译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文件。
& |1 f4 |. V$ a4 M卸载COM组件: % }: n+ R7 Y9 B; K4 b( Z3 v) [
与注册过程基本相同,只需将命令改为“RegAsm /u D:\ COMLib.dll /tlb: COMLib.tlb /codebase”。
1 `# J7 w- d( O% [. {# W* k: ~2 v$ K: x4 t7 q
% }! q2 e7 T; r8 t$ d- y: G
2.注册完了就可以在代码中用了,先新建一个C++程序, 类型选 Win32 Console控制台应用程序
0 W% j! [" |# [/ B
$ F# u8 \: s; d0 A名字取MEI_UseCsharpCom,点完成
8 ]6 ]; T8 [. F4 N: } [+ [6 Q0 Q! i# c' k, x
把MEI_AddCom.tlb文件拷贝到项目的任何目录下.我就放在D:\MEI_UseCsharpCom\MEI_UseCsharpCom.
) q* G p( T# X6 r& P
' z9 q* L9 h& |4 N我们会看到一个MEI_UseCsharpCom.cpp文件,双击打开把默认生成的代码全部删掉.敲入下面代码:% d0 @9 z& G q- R @
/ Z7 B; A- {2 F& {0 d) `% c9 H: r& Z
' \3 l; C' ]# b/ a K1 k#include "stdafx.h"
+ u7 m: B4 W3 l- i& C#include <windows.h># }6 {) z' S; p1 _: h
#include <string.h>
8 ?: X$ P( @1 \1 Q( x
7 z2 V: a$ H9 @6 M) X* b#import "MEI_AddCom.tlb" named_guids raw_interfaces_only
; V$ P/ b8 S; x% i9 M) f( r" W, a; M8 E+ J# t, n& n O( n
char* WcharToChar(const wchar_t* wp) //wchar_t转char*
0 k7 O# A N5 e o" S% u6 [{
2 K- y; U7 V4 f) @; S- x! U, ` char *m_char;
* @8 P# R8 C6 s4 ]5 z int len= WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),NULL,0,NULL,NULL); ; |: ?. L8 q5 {" y9 q0 L/ R
m_char=new char[len+1];
/ P7 Q, @7 ? W& C) O, q0 ? WideCharToMultiByte(CP_ACP,0,wp,wcslen(wp),m_char,len,NULL,NULL);
1 e0 R. K3 ^1 H" t0 r) R1 w m_char[len]='\0';
* z/ @; J8 V" A4 P [ return m_char;
+ l, R' l+ d7 B# l/ d}
4 D4 y9 U; R: W6 V; hwchar_t* CharToWchar(const char* c) //char*转wchar_t
8 w. R3 B6 _8 E% y- t+ H{ 3 j% b& j4 | r$ z1 w
wchar_t *m_wchar;
2 q- B% f+ p* w) o( S0 G int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0);
5 `! y4 h, U% b/ b0 [) T6 n) z4 T m_wchar=new wchar_t[len+1]; , `6 S4 q! _8 Y0 z9 X
MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len); + } _8 C0 X0 m/ {2 `
m_wchar[len]='\0'; . i) T7 L1 c( n/ r6 O2 H, i6 u% D
return m_wchar; 5 I! Z# p( u, f+ ?% J' b4 y
}
: e: K% Z7 a& j f5 A: r: S1 y+ V6 h' i$ g* X
void _tmain(int argc, _TCHAR* argv[])) B% d# e8 q o5 [' Z* D
9 A5 ?9 Q+ O7 d5 y- [" @# ^ @{
( t! ?6 J+ t3 Q* v
) l+ L2 O* S7 N. e$ D CoInitialize(NULL);. N5 ]7 e; b( z4 N
) P) b- P/ [4 Y# n: Q- | MEI_AddCom::MEI_COMPtr ptr; //类似明志一个指向接口的指针0 H# t4 I- k2 V7 d; ?/ V
+ G) q9 q' A/ _. o% r ptr.CreateInstance(MEI_AddCom::CLSID_MEI_COM_T); //实例化一个类 CLSID_ 类名# w' m! X+ c e2 S& y1 k# e
+ p! d' a& L$ t
//这个地方有一点点奇怪我也还没弄懂.在C#中的函数是int Plus(int,int).但类型在这里都转成long了.另外就是我们不能直接2 w- d% [ Z# I# N; Z1 [
: X1 e/ H& u1 D6 c8 M+ O" I! U
//来个long a = ptr->Plus(1,2);这样得不到a = 3,反正会出错.* I! B" q' B7 ~7 H0 }" Y. l
//这里函数Plus的参数变成三个了long Plus(long,long,long *).其中最后一个指针得两数相加的结果
+ R0 L5 n/ m. q$ p3 S% D% [2 [& P- V8 s; J2 F
long a = 1;1 u3 G( G" j7 e* C6 w) l1 J
) g6 w3 n, ]: w4 H. ~$ z8 h* O long * lPtr = &a;
' o' S6 ^& X, f! ?, ?- v$ L' a+ f, j
ptr->Plus(1,2,lPtr);5 f+ H5 Y7 O I$ N% ?/ L, w
5 O* G7 K4 p0 R! _ m. q
char msg[132]="";, f' u* [% w' l# Y
sprintf(msg, "%d",lPtr[0]);
- ~% {; l# b# T; ~( y* h& [$ s2 D# |' V
LPCWSTR str=CharToWchar(msg);/ G5 S1 k3 J" T* s$ U6 G: f
" p0 b- A% o8 a" U MessageBox(NULL,str,_T("123"),MB_ICONWARNING);, t: b8 o7 d" b2 K
! }* D9 c- ~, r! I$ ]. y: }. E
. J0 F6 r; ? v9 w}4 H5 G) i& L9 [& U0 U% Z( ^2 R" ]% W
5 V! S6 x& f) `此时就可以正确运行了.得到结果39 V1 S6 ]1 y6 k
4 V9 t* O; Y9 {3 W如果没有正常运行,则必须把dll文件拷贝到有MEI_UseCsharpCom.exe这个文件的目录下.1 W9 r" J& W2 z
) y. h) N3 R3 @) r; n
( t" g$ P3 \" J! ?3 C! ~; \& Q
--------------------------------------------------------------
) t& w: h/ ]' m% {7 c7 |C# Npoi库 操作excel 的代码网上很多
8 l4 _: p+ e$ J: }/ I: W' E) {* k- e x9 O
// ----------------------------------------------------------------------
2 R& ^ O# I5 b5 Z T! [. G' E// 使用Npoi创建一个简单的xls文件,写内容
7 A) l+ {7 ?, }* M: C% O& L
) o3 ~4 O4 E2 R! R1 l5 ?9 zusing System;
. z8 P. O0 \/ X1 J( F' p" nusing System.Collections.Generic;/ H" A0 v1 ^1 L& O' O& k
using System.Linq;
0 F1 q, g/ D, U' A+ X5 Q: o2 ^using System.Text;5 h; |. @; U% O: q3 X7 h: b2 _" B
using NPOI.SS.UserModel;
I. v; p: \! A1 J8 e- v, d, d! Q- H8 Nusing NPOI.XSSF.UserModel;6 t4 B" L; P. V% F8 ?6 Z
using NPOI.HSSF.UserModel;0 ?- w$ c8 q2 L* e K4 [1 b
using System.IO;
: V( B7 j5 x( b3 D# Q- fusing System.Data;: b; }5 ^" r8 C% C
0 Y) H" W4 b! w1 A E" E
//using System.Windows.Forms;
" u! j" o0 L j/ f# X' r& d8 x0 w1 h+ y6 K3 I% d+ H% }
namespace CC
2 a* K N- z/ C' p" s: m1 y4 o{3 ?# v& R4 o9 @( J
$ a" x0 V- J. K3 z4 c" @4 S* C
class Program& v" G2 h( }, L6 l. I* p" m; V O
{" O4 {6 W+ ?2 r2 d
; B8 p. t, _8 ?7 t
6 @ a* |2 M: r7 Z# k! z1 I static void Main(string[] args)
; k4 ]; T8 g" J8 F/ J {5 u2 w( d% m# l6 q
//创建工作薄
& P9 L6 G% J, L; t+ @ HSSFWorkbook wk = new HSSFWorkbook();
- H- Y9 F) L0 P7 p k- ^ //创建一个名称为mySheet的表
" r [) Y' K3 c7 j# O# W3 w ISheet tb = wk.CreateSheet("mySheet");
9 M& V7 ?! ]' R6 h H% X' W //创建一行,此行为第二行7 C/ @8 n+ X+ X/ N
IRow row = tb.CreateRow(1);% |) S" i/ V: l
for (int i = 0; i < 20; i++)( P1 `0 [/ N: |* q! ^% s& v3 b
{7 H5 ]- t. t" H/ S- t0 g
ICell cell = row.CreateCell(i); //在第二行中创建单元格
' N5 g. W \7 Y9 V S6 ] cell.SetCellValue(i);//循环往第二行的单元格中添加数据5 M! v3 N/ V- U9 ~
}' X5 L6 N7 o" h+ l* B
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
! B0 O, H/ d% ~* g {6 @ w7 s+ \ l: f3 n7 h1 G7 U
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
' C! T; }! J' z# C$ F+ c5 t! g$ T // MessageBox.Show("提示:创建成功!");
) G, @3 l# f) D5 ^: O5 y* c }, o0 e0 }0 l9 w* e5 j
9 w6 D! G8 _. r1 y$ |4 F, z
}
: s) ~( B; [1 O9 ^2 ~8 T% x
- `/ S" J/ u( j* Y% O; ]; L3 B7 T7 ~) p0 M( }9 |5 S" O
}% H% v- C# r R" N2 `
) n+ n/ j; A4 ]' T- N. c: F. g# W+ a- p( `
. ~" a4 F1 r; D' n& r}
; r g. \- ]3 l! f6 T& C' T/ E$ r" q" \) |
// ----------------------------------------------------------------------1 n, Z* b* H6 x4 v; ^" C' i3 `( \
// 使用Npoi读一个简单的xls文件
, ~* Y1 t6 d, ?: q) G' X( c O/ Z8 E% O! S
using System;" @9 O8 _& H' G0 {4 t
using System.Collections.Generic;- N! o" x1 g R
using System.Linq;
/ G$ m: f8 P: r8 x" J/ h* Musing System.Text;
) q% |' j( S! p" v! Z( Yusing NPOI.SS.UserModel;
8 }; a [" R" ?9 u- }using NPOI.XSSF.UserModel;
: V% ?7 e3 b4 dusing NPOI.HSSF.UserModel;
5 g9 d# m0 ~0 A+ T- Iusing System.IO;
4 ] e! `0 F. `8 `' [; Z, Z0 B3 xusing System.Data;2 v6 }) Q5 X/ @- V- {
2 U) D Y! Q* @" m% Y } jnamespace CC
8 Y/ f6 A- e; N3 P/ \! j. K{4 h7 G9 ?: y- N8 Z& t
7 g7 C' M( U9 x& e
class Program
) O0 M4 ?( b3 e6 o. I7 H, H {) b, z6 D' z/ Z8 r5 }% z
9 w; B2 Q! a6 _+ _5 i% L
, l! w5 m1 P" G1 [7 {3 J& ^ static void Main(string[] args)1 c) E4 M2 p7 E j
{, y$ I: w7 M4 a+ ]) k- `
StringBuilder sbr = new StringBuilder();' T3 p! o- u9 v# a# U
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件, e y: Y& @8 ]* a- B' W
{
# C) z- Q1 I4 V7 \- W" f4 y HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
+ m5 W- \- J6 n2 Q* D for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数# K" e M) X- e! l
{
; u& Q: Q! y# E0 S( i0 b ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
5 o3 Y6 e+ u, P3 d# p& ^ for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数3 n; o: W- T; Z4 _$ s" G
{
2 D9 S3 W1 R' }3 y$ i, A IRow row = sheet.GetRow(j); //读取当前行数据
% _5 p8 C3 i0 A. M4 U/ w5 z if (row != null)5 @, g% ~* Z9 \/ {
{
2 l' ~5 |; T" Z, \ sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
3 x+ d" m& y7 Q# }) l! Q for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
5 l0 H% Z7 O% E! V# ^1 v {3 U3 P! z% v& z" \+ ^4 D
ICell cell = row.GetCell(k); //当前表格5 U1 Y6 e" f& k0 D% U9 W& J; |' O
if (cell != null)
6 l* J7 L2 _* s) r. P* W { |" M5 W* `# K3 Y5 J
sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型
9 f; l# W/ H, L3 Y }- d9 V/ \4 T# H) _$ b) Z: G
}1 V6 S" d3 x( g3 }, w
}
% S% q; g& m3 d3 Q7 p }
1 Z2 d$ t) Q* Z" h' n }/ a6 b/ G; ]4 K1 [
}
; S! b: [. v' O1 K- \2 _ sbr.ToString();9 c2 }2 b9 `+ e3 Q
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
4 B1 n$ F' m: ^, W7 ~; Z4 ~ {. {- H5 \# `% G) T1 }1 A1 C+ C
wr.Write(sbr.ToString());" ], {2 }# Y. A2 c! F" E
wr.Flush();$ F5 u' w* A- P& v, [7 |4 n0 X
}
. H/ b' [& r6 S' A) ~3 }0 ~0 g" z0 Q I5 ]1 }
. t% ^2 V$ |$ Z6 @$ }7 @ G7 Z
}* R9 ?; C+ q9 W$ V# ]
: n. L- }9 O; c$ G7 r/ b
. G8 I, Z% T5 Y
}- i' |- P1 Z+ b' q5 ^% p) \
; i# G7 e! c Q/ ~+ i
. p9 s3 A) p- q
# Z1 b' J3 a5 l! h) J, n* M4 O% y}
2 r& B$ \0 Y/ g: L+ w9 L1 y8 G- B# [2 J$ H" ^0 N
a; v1 E9 U* T
然后 自己封装 给 c++用
' N6 ~5 Y; k- D0 C" f( y% M4 o; w, O6 I) e% n9 Y9 `
8 L3 D r& J, O( V" r1 s0 D; s/ ^3 _! t% K6 m# ~' x
" q. u3 A. d7 Z* U; g
% c N" ?& i: @5 B6 S+ j6 l6 a# |0 E) x8 W
6 G2 x# u; `' [/ e7 [$ m8 w4 o; [- ]; Y' w& y, \. q
5 @% o- h' d& Q; {0 O. ]4 S& e
3 `( g( M% K8 z* N! x7 \4 m; l" ^7 H& r. x$ h p* C
% q* R0 f* ~, F1 @. Z3 ~2 e$ @( _% o1 N$ D
2 `5 K6 L6 q6 C2 \8 J. q, }4 b
3 |0 S; P' b4 w C' o3 A- D
% q+ j( m9 X" c; Y% v5 a! o- r8 r9 g
3 a+ a% P# k4 o( `7 b1 b' K. [8 g8 M5 \. y6 j9 F! `3 H! G
/ N* x2 N, n! w& {4 V! ? ^* L+ G7 _
9 e- d( [% h' H% U7 i9 ]# d% d- K9 u5 M3 l! ^ G4 t
5 M! j: C7 A9 F$ {- T: x, P
0 {. D4 u) u/ G8 i0 l |
|