【开源库 | xlsxio】C/C++读写.xlsx文件,xlsxio 在 Linux(Ubuntu18.04)的编译、交叉编译

server/2024/12/26 0:41:51/

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
⏰发布时间⏰: 2024-12-20 16:41:55

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
  • 🎄二、XLSXIO 介绍
  • 🎄三、XLSXIO 的下载
  • 🎄四、XLSXIO 的编译
    • ✨4.1 XLSXIO 的编译
    • ✨4.2 XLSXIO 的交叉编译
  • 🎄五、XLSXIO 的使用
  • 🎄六、总结


在这里插入图片描述

在这里插入图片描述

🎄一、概述

最近项目需要将日志写到.xlsx中,了解到C和C++的操作.xlsx几个开源库:
在这里插入图片描述
本文要介绍的 xlsxio,虽然不在上图中,但也很好用。

下面主要介绍 xlsxio 库的下载以及在Ubuntu 18.04 下的编译和使用。


在这里插入图片描述

🎄二、XLSXIO 介绍

XLSXIO 是一款用于读取和写入.xlsx文件的跨平台C库。.xlsx文件格式自2007版起成为微软Excel的默认格式。

XLSXIO 提供了以下库:

  • -lxlsxio_read - 用于读取.xlsx文件,要求#include <xlsxio_read.h>
  • -lxlsxio_write - 用于写入.xlsx文件,要求#include <xlsxio_write.h>
  • -lxlsxio_readw - 实验性库,用于读取.xlsx文件,链接到-lexpatw,要求在#include <xlsxio_read.h>之前定义XML_UNICODE

该库的设计目标包括:

  • 使用标准C编写,但也适用于C++
  • 简单的接口
  • 小巧的体积
  • 可移植到不同平台(Windows,*nix)
  • 最小依赖:仅依赖于expat(仅用于阅读)和minizip或libzip(它们本身依赖于zlib)
  • 分别为读取和写入.xlsx文件提供独立的库
  • 不需要安装微软Excel

读取.xlsx文件:

  • 设计用于以数据表的形式处理.xlsx文件,假设:
    • 假设第一行包含列头名称
    • 假设接下来的行在与列头相同的列中提供值
    • 只处理值,忽略其他所有内容(公式,布局,图形,图表…)
  • 整个共享字符串表被加载到内存中(警告:对于具有大量不同值的大工作簿可能很大)
  • 支持没有共享字符串表的.xlsx文件
  • 工作表数据即时读取,无需在内存中缓冲数据
  • 提供两种方法:
    • 一个简单的方法,允许应用程序遍历行和单元格
    • 一个高级方法(开销较小),为每个单元格和每行后调用回调函数

写入.xlsx文件:

  • 旨在将数据表写入.xlsx文件,假设:
  • 仅支持写入数据(不支持公式,布局,图形,图表…)
  • 不支持多个工作表(每个文件只有一个工作表)
  • 即时文件生成,无需在内存中缓冲数据
  • 不支持共享字符串(所有值作为内联字符串写入)

该项目依赖于以下组件:

  • expat (仅用于libxlsxio_read)
  • minizip 或 libzip (libxlsxio_read 和 libxlsxio_write)

请注意,由于报告称使用libzip构建的XLSX I/O生成的.xlsx文件无法用LibreOffice打开,所以首选minizip。
不依赖于微软Excel。
XLSX I/O考虑了跨平台兼容性,在多种操作系统上运行良好,包括Windows,macOS和Linux。


在这里插入图片描述

🎄三、XLSXIO 的下载

XLSXIO 可以在GitHub下载,地址是:https://github.com/brechtsanders/xlsxio.git

下载地址:https://github.com/brechtsanders/xlsxio/tags

其最新版本是 0.2.35,下载后文件名为:xlsxio-0.2.35.tar.gz

在这里插入图片描述


在这里插入图片描述

🎄四、XLSXIO 的编译

✨4.1 XLSXIO 的编译

