在数据处理和数据分析的过程中,Excel表格是一个不可或缺的工具。无论是财务报表、数据收集还是统计分析,Excel表格都扮演着重要的角色。通过编程语言来读写Excel文件,可以在处理数据时达到更高的效率。本文将带你一步步使用LibXL库来轻松读写Excel表格,特别适合那些刚接触编程和LibXL的新手。
🧑 博主简介:现任阿里巴巴嵌入式技术专家,15年工作经验,深耕嵌入式+人工智能领域,精通嵌入式领域开发、技术管理、简历招聘面试。CSDN优质创作者,提供产品测评、学习辅导、简历面试辅导、毕设辅导、项目开发、C/C++/Java/Python/Linux/AI等方面的服务,如有需要请站内私信或者联系任意文章底部的的VX名片(ID:
gylzbk
)
💬 博主粉丝群介绍:① 群内初中生、高中生、本科生、研究生、博士生遍布,可互相学习,交流困惑。② 热榜top10的常客也在群里,也有数不清的万粉大佬,可以交流写作技巧,上榜经验,涨粉秘籍。③ 群内也有职场精英,大厂大佬,可交流技术、面试、找工作的经验。④ 进群免费赠送写作秘籍一份,助你由写作小白晋升为创作大佬。⑤ 进群赠送CSDN评论防封脚本,送真活跃粉丝,助你提升文章热度。有兴趣的加文末联系方式,备注自己的CSDN昵称,拉你进群,互相学习共同进步。
【工具推荐】使用LibXL轻松读写Excel表格:从下载安装配置到丰富的示例程序
什么是LibXL?
LibXL 是一个用于读写 Excel文件的跨平台库,支持C、C++、C# 以及 Delphi 等多种编程语言,不需要安装 Microsoft Excel 程序。相较于其他Excel读写库,LibXL 的优势在于其速度快,支持大文件且不依赖于COM接口。
一、下载并安装LibXL
1. 下载LibXL库
首先,前往LibXL官网下载最新版本。根据操作系统和编程语言选择合适的版本下载,如Windows、Linux版本等。
2. 解压LibXL库
下载完成后,使用合适的解压工具解压文件。以Windows平台为例,解压后的LibXL库文件结构如下:
libxl/
├── bin/
│ ├── libxl.dll
│ └── libxl.lib
├── include/
│ └── libxl.h
└── examples/
└── c/
└── example1.c
二、配置开发环境
Windows平台配置
本文以Windows平台的C++为例,配置Visual Studio开发环境:
-
包含头文件和库文件:
- 打开
项目属性
->C/C++
->常规
->附加包含目录
,添加LibXL的include
目录路径。 - 打开
项目属性
->链接器
->常规
->附加库目录
,添加LibXL的lib
目录路径。
- 打开
-
链接库文件:
- 打开
项目属性
->链接器
->输入
->附加依赖项
,添加libxl.lib
。
- 打开
-
添加DLL文件:
- 将libxl.dll文件复制到项目的输出目录,或将DLL文件所在路径添加到系统环境变量中。
Linux平台配置
在Linux上,涉及到库文件和头文件的复制以及环境变量的配置。步骤如下:
-
复制库文件和头文件:
- 将
libxl.so
文件复制到系统库目录:sudo cp libxl/bin/libxl.so /usr/local/lib/
- 将
libxl.h
文件复制到系统包含目录:sudo cp libxl/include/libxl.h /usr/local/include/
- 将
-
更新动态库缓存:
sudo ldconfig
-
设置环境变量:
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
三、基础用法:创建和保存Excel文件
下面是一个简单的示例程序,演示如何用LibXL在Windows和Linux平台上创建一个新的Excel文件并写入数据。
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
// Step 1: 创建一个新的Book对象
Book* book = xlCreateBook();
if (book) {
// Step 2: 添加一个新的Sheet
Sheet* sheet = book->addSheet("Sheet1");
if (sheet) {
// Step 3: 在指定单元格位置写入数据
sheet->writeStr(2, 1, "Hello, LibXL!");
sheet->writeNum(3, 1, 1000);
sheet->writeFormula(4, 1, "SUM(B4)");
cout << "Data written to sheet successfully!" << endl;
}
// Step 4: 保存Excel文件
if (book->save("example.xlsx")) {
cout << "File saved successfully!" << endl;
} else {
cout << "Error saving file!" << endl;
}
// Step 5: 释放Book对象资源
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
逐步解释
- 创建Book对象:调用
xlCreateBook()
函数创建一个Book对象,用于操作Excel文件。 - 添加Sheet:使用
book->addSheet("Sheet1");
创建一个名为"Sheet1"的新工作表。 - 写入数据:
sheet->writeStr(2, 1, "Hello, LibXL!");
:向第2行第1列写入字符串数据。sheet->writeNum(3, 1, 1000);
:向第3行第1列写入数字数据。sheet->writeFormula(4, 1, "SUM(B4)");
:向第4行第1列写入一个公式。
- 保存Excel文件:使用
book->save("example.xlsx");
将操作结果保存到example.xlsx
文件中。 - 释放资源:调用
book->release();
释放Book对象占用的资源。
四、读取Excel文件
接下来是另一个示例,展示如何读取一个现有的Excel文件并提取其中的内容。
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
// Step 1: 创建一个新的Book对象
Book* book = xlCreateBook();
if (book) {
// Step 2: 加载已经存在的Excel文件
if (book->load("example.xlsx")) {
// Step 3: 获取第一个Sheet
Sheet* sheet = book->getSheet(0);
if (sheet) {
// Step 4: 读取指定单元格位置的数据
const char* str = sheet->readStr(2, 1);
double num = sheet->readNum(3, 1);
// Step 5: 输出读取的数据
if (str) {
cout << "String data at (2,1): " << str << endl;
}
cout << "Numeric data at (3,1): " << num << endl;
} else {
cout << "Unable to get sheet!" << endl;
}
} else {
cout << "Unable to load Excel file!" << endl;
}
// Step 6: 释放Book对象资源
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
逐步解释
- 创建Book对象:
xlCreateBook()
函数创建一个Book对象,用于操作Excel文件。 - 加载Excel文件:
book->load("example.xlsx");
加载现有的Excel文件example.xlsx
。 - 获取Sheet:
book->getSheet(0);
获取第一个工作表。 - 读取数据:
const char* str = sheet->readStr(2, 1);
读取第2行第1列的字符串数据。double num = sheet->readNum(3, 1);
读取第3行第1列的数值数据。
- 输出数据:通过
cout
输出读取到的数据。 - 释放资源:调用
book->release();
释放Book对象占用的资源。
五、进阶用法:处理不同类型的数据
示例:写入字符串、数字、布尔值和日期
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
Book* book = xlCreateBook();
if (book) {
Sheet* sheet = book->addSheet("Sheet1");
if (sheet) {
// 写入字符串
sheet->writeStr(2, 1, "Hello, LibXL!");
// 写入数字
sheet->writeNum(3, 1, 1000);
// 写入布尔值
sheet->writeBool(4, 1, true);
// 写入日期
double date = book->datePack(2023, 10, 15);
sheet->writeNum(5, 1, date);
// 设置单元格格式为日期格式
Format* dateFormat = book->addFormat();
dateFormat->setNumFormat(NUMFORMAT_DATE);
sheet->setCellFormat(5, 1, dateFormat);
if (book->save("example1.xlsx")) {
cout << "File example1.xlsx saved successfully!" << endl;
} else {
cout << "Error saving file example1.xlsx!" << endl;
}
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
示例:读字符串、数字、布尔值和日期
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
Book* book = xlCreateBook();
if (book) {
if (book->load("example1.xlsx")) {
Sheet* sheet = book->getSheet(0);
if (sheet) {
// 读字符串
const char* str = sheet->readStr(2, 1);
if (str) {
cout << "String data: " << str << endl;
}
// 读数字
double num = sheet->readNum(3, 1);
cout << "Numeric data: " << num << endl;
// 读布尔值
bool b = sheet->readBool(4, 1);
cout << "Boolean data: " << (b ? "true" : "false") << endl;
// 读日期
double date = sheet->readNum(5, 1);
int year, month, day;
book->dateUnpack(date, &year, &month, &day);
cout << "Date data: " << year << "-" << month << "-" << day << endl;
} else {
cout << "Unable to get sheet!" << endl;
}
} else {
cout << "Unable to load Excel file!" << endl;
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
示例:单元格格式化
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
Book* book = xlCreateBook();
if (book) {
Sheet* sheet = book->addSheet("Sheet1");
if (sheet) {
// 创建一个加粗的格式
Format* boldFormat = book->addFormat();
boldFormat->setBold();
sheet->writeStr(2, 1, "Bold Text", boldFormat);
// 创建一个红色背景的格式
Format* redBgFormat = book->addFormat();
redBgFormat->setPatternForegroundColor(COLOR_RED);
redBgFormat->setPattern(PATTERN_SOLID);
sheet->writeStr(3, 1, "Red Background", redBgFormat);
// 创建一个居中对齐的格式
Format* centerAlignFormat = book->addFormat();
centerAlignFormat->setAlignH(ALIGNH_CENTER);
sheet->writeStr(4, 1, "Center Aligned", centerAlignFormat);
if (book->save("example2.xlsx")) {
cout << "File example2.xlsx saved successfully!" << endl;
} else {
cout << "Error saving file example2.xlsx!" << endl;
}
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
示例:批量写入和读取数据
1. 批量写入数据
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
Book* book = xlCreateBook();
if (book) {
Sheet* sheet = book->addSheet("Sheet1");
if (sheet) {
// 批量写入数据
for (int row = 0; row < 10; ++row) {
for (int col = 0; col < 5; ++col) {
sheet->writeNum(row, col, row * col);
}
}
if (book->save("example3.xlsx")) {
cout << "File example3.xlsx saved successfully!" << endl;
} else {
cout << "Error saving file example3.xlsx!" << endl;
}
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
2. 批量读取数据
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
Book* book = xlCreateBook();
if (book) {
if (book->load("example3.xlsx")) {
Sheet* sheet = book->getSheet(0);
if (sheet) {
// 批量读取数据
for (int row = 0; row < 10; ++row) {
for (int col = 0; col < 5; ++col) {
double num = sheet->readNum(row, col);
cout << "Data at (" << row << ", " << col << "): " << num << endl;
}
}
} else {
cout << "Unable to get sheet!" << endl;
}
} else {
cout << "Unable to load Excel file!" << endl;
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
示例:处理大文件
对于非常大的数据集,建议分批进行读写操作以避免内存占用过高。以下示例展示了如何使用LibXL处理大文件,每次处理一个数据块:
1. 分批写入数据
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
const int BATCH_SIZE = 1000;
const int TOTAL_ROWS = 100000;
Book* book = xlCreateBook();
if (book) {
Sheet* sheet = book->addSheet("Sheet1");
if (sheet) {
for (int row = 0; row < TOTAL_ROWS; row += BATCH_SIZE) {
for (int i = 0; i < BATCH_SIZE && (row + i) < TOTAL_ROWS; ++i) {
for (int col = 0; col < 5; ++col) {
sheet->writeNum(row + i, col, (row + i) * col);
}
}
cout << "Processed rows: " << row + BATCH_SIZE << endl;
}
if (book->save("large_example.xlsx")) {
cout << "File large_example.xlsx saved successfully!" << endl;
} else {
cout << "Error saving file large_example.xlsx!" << endl;
}
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
2. 分批读取数据
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
const int BATCH_SIZE = 1000;
Book* book = xlCreateBook();
if (book) {
if (book->load("large_example.xlsx")) {
Sheet* sheet = book->getSheet(0);
if (sheet) {
int totalRows = sheet->lastRow();
for (int row = 0; row < totalRows; row += BATCH_SIZE) {
for (int i = 0; i < BATCH_SIZE && (row + i) < totalRows; ++i) {
for (int col = 0; col < 5; ++col) {
double num = sheet->readNum(row + i, col);
// 可以对读取的数据进行进一步处理,这里只是输出为了示例
cout << "Data at (" << row + i << ", " << col << "): " << num << endl;
}
}
cout << "Processed rows: " << row + BATCH_SIZE << endl;
}
} else {
cout << "Unable to get sheet!" << endl;
}
} else {
cout << "Unable to load Excel file!" << endl;
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
示例:处理多个工作表
我们继续讲解读取多个工作表的示例代码:
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
Book* book = xlCreateBook();
if (book) {
if (book->load("multi_sheet_example.xlsx")) {
for (int i = 0; i < book->sheetCount(); ++i) {
Sheet* sheet = book->getSheet(i);
if (sheet) {
const char* str = sheet->readStr(2, 1);
if (str) {
cout << "Data in Sheet " << i + 1 << ": " << str << endl;
}
} else {
cout << "Unable to get sheet " << i + 1 << "!" << endl;
}
}
} else {
cout << "Unable to load Excel file!" << endl;
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
示例:使用公式
LibXL支持在Excel单元格中使用公式,以下代码演示了如何给单元格写入公式并读取计算结果。
写入公式
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
Book* book = xlCreateBook();
if (book) {
Sheet* sheet = book->addSheet("Sheet1");
if (sheet) {
// 写入一些基础数据
sheet->writeNum(2, 1, 1);
sheet->writeNum(3, 1, 2);
sheet->writeNum(4, 1, 3);
// 写入公式
sheet->writeFormula(5, 1, "SUM(B3:B5)");
if (book->save("formula_example.xlsx")) {
cout << "File formula_example.xlsx saved successfully!" << endl;
} else {
cout << "Error saving file formula_example.xlsx!" << endl;
}
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
读取公式和计算结果
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
Book* book = xlCreateBook();
if (book) {
if (book->load("formula_example.xlsx")) {
Sheet* sheet = book->getSheet(0);
if (sheet) {
const char* formula = sheet->readFormula(5, 1);
if (formula) {
cout << "Formula: " << formula << endl;
}
double result = sheet->readNum(5, 1);
cout << "Formula result: " << result << endl;
} else {
cout << "Unable to get sheet!" << endl;
}
} else {
cout << "Unable to load Excel file!" << endl;
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
六、处理大文件与批量操作
对于大数据集处理和批量操作,最好分批处理以节省内存和提升性能。
示例:分批写入大文件
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
const int BATCH_SIZE = 1000;
const int TOTAL_ROWS = 100000;
Book* book = xlCreateBook();
if (book) {
Sheet* sheet = book->addSheet("Sheet1");
if (sheet) {
for (int row = 0; row < TOTAL_ROWS; row += BATCH_SIZE) {
for (int i = 0; i < BATCH_SIZE && (row + i) < TOTAL_ROWS; ++i) {
for (int col = 0; col < 5; ++col) {
sheet->writeNum(row + i, col, (row + i) * col);
}
}
cout << "Processed rows: " << row + BATCH_SIZE << endl;
}
if (book->save("large_example.xlsx")) {
cout << "File large_example.xlsx saved successfully!" << endl;
} else {
cout << "Error saving file large_example.xlsx!" << endl;
}
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
示例:分批读取大文件
#include "libxl.h"
#include <iostream>
using namespace libxl;
using namespace std;
int main() {
const int BATCH_SIZE = 1000;
Book* book = xlCreateBook();
if (book) {
if (book->load("large_example.xlsx")) {
Sheet* sheet = book->getSheet(0);
if (sheet) {
int totalRows = sheet->lastRow();
for (int row = 0; row < totalRows; row += BATCH_SIZE) {
for (int i = 0; i < BATCH_SIZE && (row + i) < totalRows; ++i) {
for (int col = 0; col < 5; ++col) {
double num = sheet->readNum(row + i, col);
// 可以对读取的数据进行进一步处理,这里只是输出作为示例
cout << "Data at (" << row + i << ", " << col << "): " << num << endl;
}
}
cout << "Processed rows: " << row + BATCH_SIZE << endl;
}
} else {
cout << "Unable to get sheet!" << endl;
}
} else {
cout << "Unable to load Excel file!" << endl;
}
book->release();
} else {
cout << "Unable to create book object!" << endl;
}
return 0;
}
七、常见问题和技巧
1. 确保路径正确
在Linux环境中,路径是区分大小写的,因此一定要确保文件和目录的路径正确,避免出错。
2. 动态库路径
如果LibXL库没有安装在标准系统库路径中,可以将库路径添加到环境变量LD_LIBRARY_PATH
中,例如:
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
3. 错误处理
使用book->errorMessage()
可以获取LibXL操作失败时的详细错误信息,帮助你更好地了解出错原因。
if (!book->save("example.xlsx")) {
cout << "Error saving file: " << book->errorMessage() << endl;
}
4. 处理大文件
LibXL在处理大文件时表现优越,但即便如此也不要过度依赖一次性操作大量数据。对于非常大的数据集,建议分批进行读写操作。
结论
通过本文,你已经学习了如何在Windows和Linux平台上配置LibXL库,并使用它来创建、读取和操作Excel文件。从基础的读写操作到处理不同类型的数据、格式化单元格、批量处理数据,以及使用公式和操作多个工作表等,LibXL为我们提供了强大且灵活的功能。
希望这些详细的示例和解释能够帮助你理解和利用LibXL,提高数据处理的效率和工作质量。如果在使用过程中遇到任何问题,LibXL的官方文档和论坛是很好的咨询渠道。