前言
在qt中我们需要读取excel可以用qt自带的库,但是网上还有很多用起来很方便的第三方库
这里要介绍的就是QtXlsx
下载地址:dbzhang800/QtXlsxWriter: .xlsx file reader and writer for Qt5 (github.com)
配置
官方介绍了两种使用方法,这里主要介绍第二种方法
下载并解压
我们把该项目下载好,并解压,查看是否有个src
文件
这里面的所有内容就是我们所需要的,example
中有许多使用的样例,可以查看学习
在.pro
文件中导入
新建一个Qt工程,这里就用普通的Qt Console Application
为例
在.pro
当前路径下创建3rdparty
文件夹,表示使用第三方库
再在3rdparty
创建一个几个qtxlsx
文件夹
|-- 项目名.pro
|-- ....
|-- 3rdparty\
| |-- qtxlsx\
| |
我们将刚才的src
整个复制过来
这里我的项目名为test_qtxlsx
└─qtxlsx
└─src # 目标文件夹
└─xlsx
└─doc
├─snippets
└─src
最关键一步
在.pro
文件中加入下面这句代码
就是我们要导入qtxlsx.pri
文件
include(3rdparty/qtxlsx/src/xlsx/qtxlsx.pri)
注意,我们的目的是导入这个.pri
文件,这些路径操作可以和楼主不一样
导入成功
查看是否有qtxlsx
这个文件夹配置
若不存在,则检查之前的步骤是否有错误,或者重新构建,或者关闭项目重新打开
示例讲解
官方demo
#include "xlsxdocument.h"
int main()
{
QXlsx::Document xlsx;
xlsx.write("A1", "Hello Qt!");
xlsx.saveAs("Test.xlsx");
return 0;
}
这8行代码,我们主要分析4行内容
#include "xlsxdocument.h"
我们仅需要导入
xlsxdocument.h
这个头文件即可,并且不用指定什么相对路径,直接视为当前路径即可
QXlsx::Document xlsx;
创建一个默认构造的对象
xlsx.write("A1", "Hello Qt!");
在A1这个单元格内写入Hello Qt!
xlsx.saveAs("Test.xlsx");
保存到Test.xlsx中
注意,这里的默认保存路径是在build
下的
write && read
官方这个小样例只展示了写的一种操作,而读也是很重要的
废话不多说,直接展示代码
#include <QDebug>
#include "./3rdparty/qtxlsx/src/xlsx/xlsxdocument.h"
//! Format 需要这个宏
QTXLSX_USE_NAMESPACE
/**
* @brief write2QXlsx
* @param filePath
* 写文件
*/
void write2QXlsx(const QString& filePath) {
/// 预处理需要填入的数据
/// string[][]
QVector<QVector<QString>> matrix;
matrix.push_back({"九九乘法表"});
for (int row = 1; row <= 9; row += 1) {
matrix.push_back({});
for (int col = 1; col <= row; col += 1) {
QString calc = QString::asprintf("%d * %d = %d", row, col, row * col);
matrix[row] << calc;
}
}
/// 创建对象
QXlsx::Document xlsx;
/// 添加到excel表的对象中
/// 注意这里是[1, n]
for (int row = 0; row < matrix.size(); row += 1) {
for (int col = 0; col < matrix[row].size(); col += 1) {
xlsx.write(row + 1, col + 1, matrix.at(row).at(col));
}
}
/// 修改表格名
xlsx.renameSheet("Sheet1", "九九乘法表");
/// 设置单元格样式
Format format;
format.setHorizontalAlignment(Format::AlignHCenter);
format.setVerticalAlignment(Format::AlignVCenter);
format.setFontBold(true);
format.setFontColor(QColor(Qt::magenta));
/// 合并单元格
xlsx.mergeCells("A1:I1", format);
/// 保存
/// 若原来有同名文件,则会覆盖
xlsx.saveAs(filePath);
}
/**
* @brief readFromQXlsx
* @param filePath
* @return
* 读取文件
*/
bool readFromQXlsx(const QString& filePath) {
/// 根据路径获取xlsx文件对象
QXlsx::Document xlsx(filePath);
QXlsx::CellRange range = xlsx.dimension();
/// xlsx表中行列的范围
/// 若不存在则是-1和-2
if (range.firstRow() < 0 || range.lastRow() < 0 ||
range.firstColumn() < 0 || range.lastColumn() < 0) {
qDebug() << filePath << " 不存在";
qDebug() << range.firstRow();
qDebug() << range.lastRow();
qDebug() << range.firstColumn();
qDebug() << range.lastColumn();
return false;
}
qDebug() << xlsx.read("A1");
qDebug() << xlsx.sheetNames();
/// 范围[1, n]
for (int row = range.firstRow(); row <= range.lastRow(); row += 1) {
for (int col = range.firstColumn(); col <= range.lastColumn(); col += 1) {
qDebug() << xlsx.read(row, col).toString();
}
}
return true;
}
int main() {
QString filePath = "./test.xlsx";
write2QXlsx(filePath);
readFromQXlsx(filePath);
system("pause");
return 0;
}
write
这里以存入一个九九乘法表为例
可见对excel的操作是[1, n]
的范围操作
这里顺带提三个常用操作
- 修改表名
xlsx.renameSheet("Sheet1", "九九乘法表");
- 设置单元格样式
QTXLSX_USE_NAMESPACE
需要的宏Format format;
- 合并单元格
xlsx.mergeCells("A1:I1", format);
//! Format 需要这个宏
QTXLSX_USE_NAMESPACE
/**
* @brief write2QXlsx
* @param filePath
* 写文件
*/
void write2QXlsx(const QString& filePath) {
/// 预处理需要填入的数据
/// string[][]
QVector<QVector<QString>> matrix;
matrix.push_back({"九九乘法表"});
for (int row = 1; row <= 9; row += 1) {
matrix.push_back({});
for (int col = 1; col <= row; col += 1) {
QString calc = QString::asprintf("%d * %d = %d", row, col, row * col);
matrix[row] << calc;
}
}
/// 创建对象
QXlsx::Document xlsx;
/// 添加到excel表的对象中
/// 注意这里是[1, n]
for (int row = 0; row < matrix.size(); row += 1) {
for (int col = 0; col < matrix[row].size(); col += 1) {
xlsx.write(row + 1, col + 1, matrix.at(row).at(col));
}
}
/// 修改表格名
xlsx.renameSheet("Sheet1", "九九乘法表");
/// 设置单元格样式
Format format;
format.setHorizontalAlignment(Format::AlignHCenter);
format.setVerticalAlignment(Format::AlignVCenter);
format.setFontBold(true);
format.setFontColor(QColor(Qt::magenta));
/// 合并单元格
xlsx.mergeCells("A1:I1", format);
/// 保存
/// 若原来有同名文件,则会覆盖
xlsx.saveAs(filePath);
}
成功写入
read
读文件数据的时候,我们一般要先检查该文件是否存在
通常我们可以借助QFile
检查
但这里通过获得整个表格的最大最小范围判断是否存在有效范围
这里可以看出,虽然有的单元格合并了,但是还是存在的,只是视图层的合并
/**
* @brief readFromQXlsx
* @param filePath
* @return
* 读取文件
*/
bool readFromQXlsx(const QString& filePath) {
/// 根据路径获取xlsx文件对象
QXlsx::Document xlsx(filePath);
QXlsx::CellRange range = xlsx.dimension();
/// xlsx表中行列的范围
/// 若不存在则是-1和-2
if (range.firstRow() < 0 || range.lastRow() < 0 ||
range.firstColumn() < 0 || range.lastColumn() < 0) {
qDebug() << filePath << " 不存在";
qDebug() << range.firstRow();
qDebug() << range.lastRow();
qDebug() << range.firstColumn();
qDebug() << range.lastColumn();
return false;
}
qDebug() << xlsx.read("A1");
qDebug() << xlsx.sheetNames();
/// 范围[1, n]
for (int row = range.firstRow(); row <= range.lastRow(); row += 1) {
for (int col = range.firstColumn(); col <= range.lastColumn(); col += 1) {
qDebug() << xlsx.read(row, col).toString();
}
}
return true;
}
注意点
这个包对excel的操作是从1到n的,使用时不要下标越界
对表格操作的时候,尽量不要打开