这个小节介绍的是使用 Ubuntu 自带的 gcc 编译器编译过程。XLSXIO 库依赖于 minizip 或 libzip,本文使用的是 minizip。关于minizip 的编译可以参考文章 :https://blog.csdn.net/wkd_007/article/details/144596975

下面是编译 XLSXIO 的步骤:

tar zxf xlsxio-0.2.35.tar.gz
cd xlsxio-0.2.35
make CFLAGS:="-I `pwd`/../../01_zlib/" LDFLAGS:="-L `pwd`/../../01_zlib/minizip/"
make install PREFIX=`pwd`/../result_gcc

CFLAGS 指明存放 minizip/zip.h 头文件的目录。
LDFLAGS 指明存放 libminizip.so 库文件的目录。

编译完成后,在 ../result_gcc 目录会有如下内容:
在这里插入图片描述


✨4.2 XLSXIO 的交叉编译

交叉编译需要先编译 zlib、minizip、libexpat:

  • zlib 库交叉编译参考:https://blog.csdn.net/wkd_007/article/details/140573322
  • minizip 库交叉编译参考:https://blog.csdn.net/wkd_007/article/details/144596975
  • libexpat
    下载最新版本: https://github.com/libexpat/ ,然后参考下面编译过程:
    tar zxf expat-2.6.4.tar.gz
    cd expat-2.6.4
    ./configure --prefix=`pwd`/../result_mix210 --host=aarch64-mix210-linux CC=aarch64-mix210-linux-gcc
    

下面是交叉编译 XLSXIO 的步骤:

tar zxf xlsxio-0.2.35.tar.gz
cd xlsxio-0.2.35
make CC=aarch64-mix210-linux-gcc CFLAGS:="-I `pwd`/../../01_zlib -I `pwd`/../../01_zlib/result_mix210/include/ -I `pwd`/../../17_expat/result_mix210/include/" \
LDFLAGS:="-L /home/samba/01_libCompile/opensource/01_zlib/minizip/ -L `pwd`/../../01_zlib/result_mix210/lib -L `pwd`/../../17_expat/result_mix210/lib -lz" make install PREFIX=`pwd`/../result_mix210

成功编译后,在 ../result_mix210/ 目录会有如下内容
在这里插入图片描述


在这里插入图片描述

🎄五、XLSXIO 的使用

XLSXIO 源码中有个 xlsxio-0.2.35/examples 目录,里面有几个例子介绍了怎样使用 XLSXIO来操作 .xlsx 文件。感兴趣的可以看看,代码也不难理解。这里以 example_xlsxio_write_cpp.cpp 为例介绍一下怎样单独编译这些例子:

使用动态库编译,运行编译结果时,需要指定动态库路径:

g++ example_xlsxio_write_cpp.cpp -I ./result_gcc/include/ ./result_gcc/lib/libxlsxio_write.a -L ../01_zlib/minizip/ -lminizip -lpthreadexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/home/samba/01_libCompile/opensource/01_zlib/minizip/"./a.out

下面是使用静态库编译,编译后直接可以运行:

g++ example_xlsxio_write_cpp.cpp -I ./result_gcc/include/ ./result_gcc/lib/libxlsxio_write.a ../01_zlib/minizip/libminizip.a ../01_zlib/result_gcc/lib/libz.a -lpthread 
./a.out

下面是例子 example_xlsxio_write_cpp.cpp 源码,可以帮助我们了解使用XLSXIO :

