1.简介
一直以来,都想学习一下C/C++如何操作excel表,在网上调研了一下,觉得使用C/C++去操作很麻烦,遂转向QT这边;QT有一个自带的类QAxObject,可以使用他去操作,但随着了解的深入,觉得他并不是很好,有很多其他缺陷(例如必须电脑安装了办公软件才可以进行操作等),所以继续调研,终于找到了QT的一个第三方库可以很好的实现:QtXlsx.
Github下载:https://github.com/dbzhang800/QtXlsxWriter
在Github下载后,可以直接添加到QtCreator项目中,也可以编译成lib库后再添加到VS中去使用。
2、下载QtXlsx
点击链接进入Github下载
下载解压后得到如下文件
二、QtXlsx源码嵌入QTCreator中使用
新建一个QTCreator窗体项目
将上图src文件夹拷贝到该项目路径中
之后双击项目中的.pro文件
将如下代码拷贝到.pro文件中
include(src/xlsx/qtxlsx.pri)
Ctrl + s 保存一下,就可以把QtXlsx源码模块加载进来啦!
可以在项目构造函数中添加如下代码进行测试:
cpp
#include "xlsxdocument.h"
#include "xlsxchartsheet.h"
#include "xlsxcellrange.h"
#include "xlsxchart.h"
#include "xlsxrichstring.h"
#include "xlsxworkbook.h"
QXlsx::Document xlsx;
xlsx.write(1, 2, "Hello Qt!");
xlsx.write(2, 2, QString::fromLocal8Bit("中文"));
xlsx.saveAs("Text.xlsx");
编译运行后,就可以在项目路径看到程序创建的Text.xlsx文件,打开后就可以看到写入的 "Hello Qt!"和"中文".
三、QtXlsx源码编译成为.lib库使用
1. 下载安装Perl
下载安装:Perl
下载链接:Strawberry Perl for Windows
注意,这个是一定要下载安装的,否则编译lib库会编译失败!!!
下载后默认安装即可
2. 编译QtXlsx
打开下载的QtXlsx文件夹,双击打开.pro
根据自己安装的vs版本,选择相应的msvc编译
打开后直接点击编译
编译完成后,就可以在相应路径找到编译好的lib库
3. 在vs中使用
新建vsQT项目,将include文件夹和Qt5Xlsxd.dll和Qt5Xlsxd.lib拷贝到项目路径中;
将QtXlsxWriter-master文件夹整个拷贝到项目路径中;
拷贝之后项目路径文件,下图方框中的就是我们需要拷贝的文件
右键项目 - 属性 - C/C++ - 常规 - 附加包含目录,把头文件路径添加进来
右键项目 - 属性 - 链接器 - 输入 - 附加依赖项,添加Qt5Xlsxd.lib
之后,可以加入头文件
cpp
#include "xlsxdocument.h"
#include "xlsxchartsheet.h"
#include "xlsxcellrange.h"
#include "xlsxchart.h"
#include "xlsxrichstring.h"
#include "xlsxworkbook.h"
在构造函数中加入代码
cpp
QXlsx::Document xlsx;
xlsx.write(1, 2, "Hello Qt!");
xlsx.write(2, 2, QString::fromLocal8Bit("中文"));
xlsx.saveAs("Text.xlsx");
编译运行,不出意外的话, 在项目路径会一个名为Text.xlsx的文件,双击打开
数据也已经写入,测试成功!
四、QtXlsx
- 知识点
a. 定义
cpp
QXlsx::Document xlsx;
QXlsx::Document xlsx("Text.xlsx");
b. 往单元格中写入数据
cpp
write
xlsx.write(2, 2, "中文"); 参数一是行,参数二是列,参数三是数据
xlsx.write("C3", "C3"); 参数一是对应单元格名字,参数二是数据
c. 设置行高
cpp
setRowHeight
xlsx.setRowHeight(4, 30); 设置第四行高度为30
d. 设置列宽
cpp
setColumnWidth
xlsx.setColumnWidth(3, 50); 设置第三列宽度为50
e. 设置单元格样式
cpp
QXlsx::Format format;
format.setFontColor(Qt::red); // 设置字体颜色为红色
format.setFontBold(true); // 设置加粗
format.setFontSize(30); // 设置字体大小
format.setFontItalic(true); // 设置倾斜
format.setFontName("楷体"); // 设置字体
format.setPatternBackgroundColor(QColor(100, 200, 100)); // 设置单元格背景颜色
format.setHorizontalAlignment(QXlsx::Format::AlignHCenter); // 设置水平居中,更多参考enum HorizontalAlignment枚举
format.setVerticalAlignment(QXlsx::Format::AlignVCenter); // 设置垂直居中
format.setBorderColor(QColor(50, 50, 50)); // 设置边框颜色
format.setFontUnderline(QXlsx::Format::FontUnderlineDouble); // 设置双下划线,更多参考enum FontUnderline枚举
format.setFontUnderline(QXlsx::Format::FontUnderlineSingle); // 设置单下划线
format.setFillPattern(QXlsx::Format::PatternLightUp); // 填充方式,更多参考enum FillPattern枚举
xlsx.write("C4", "红色|加粗|30", format); 作为第三个参数
f. 设置单元格方框
cpp
setBorderStyle
format.setBorderStyle(QXlsx::Format::BorderThin); 更多参考enum BorderStyle枚举
g. 合并单元格
cpp
mergeCells
xlsx.mergeCells("C4:E6"); 参数指定那个单元格区间
h. 取消合并
cpp
unmergeCells
xlsx.unmergeCells("C4:E6"); 参数指定的单元格区间一定是要已经合并的,否则打开xlsx文件报错
i. 读取单元格中的数据
cpp
read
QString str1 = xlsx.read(1, 1).toString(); 指定行列获取
QString str2 = xlsx.read("B2").toString(); 指定单元格名字获取
j. 获得单元格对象
cpp
cellAt
QXlsx::Cell *cell = xlsx.cellAt("C4"); 获取到的是指针对象
QXlsx::Cell *cell = xlsx.cellAt(1, 1);
cell->value(); 可以通过value()函数获取单元格中的值
k. 添加工作表
cpp
addSheet
xlsx.addSheet("sheet_2"); 添加这一张名为"sheet_2"的工作表
l. 工作表重命名
cpp
renameSheet
xlsx.workbook()->renameSheet(1, "sheet_3"); 将索引为1(也就是第二张)的工作表命名为"sheet_3"
m. 选择当前工作表
cpp
selectSheet
xlsx.selectSheet("sheet_3"); 选择名为"sheet_3"的工作表为当前xlsx工作表
n. 获得所有工作表的名字
cpp
sheetNames
QStringList sheetList = xlsx.sheetNames(); 获取返回的是一个字符串链表
o. 获取工作簿对象
cpp
workbook
QXlsx::Workbook *workBook = xlsx.workbook();
p. 获取当前工作簿的第一张sheet工作表
cpp
QXlsx::Worksheet *workSheet = static_cast<QXlsx::Worksheet*>(workBook->sheet(0));
q. 获取当前sheet表所使用到的行数
cpp
int row = workSheet->dimension().rowCount();
r. 获取当前sheet表所使用到的列数
cpp
int colum = workSheet->dimension().columnCount();
s. 遍历sheet表中有数据的单元格
cpp
for (int i = 0; i < row; i++) {
for (int j = 0; j < colum; j++) {
// 获取单元格
QXlsx::Cell *cell = workSheet->cellAt(i, j); // 读取单元格
if (cell) {
qDebug() << "(" << i << ", " << j << ")\t" << cell->value().toString().trimmed(); // trimmed 去除字符串两侧的空格
}
}
}
t. 删除单元格数据
cpp
xlsx.write("G5", ""); 直接重新设置为空即可
u. 修改单元格数据
cpp
xlsx.write("G6", "修改"); 重新对单元格写入数据即可
v. 保存
cpp
saveAs
xlsx.saveAs("Text.xlsx"); 初始化xlsx对象时没有指定excel文件,那么保存时使用这个
save
xlsx.save(); 初始化xlsx对象时,指定了excel文件,那么保存时使用这个
w. 设置单元格中字符串不同字体颜色
RichString
cpp
QXlsx::Document xlsx("Text.xlsx");
QXlsx::Format blue; // 设置字体颜色
blue.setFontColor(Qt::blue);
QXlsx::Format red;
red.setFontColor(Qt::red);
red.setFontSize(20); // 设置字体大小
QXlsx::Format bold;
bold.setFontBold(true); // 设置字体加粗
QXlsx::RichString rich;
rich.addFragment("test", blue);
rich.addFragment("QT", red);
rich.addFragment("中文", bold);
xlsx.write("C3", rich);
xlsx.save();
x. 给单元格命名
cpp
xlsx.defineName("Cell_1", "=Sheet1!$A$1:$A$10"); // A1-A10命名为Cell_1
xlsx.defineName("Cell_2", "=Sheet1!$B$1:$B$10", "这是描述信息"); // B1-B10命名为Cell_2
y. 赋值
cpp
xlsx.defineName("Factor", "=0.5"); // 将0.5赋值给Factor,相当于变量赋值一样,我们就可以使用这个变量了
z. 使用公式
cpp
xlsx.write(11, 1, "=SUM(Cell_1)"); // 计算A1-A10数据总和,并写入(11,1)单元格中
xlsx.write(15, 1, "=SUM($A$1:$A$10)"); // 计算A1-A10数据总和,并写入(15,1)单元格中
使用公式和变量
cpp
xlsx.write(12, 1, "=SUM(Cell_1)*Factor"); // 计算A1-A10数据总和再乘以0.5,并写入(12,1)单元格中
xlsx.write(16, 1, "=SUM($A$1:$A$10)*Factor"); // 计算A1-A10数据总和再乘以0.5,并写入(16,1)单元格中
xlsx.write(13, 2, "=SUM($B$1:B$10)*0.1"); // B1 - B10 计算总和后乘以0.1
五、QtXlsx知识点补充
1.QStringList sheetNames() const
2.bool addSheet(const QString &name = QString(), AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet)
3.bool insertSheet(int index, const QString &name = QString(), AbstractSheet::SheetType type = AbstractSheet::ST_WorkSheet)
4.bool renameSheet(const QString &oldName, const QString &newName)
5.bool moveSheet(const QString &srcName, int distIndex)
6.bool deleteSheet(const QString &name)
7.AbstractSheet *Document::sheet(const QString &sheetName) const
8.AbstractSheet::SheetState AbstractSheet::sheetState() const
9.void AbstractSheet::setSheetState(SheetState state)
10.bool AbstractSheet::isHidden() const
11.bool AbstractSheet::isVisible() const
12.void AbstractSheet::setHidden(bool hidden)
13.void AbstractSheet::setVisible(bool visible)\
14.Chart *Document::insertChart(int row, int col, const QSize &size)
15.void Chart::setChartType(ChartType type)
16.void Chart::addSeries(const CellRange &range, AbstractSheet *sheet, bool headerH, bool headerV, bool swapHeaders)
17.void Chart::setChartLegend(Chart::ChartAxisPos legendPos, bool overlay)
18.void Chart::setChartTitle(QString strchartTitle)
19.void Chart::setGridlinesEnable(bool majorGridlinesEnable, bool minorGridlinesEnable)
20.int Document::insertImage(int row, int column, const QImage &image)
21.uint Document::getImageCount()
22.bool Document::getImage(int imageIndex, QImage& img)
23.bool Document::getImage(int row, int col, QImage &img)
不错的连接:https://blog.csdn.net/qq_43627907/category_11756312.html