转载请注明出处:http://www.cnblogs.com/superbi/p/5482516.html
到目前为止,网络和官网上并没有关于libxls在windows下支持中文的教程,也没有现成的二进制文件。
想直接得到结果的请直接拉到最后获取成果,想自己以后遇到类似问题不用焦虑的请慢慢往下看
xls的第三方库目前能找到的只有libxl、libxls、xlslib。
libxl是商业的,对我来说直接过滤掉。
libxls只能读,xlslib只能写,对我来说知足了。
我也想能有一个跨平台的开源库能对xls进行读写,竟然没找到。
那就自己动手把,libxls和xlslib合并之后就能达到目的。
今天先来看看libxls。
首先libxls的文档不全,readme没有实质东西,最后找到INSTALL文档,如下:
BUILD AND INSTALL ================= * To build and install, for most environments: ./configure make make install * To build a native Win32 library under cygwin, use this configure: CC='gcc -mno-cygwin' ./configure --host=mingw32 --build=mingw32 --with-iconv=no MAINTENANCE =========== * To build versions for multiple architectures from the same place: - create a directory for each arch: arch-<arch-name> - call configure and make from within each directory * Do this when you update configure.in, or when there is an upgrade of autoconf/libtool versions: ./bootstrap or: autoreconf -v --install --force then: ./configure * To build a binary distribution, use the following commands after substituting the current version number (e.g., 0.30) for <version> and the current computer architecture (e.g., i386) DESTDIR="$PWD/libxls-<version>-<arch>" make install tar cvzf libxls-<version>-<arch>.tar.gz libxls-<version>-<arch>
可以看到linux下编译是相当简单,今天暂且不说,只是要注意是否有安装iconv。
windows环境的编译从INSTALL中
* To build a native Win32 library under cygwin, use this configure: CC='gcc -mno-cygwin' ./configure --host=mingw32 --build=mingw32 --with-iconv=no
说明看出来我们需要使用cygwin来进行编译。
接下来进入正题:
1、首先下载cygwin,根据自己机器选择setup-x86.exe 或 setup-x86_64.exe 。
2、安装cygwin下的编译环境,仅仅为了编译libxls我们安装以下组件:
Devel下的make、mingw64-i686-binutils、mingw64-i686-gcc-core、mingw64-i686-gcc-g++、mingw64-i686-win-iconv
3、然后把libxls源码放到cygwin中,建议放入/home/用户名/opt/下,第一次运行opt会不存在,需要手动新建。
4、在libxls的根目录(比如我的libxls根目录 c:/cygwin/home/fbi/opt/libxls)修改configure中的DEFS定义为DEFS="-DHAVE_CONFIG_H -D_GNU_SOURCE"(用来解决make时候的警告warning: implicit declaration of function 'asprintf' [-Wimplicit-function-declaration]),然后执行configure进行配置:
CC='i686-w64-mingw32-gcc' ./configure --host=i686-w64-mingw32 --build=i686-w64-mingw32
有的朋友就要问了,你的这个configure命令和libxls的INSTALL文档中提供的不一样,这是为啥呢??
只能说作者没有实时更新这个INSTALL文档,最新cygwin的gcc并不再支持“-mno-cygwin”选项,且host和build选项发生了变化。
具体的说明请见stackoverflow上此问题的第3个回答。
我一开始就是卡在这个编译指令上,完全找不到方向,只能用“cygwin编译”关键字开始搜索,然后查找到“-mno-cygwin”这个选项是用来去除编译的程序对cygwin1.dll的依赖。
剩下就目的明显了,直接把“去除编译的程序对cygwin1.dll的依赖”翻译成英文然后搜索,主要关注stackoverflow上的帖子。
当然看帖子别只看楼主采用的答案,往往对自己有用的信息隐藏在其他回答里面,这种情况已经遇到几次了。
如何通过关键字一步一步逼近自己需要的信息需要长时间搜索的经验和认真查看搜索结果中的信息。一般疑难问题的线索在stackoverflow上都会有。
回到上面的configure指令,对比INSTALL中的会发现最后少了“--with-iconv=no”
熟悉iconv的朋友结合我的文章题目就会想到iconv是用来支持中文的,想不到的也不碍事,这取决于自己的经验和知识面。
既然iconv是用来做中文支持的,也就能解释为什么我要在cygwin中安装mingw64-i686-win-iconv组件。
5、前面步骤正确的话,步骤4中的配置就会成功并生成必须的makefile文件,执行“make && make install”来进行编译安装了。
6、只要make没报错,我们就能在$(cygwin_home)/usr/local/libxls下即可看到安装成果($(cygwin_home)是指cygwin的安装目录)
安装成果中的bin目录只有xls2csv.exe,但是没法成功运行,原因就如提示一样:缺少iconv.dll,这个简单,利用everything搜索$(cygwin_home),拷贝usr\i686-w64-mingw32\sys-root\mingw\bin下的即可正常运行。
安装成果中的include目录没有什么疑问,调用dll需要的头文件目录。
安装成果中的lib目录只有libxlsreader.a和libxlsreader.la,并没有我们需要的dll和lib文件。不过可以利用.a文件最终转换出运行需要的dll、链接需要的lib及def文件。
从网上查资料得到此处能够通过gcc -shared能直接生成dll,但是我没成功,如果有朋友成功请指教,谢谢。
7、接下来我们利用安装成果中的libxlsreader.a来生成我们需要的dll、lib和def文件。
(1)在cygwin命令行下执行“i686-w64-mingw32-ar x libxlsreader.a”提取a中的.o文件
(2)然后利用.o文件来生成dll和def文件,具体命令如下:
i686-w64-mingw32-gcc -shared -o libxls.dll *.o -Wl,--export-all-symbols,--output-def,libxls.def -liconv
最后的-liconv很关键,否则会提示iconv相关接口未定义。
(3)利用dll和def通过visual studio的lib来得到链接需要的lib文件,打开visual studio 命令提示,然后切换目录到dl所在目录并执行“lib /machine:X86 /def:libxls.def”
找不到visual studio 命令提示的请看下面的2个图,图1中打开visual studio 命令提示需要右键用管理员模式打开,图2直接打开就行。
8、到此大功告成,我们需要的libxls的动态库成功得到,中文也能正常支持了。
9、成果已上传网盘:http://pan.baidu.com/s/1miD4GVQ 密码:yxat
PS:因为在vc中使用的时候会出现编译的问题,修改xlstypes.h最终文件如下:如果有更好的办法解决请指教,谢谢,主要是因为linux和windows的差异。
#ifndef XLS_TYPES_INC #define XLS_TYPES_INC #include <stdint.h> typedef unsigned char BYTE; typedef uint16_t WORD; typedef uint32_t DWORD; #ifdef NO_ALIGN typedef uint16_t WORD_UA; typedef uint32_t DWORD_UA; #else #ifdef _WIN32 typedef __declspec(align(1)) uint16_t WORD_UA; typedef __declspec(align(1)) uint32_t DWORD_UA; #else typedef uint16_t WORD_UA __attribute__ ((aligned (1))); // 2 bytes typedef uint32_t DWORD_UA __attribute__ ((aligned (1))); // 4 bytes #endif /* _WIN32 */ #endif /* NO_ALIGN */ #endif /* XLS_TYPES_INC*/