我上班的地方规定,Office文档要在页眉页脚上加上密级才能传输,而我做的内部软件里会导出来很多Excel文档,于是,为了防止同事忘记加密级,我对Office文件结构作了一番研究。我做的软件使用的语言主要是C/C++,还用黑魔法连接了nodejs、python等各种各样的东西,汇聚了一堆非常小众的框架,于是在这上面费了老半天劲....好久没更新博客了,就记录一下探索的过程吧...
一些尝试
首先当然是要找找看有没有现成的轮子啦,我兴致冲冲直接打开了浏览器,输入关键词“Excel C++”...
OLE
结果出现了一堆基于“OLE”技术的范例,这个OLE技术全称Object Linking and Embedding,翻译过来是对象链接和嵌入,我横看竖看不对劲,最终还是放弃了这个方案,主要原因有以下几点:
- OLE是微软的技术,我的软件需要在各种操作系统上运行,可移植性不好
- 基于这篇文章的若干观点,加上我用vbs的实践,发现它运行太慢了,而且不稳定,加个页眉页脚要跑好几秒
开源库 - libxlsxwriter
于是我继续往下翻啊翻,翻啊翻...还是很难翻到啊,于是我加了个关键词搜索“开源”...
欸,咱就是说,开源真不辍,一搜就搜出来了这篇文章,根据文章的指引,OpenXLSX不行不支持UTF-8,readxl只能读取不能写入,libxl要收费...似乎只能试试这个BasicExcel,还有这个libxlsxwriter了啊,于是我又兴致勃勃地打开了BasicExcel原作者的博客,一看日期,好家伙,2006年写的,xlsx格式都还没出来呢吧....我果断关掉了这个页面,转眼将目光看上了最后的希望——libxlsxwriter...
一顿搜索猛如虎,我直接找到了它的Github项目主页,先看看日期,一个月前更新的,好耶!我熟练地点进了Release,下载了它1.1.4 October 9 2021的版本(作为经历大半年毒打的老油条,我已经深谙稳定之道,绝不再像之前的少年那样,直接Download zip下最新版直面一堆报错了...)
解压下来一看,我一眼瞄到了其中的CMakeLists.txt,于是我熟练地打开了CMake GUI,将路径粘了进去,又熟练地点击了Configure,被报错糊了一脸....
一看,原来有个zlib依赖库,直接进入了zlib官网,一眼瞄到了它的source code,直接下载下来,又是熟悉的CMakeLists.txt,又是一顿熟练的Configure-Generate-make install操作,很快啊,直接就装上了
再回来libxlsxwriter这里,大抵是要在configure前填写这一项ZLIB_ROOT配置吧,填上,Configure-Generate-make install,过啦!
接下来便是看文档了,U1S1,文档、范例写得真不辍,两分钟就上手了,把之前编译好的链接库、头文件放项目里,随手写个CMakeLists.txt配置一下,再把官方的例程放进来,很快啊,直接就编译成功了奥
官方例程代码大意是创建了一个excel档并写入了一些数据:
#include "xlsxwriter.h"
int main() {
/* Create a new workbook and add a worksheet. */
lxw_workbook *workbook = workbook_new("demo.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
/* Add a format. */
lxw_format *format = workbook_add_format(workbook);
/* Set the bold property for the format */
format_set_bold(format);
/* Change the column width for clarity. */
worksheet_set_column(worksheet, 0, 0, 20, NULL);
/* Write some simple text. */
worksheet_write_string(worksheet, 0, 0, "Hello", NULL);
/* Text with formatting. */
worksheet_write_string(worksheet, 1, 0, "World", format);
/* Write some numbers. */
worksheet_write_number(worksheet, 2, 0, 123, NULL);
worksheet_write_number(worksheet, 3, 0, 123.456, NULL);
/* Insert an image. */
worksheet_insert_image(worksheet, 1, 2, "logo.png");
workbook_close(workbook);
return 0;
}
运行了一下,得到了这样的一个demo.xlsx
看起来一切都很nice,接下来该翻翻文档看怎么加页眉页脚了,很快我便找到了对应的文档:
文档里给出了各种范例,例如在页眉左部添加图片,以及其中各种控制字的含义:
一切看起来都非常简单,我很快便在官方例程的基础上写出了如下的代码:
// 添加页眉
lxw_header_footer_options header_options = {.image_left = (char*)"logo.png"};
worksheet_set_header_opt(worksheet, "&L&[Picture]&R▲机密", &header_options);
然后编译运行,没!有!报!错!直接通过了奥,运行看看效果,Nice!大成功啊!
似乎很好写了吧,接下来只需要把逻辑从写入改成读取并修改....等等...这个libxlsxwriter...从名字上看是不是有点不太对劲?我查了查文档,通篇没有找到如何读取文件....莫非?
不信邪的我又去issue区搜了搜....一搜吓一跳....
好家伙我直接好家伙...我不禁陷入了沉思,到底该咋整捏?
不得已的造轮经历
(未完待续...)
2022年07月28日 19:51
老黄已经快半年没造轮子了,期待ing
2022年08月18日 11:31
出差中,事情太多辣,打算出差回来更新了