C++如何写Excel?
大家时间都这么宝贵,没有起因的问题是不值得被优先研究的。这篇博客的起因就是希望找到一个比较合适于C++的开源库,用以在C++中生成Excel文档。其实C++可用的开源Excel库,很多博主都已经撰文提及。例如:# c++操作excel的几种库这篇博文的作者就总结了几种库,小白也是从这篇文章开始挑选的。
libxlsxwriter库简介
从上文提到的博文里,小白挑选了libxlsxwriter这个专门用于写xlsx文件的库。这个库被选中的关键原因,有以下几点:
- 开源免费
- 功能强大
- 支持中文
- 文档丰富
这个库在github上的开源仓库地址是https://github.com/jmcnamara/libxlsxwriter。它还有一个文档地址http://libxlsxwriter.github.io/非常详尽地教大家如何安装、使用这个库,这简直是小白的福音。
下面摘抄一段官方对该库的介绍:
Libxlsxwriter is a C library that can be used to write text, numbers, formulas and hyperlinks to multiple worksheets in an Excel 2007+ XLSX file. It supports features such as:
Libxlsxwriter是一个C库,可以向Excel 2007以上版本的XLSX文档中写入文本、数字、公式、超链接,并且支持多工作表。它支持的一些功能特征如下:
- 100% compatible Excel XLSX files. 100% 兼容Excel XLSX文件。
- Full Excel formatting. 完整的Excel格式支持。
- Merged cells. 合并单元格。
- Defined names. 定义名称。
- Autofilters. 自动筛选。
- Charts. 表格。
- Data validation and drop down lists. 数据验证以及下拉列表。
- Conditional formatting. 条件格式。
- Worksheet PNG/JPEG/GIF images. 工作表 PNG/JPEG/GIF 图像。
- Cell comments. 单元格注释。
- Support for adding Macros. 支持宏。
- Memory optimization mode for writing large files. 写入大文件时优化内存模式。
- Source code available on GitHub. 开源代码可得。
- FreeBSD License. FreeBSD 协议。
- ANSI C. ANSI C 标准。
- Works with GCC, Clang, Xcode, MSVC 2015, ICC, TCC, MinGW, MingGW-w64/32. 编译器支持GCC, Clang, Xcode, MSVC2015, ICC, TCC, MinGW, MingGW-w64/32。
- Works on Linux, FreeBSD, OpenBSD, OS X, iOS and Windows. Also works on MSYS/MSYS2 and Cygwin. 在Linux,FreeBSD,OpenBSD,OS X,iOS和 Windows上均可使用。同时在MSYS/MSYS2和Cygwin上也可使用(支持多种系统)
- Compiles for 32 and 64 bit. 可编译为32位和64位。
- Compiles and works on big and little endian systems. 适用于高位编址和低位编址系统。
- The only dependency is on
zlib
. 唯一的依赖库是zlib
。
特别注意最后一条——这一条的重要性在于,对我们编译和使用libxlsxwriter库有比较大的影响。
libxlsxwriter的文档相对比较友好:
Windows 环境下 VS + CMake 编译libxlsxwriter库
我们接下来讨论在Windows环境下,利用VS编译器和CMake工具,以源码方式编译libxlsxwriter库。
这个过程需要分为两步:第一步是编译zlib库,第二步才是编译libxlsxwriter库。
首先我们在github上找到zlib库,很高兴这个库仍然是一个开源库。其地址为:https://github.com/madler/zlib
这里的编译需要CMake工具,CMake工具结合VS的使用这里就不多说了。zlib库小白用VS2013和VS2019都试过,幸运无坑。编译成功后,我们可以得到x64 Release版本的zlib.dll / zlib.exp / zlib.lib / zlibstatic.lib,如下图所示:
在我们编译libxlsxwriter的目标路径下建立一个文件夹zlib,把上述四个文件放进去。然后利用CMake和VS对libxlsxwriter进行编译。注意如果没有在编译前把zlib准备好,则会报错。
注意,在此处,打开xlsxwriter.sln工程后,将C/C++ --> 常规 --> 调试信息格式 修改为 “无”。
如果不执行这个操作,那么使用编译好的xlsxwriter.lib时,会报出LNK4099错误。因为有一些pdb文件会依赖于编译环境,如果我们编译完成后把编译文件移动或删除了,就会找不到xlsxwriter.pdb,不利于我们使用。考虑到我们并不需要对libxlsxwriter库本身进行调试,所以直接把此处调试信息格式改成“无”比较省事。否则的话就需要对pdb的生成位置进行修改,关于这一点,可以阅读以下博客学习一下:
warning LNK4099: PDB 原因及解决方案
使用libxlsxwriter库
使用libxlsxwriter库,即新建一个工程,我们只需要准备好以下文件:
- zlib四兄弟
- xlsxwriter编译好的库下面的Include文件夹(注意保持内部的层级关系)
- xlsxwriter.lib
添加include文件到包含,添加zlib.lib和xlsxwriter.lib到附加依赖库即可。
注意在预生成事件/生成后事件里把zlib.dll拷贝到最终生成的exe目录下,否则会因为没有zlib.dll而无法运行。
让我们来一个示例程序:
#include "xlsxwriter.h"
/* Some data we want to write to the worksheet. */
struct expense {
char item[32];
int cost;
};
struct expense expenses[] = {
{"租金", 1000},
{"燃气", 100},
{"食物", 300},
{"健身", 50},
};
int main(int argc, char* argv[])
{
/* Create a workbook and add a worksheet. */
lxw_workbook* workbook = workbook_new("tutorial01.xlsx");
lxw_worksheet* worksheet = workbook_add_worksheet(workbook, NULL);
/* Start from the first cell. Rows and columns are zero indexed. */
int row = 0;
int col = 0;
/* Iterate over the data and write it out element by element. */
for (row = 0; row < 4; row++) {
worksheet_write_string(worksheet, row, col, expenses[row].item, NULL);
worksheet_write_number(worksheet, row, col + 1, expenses[row].cost, NULL);
}
/* Write a total using a formula. */
worksheet_write_string(worksheet, row, col, "总计", NULL);
worksheet_write_formula(worksheet, row, col + 1, "=SUM(B1:B4)", NULL);
/* Save the workbook and free any allocated memory. */
return workbook_close(workbook);
}
生成的结果为:
为什么VS2013编译时theme.c中有报错?
因为VS2013编译器中可能安装时选择了英语和中文简体,日语和韩语编码不能解析。解决的办法是把对应报错的日语和韩语直接注释掉。当然这样也意味着在使用库时就最好不要使用日语和韩语输入了。如果有VS2019的话,则不会有此坑。
为什么中文输入会失败?
小白在满心欢喜调试的过程中,发现输入中文时生成的xlsx文件会报错误。
点“否”就退出了,点“是”,则报错,称xml错误,所有中文以及中文所在列都没了:
这个问题是由于我们源码的保存格式存在问题,由于默认设置的缘故,可能是由于使用的VS简体中文版,使得源文件的默认保存格式是“简体中文(GB2312)”。
这时候我们需要在“文件”-“高级保存选项”里把源文件的编码格式换成“UTF-8不带签名”。有的同学可能会问了,在Windows下,不是应该保存成带签名的UTF-8模式吗?这里要说明一下,因为Excel文件实际上是解析XML文件,而这个XML文件采用的是不带签名的UTF-8编码,所以跟系统没有啥特别关系。
还有的同学会问了,说为什么“文件”里没找到“高级保存选项”啊?
那么在“工具”–> “自定义”里
这个库还是功能比较强大的,既可以使用中文,也可以对单元格进行格式设定,甚至还能画图、写宏。后面还是需要把相关的功能再仔细学习一下。
【水平所限,错漏难免。创作不易,轻喷勿骂】