#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <unistd.h>
#include "xlsxio_write.h"/*! \class XLSXIOWriter*  \brief class for writing data to an .xlsx file*\details C++ wrapper for xlsxiowrite_ functions.*/
class XLSXIOWriter
{private:xlsxiowriter handle;public:/*! \brief XLSXIOWriter constructor, creates and opens .xlsx file* \param  filename      path of .xlsx file to open* \param  sheetname     name of worksheet* \param  detectionrows number of rows to buffer in memory, zero for none, defaults to 5* \sa     xlsxiowrite_open()*/XLSXIOWriter (const char* filename, const char* sheetname = NULL, size_t detectionrows = 5);/*! \brief XLSXIOWriter destructor, closes .xlsx file* \sa     xlsxiowrite_close()*/~XLSXIOWriter ();/*! \brief specify the row height to use for the current and next rows* \param  height        row height (in text lines), zero for unspecified* Must be called before the first call to any Add method of the current row* \sa     xlsxiowrite_set_row_height()*/void SetRowHeight (size_t height = 0);/*! \brief add a column cell* \param  name          column name* \param  width         column width (in characters)* Only one row of column names is supported or none.* Call for each column, and finish column row by calling NextRow().* Must be called before any NextRow() or the AddCell methods.* \sa     NextRow()*/void AddColumn (const char* name, int width = 0);/*! \brief add a cell with string data* \param  value         string value* \sa     NextRow()*/void AddCellString (const char* value);/*! \brief add a cell with integer data* \param  value         integer value* \sa     NextRow()*/void AddCellInt (long long value);/*! \brief add a cell with floating point data* \param  value         floating point value* \sa     NextRow()*/void AddCellFloat (double value);/*! \brief add a cell with date and time data* \param  value         date and time value* \sa     NextRow()*/void AddCellDateTime (time_t value);/*! \brief insertion operators* \sa     AddCellString()* \name   operator<<* \{*/XLSXIOWriter& operator << (const char* value);XLSXIOWriter& operator << (const std::string& value);XLSXIOWriter& operator << (int64_t value);XLSXIOWriter& operator << (double value);//XLSXIOWriter& operator << (time_t value);/*! @} *//*! \brief mark the end of a row (next cell will start on a new row)* \sa     xlsxiowrite_next_row()* \sa     AddCellString()*/void NextRow ();
};inline XLSXIOWriter::XLSXIOWriter (const char* filename, const char* sheetname, size_t detectionrows)
{unlink(filename);handle = xlsxiowrite_open(filename, sheetname);xlsxiowrite_set_detection_rows(handle, detectionrows);
}inline XLSXIOWriter::~XLSXIOWriter ()
{xlsxiowrite_close(handle);
}inline void XLSXIOWriter::SetRowHeight (size_t height)
{xlsxiowrite_set_row_height(handle, height);
}inline void XLSXIOWriter::AddColumn (const char* name, int width)
{xlsxiowrite_add_column(handle, name, width);
}inline void XLSXIOWriter::AddCellString (const char* value)
{xlsxiowrite_add_cell_string(handle, value);
}inline void XLSXIOWriter::AddCellInt (long long value)
{xlsxiowrite_add_cell_int(handle, value);
}inline void XLSXIOWriter::AddCellFloat (double value)
{xlsxiowrite_add_cell_float(handle, value);
}inline void XLSXIOWriter::AddCellDateTime (time_t value)
{xlsxiowrite_add_cell_datetime(handle, value);
}inline XLSXIOWriter& XLSXIOWriter::operator << (const char* value)
{AddCellString(value); return *this;
}inline XLSXIOWriter& XLSXIOWriter::operator << (const std::string& value)
{AddCellString(value.c_str());return *this;
}inline XLSXIOWriter& XLSXIOWriter::operator << (int64_t value)
{AddCellInt(value);return *this;
}inline XLSXIOWriter& XLSXIOWriter::operator << (double value)
{AddCellFloat(value);return *this;
}/*
inline XLSXIOWriter& XLSXIOWriter::operator << (time_t value)
{AddCellDateTime(value);return *this;
}
*/inline void XLSXIOWriter::NextRow ()
{xlsxiowrite_next_row(handle);
}const char* filename = "example.xlsx";int main (int argc, char* argv[])
{XLSXIOWriter* xlsxfile = new XLSXIOWriter(filename);xlsxfile->SetRowHeight(1);xlsxfile->AddColumn("Col1");xlsxfile->AddColumn("Col2");xlsxfile->AddColumn("Col3");xlsxfile->AddColumn("Col4");xlsxfile->AddColumn("Col5");xlsxfile->NextRow();int i;for (i = 0; i < 1000; i++) {*xlsxfile << "Test" << (char*)NULL << (int64_t)i;xlsxfile->AddCellDateTime(time(NULL));*xlsxfile << 3.1415926;xlsxfile->NextRow();}delete xlsxfile;return 0;
}

