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

😁博客主页😁:🚀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.mzph.cn/diannao/64846.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NACA四位数字翼型

NACA四位数字翼型&#xff0c;以NACA 2412为例 第一位数字2 —相对弯度 第二位数字4 —相对弯度所有位置&#xff08;单位化后的&#xff09; 最末两位数字12 —相对厚度 所有NACA四位数字翼型的&#xff08;相对厚度所在的位置&#xff09;

DataX与DataX-Web安装与使用

DataX github地址&#xff1a;DataX/introduction.md at master alibaba/DataX GitHub 环境准备 Linux环境系统 JDK&#xff08;1.8及其以上版本&#xff0c;推荐1.8&#xff09; Python&#xff08;2或者3都可以&#xff09; Apache Maven 3.x&#xff08;源码编译安装…

电子应用设计方案69:智能护眼台灯系统设计

智能护眼台灯系统设计 一、引言 随着人们对眼睛健康的重视&#xff0c;智能护眼台灯成为了越来越多人的选择。本设计方案旨在打造一款功能丰富、护眼效果显著且智能便捷的台灯系统。 二、系统概述 1. 系统目标 - 提供无频闪、无蓝光危害的均匀柔和光线&#xff0c;保护眼睛。…

cesium 常见的 entity 列表

Cesium 是一个用于创建3D地球和地图的开源JavaScript库。它允许开发者在Web浏览器中展示地理空间数据,并且支持多种类型的空间实体(entities)。 Entities是Cesium中用于表示地面上或空中的对象的一种高层次、易于使用的接口。它们可以用来表示点、线、多边形、模型等,并且可…

在Visual Studio 2022中配置C++计算机视觉库Opencv

本文主要介绍下载OpenCV库以及在Visual Studio 2022中配置、编译C计算机视觉库OpenCv的方法 1.Opencv库安装 ​ 首先&#xff0c;我们需要安装OpenCV库&#xff0c;作为一个开源库&#xff0c;我们可以直接在其官网下载Releases - OpenCV&#xff0c;如果官网下载过慢&#x…

【Java基础面试题035】什么是Java泛型的上下界限定符?

回答重点 Java泛型的上下界限定符用于对泛型类型参数进行范围限制&#xff0c;主要有上界限定符和下届限定符。 1&#xff09;上界限定符 (? extends T)&#xff1a; 定义&#xff1a;通配符?的类型必须是T或者T的子类&#xff0c;保证集合元素一定是T或者T的子类作用&…

WPF+MVVM案例实战与特效(四十七)-实现一个路径绘图的自定义按钮控件

文章目录 1、案例效果2、创建自定义 PathButton 控件1、定义 PathButton 类2、设计样式与控件模板3、代码解释3、控件使用4、直接在 XAML 中绑定命令3、源代码获取4、总结1、案例效果 2、创建自定义 PathButton 控件 1、定义 PathButton 类 首先,我们需要创建一个新的类 Pat…

共模电感的工作原理

共模电感也称为共模扼流线圈&#xff0c;是一种抑制共模干扰的器件&#xff0c;它是由两个尺寸相同&#xff0c;匝数相同的线圈对称地绕制在同一个铁氧体环形磁芯上&#xff0c;形成的一个四端器件。当共模电流流过共模电感时&#xff0c;磁芯上的两个线圈产生的磁通相互叠加&a…

外连接转AntiJoin的应用场景与限制条件 | OceanBase SQL 查询改写系列

在《SQL 改写系列&#xff1a;外连接转内连接的常见场景与错误》一文中&#xff0c;我们了解到谓词条件可以过滤掉连接结果中的 null 情形的&#xff0c;将外连接转化为内连接的做法是可行的&#xff0c;正如图1中路径(a)所示。此时&#xff0c;敏锐的你或许会进一步思考&#…

二、windows环境下vscode使用wsl教程

本篇文件介绍了在windows系统使用vscode如何连接使用wsl&#xff0c;方便wsl在vscode进行开发。 1、插件安装 双击桌面vscode&#xff0c;按快捷键CtrlShiftX打开插件市场&#xff0c;搜索【WSL】点击安装即可。 2、开启WSL的linux子系统 点击左下方图标【Open a Remote Win…