运行结果生成example.xlsx,内容如下:
在这里插入图片描述


在这里插入图片描述

🎄六、总结

本文介绍 xlsxio 开源库在 Ubuntu 18.04 的编译、交叉编译以及使用教程。

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

参考:
https://gitcode.com/gh_mirrors/xl/xlsxio/overview
C++ xlsx文件格式读写


http://www.ppmy.cn/server/153181.html

相关文章

CASA模型相关遥感数据及MODIS NDVI、FPAR遥感产品数据时序重建

植被作为陆地生态系统的重要组成部分对于生态环境功能的维持具有关键作用。植被净初级生产力&#xff08;Net Primary Productivity, NPP&#xff09;是指单位面积上绿色植被在单位时间内由光合作用生产的有机质总量扣除自养呼吸的剩余部分。植被NPP是表征陆地生态系统功能及可…

Bazel CI

本文来自智谱清言 ------ “Bazel CI” 通常指的是使用 Bazel 构建工具的持续集成&#xff08;CI&#xff09;系统。Bazel 是一个由 Google 开发的开源构建和测试工具&#xff0c;它支持多种编程语言&#xff0c;并被设计用于构建大型代码库。在持续集成环境中&#xff0c;B…

Java的垃圾回收机制介绍、工作原理、算法及分析调优

Java的垃圾回收&#xff08;Garbage Collection&#xff0c;GC&#xff09;是Java虚拟机&#xff08;JVM&#xff09;提供的一种自动内存管理机制&#xff0c;用于自动回收不再使用的内存空间&#xff0c;以避免内存泄露和内存溢出等问题。下面主要介绍Java垃圾回收的基本概念、…

[flutter] 容器组件

Center Center容器用来居中widget const Center({Key key, double widthFactor, // 若该值为空&#xff0c;该组件宽度会尽可能大&#xff1b;若不为空&#xff0c;该组件的宽度就是子节点宽度的多少倍double heightFactor, // 同widthFactorWidget child // 子组件 }) : supe…

苍穹外卖-day05redis 缓存的学习

苍穹外卖-day05 课程内容 Redis入门Redis数据类型Redis常用命令在Java中操作Redis店铺营业状态设置 学习目标 了解Redis的作用和安装过程 掌握Redis常用的数据类型 掌握Redis常用命令的使用 能够使用Spring Data Redis相关API操作Redis 能够开发店铺营业状态功能代码 功能实…

mysql(基础语法)

准备一张员工表 /*Navicat Premium Data TransferSource Server : localhost_3306Source Server Type : MySQLSource Server Version : 80037 (8.0.37)Source Host : localhost:3306Source Schema : studymysqlTarget Server Type : MySQLTar…

零基础入门Spring源码

文章目录 前言Spring相关代码pom.xml配置文件beans.xml实体类测试类 一、创建BeanFactoryApplicationContextBeanFactory和ApplicationContext的区别补充如何从容器中获取对象&#xff1f; 二、读取xml等&#xff0c;将bean定义信息放入BeanDefinition三、对BeanDefinition中的…

《软件设计的哲学》阅读摘要之设计原则

《软件设计的哲学》&#xff08;A Philosophy of Software Design&#xff09;是一本在软件架构与设计领域颇具影响力的书籍&#xff0c;作者 John Ousterhout 在书中分享了诸多深刻且实用的软件设计理念。书中列举的这些设计原则&#xff0c;汇聚了作者丰富的实战经验与深邃的…