因子问题(真EASY)

描述 任给两个正整数N、M&#xff0c;求一个最小的正整数a&#xff0c;使得a和(M-a)都是N的因子。 输入描述 包括两个整数N、M。N不超过1,000,000。 输出描述 输出一个整数a&#xff0c;表示结果。如果某个案例中满足条件的正整数不存在&#xff0c;则在对应行输出-1 用例…

2024 高频 Java 面试合集整理 (1000 道附答案解析)

2024 年马上就快要过去了&#xff0c;总结了上半年各类 Java 面试题&#xff0c;初中级和中高级都有&#xff0c;包括 Java 基础&#xff0c;JVM 知识面试题库&#xff0c;开源框架面试题库&#xff0c;操作系统面试题库&#xff0c;多线程面试题库&#xff0c;Tcp 面试题库&am…

(2024.12)Ubuntu20.04安装openMVS<成功>.colmap<成功>和openMVG<失败>记录

一、安装openMVS 官方文档&#xff1a;https://github.com/cdcseacave/openMVS/wiki/Building sudo apt-get -y install git mercurial cmake libpng-dev libjpeg-dev libtiff-dev libglu1-mesa-dev eigen git clone https://gitlab.com/libeigen/eigen --branch 3.4 mkdi…

自动控制系统综合与LabVIEW实现

自动控制系统综合是为了优化系统性能&#xff0c;确保其可靠性、稳定性和灵活性。常用方法包括动态性能优化、稳态误差分析、鲁棒性设计等。结合LabVIEW&#xff0c;可以通过图形化编程、高效数据采集与处理来实现系统综合。本文将阐述具体方法&#xff0c;并结合硬件选型提供实…

【恶意软件检测】一种基于API语义提取的Android恶意软件检测方法(期刊等级:CCF-B、Q2)

一种基于API语义提取的Android恶意软件检测方法 A novel Android malware detection method with API semantics extraction 摘要 由于Android框架和恶意软件的持续演变&#xff0c;使用过时应用程序训练的传统恶意软件检测方法在有效识别复杂演化的恶意软件方面已显不足。为…

FLTK - build fltk-1.1.10 on vs2019

文章目录 FLTK - build fltk-1.1.10 on vs2019概述笔记buildtest测试程序运行 END FLTK - build fltk-1.1.10 on vs2019 概述 看书上用到了fltk-1.1.10, 用vs2019试试能否正常编译使用? 笔记 build 从官网下载fltk-1.1.10-source.tar.bz2 用7zip解开 fltk-1.1.10-source.…

业财融合,决策有据:工程项目管理的财务新视角

在工程项目管理领域&#xff0c;业财融合正开启全新篇章。传统模式下&#xff0c;业务与财务各自为政&#xff0c;常导致信息滞后、决策盲目。如今&#xff0c;借助先进理念与技术&#xff0c;二者紧密相连。 在项目规划阶段&#xff0c;财务部门依据业务需求与市场趋势&#…

汽车IVI中控开发入门及进阶(44):杰发科智能座舱芯片

概述: 杰发科技自成立以来,一直专注于汽车电子芯片及相关系统的研发与设计。 产品布局: 合作伙伴: 杰发科技不断提升产品设计能力和产品工艺,确保产品达 到更高的质量标准。目前杰发科技已通过ISO9001质 量管理体系与CMMIL3认证。 杰发科技长期合作的供应商(芯片代工厂、…

算法专题——双指针

目录 前言 1、移动0 2、复写零 3、快乐数 4、盛最多水的容器 5、有效三⻆形的个数 6、和为s的两个数字 7、三数之和 8、四数之和 前言 本文主要介绍一些用到双指针的常见算法题。 1、移动0 链接&#xff1a;https://leetcode.cn/problems/move-zeroes/description/…

人工智能与云计算的结合:如何释放数据的无限潜力?

引言&#xff1a;数据时代的契机 在当今数字化社会&#xff0c;数据已成为推动经济与技术发展的核心资源&#xff0c;被誉为“21世纪的石油”。从个人消费行为到企业运营决策&#xff0c;再到城市管理与国家治理&#xff0c;每个环节都在生成和积累海量数据。然而&#xff0c;数…