1.簡介
一直以來,都想學習一下C/C++如何操作excel表,在網上調研了一下,覺得使用C/C++去操作很麻煩,遂轉向QT這邊;QT有一個自帶的類QAxObject,可以使用他去操作,但隨著了解的深入,覺得他并不是很好,有很多其他缺陷(例如必須電腦安裝了辦公軟件才可以進行操作等),所以繼續調研,終于找到了QT的一個第三方庫可以很好的實現:QtXlsx.?
?
Github下載:https://github.com/dbzhang800/QtXlsxWriter
官方文檔:http://qtxlsx.debao.me/
在Github下載后,可以直接添加到QtCreator項目中,也可以編譯成lib庫后再添加到VS中去使用。
2、下載QtXlsx
點擊鏈接進入Github下載
?下載解壓后得到如下文件
二、QtXlsx源碼嵌入QTCreator中使用
新建一個QTCreator窗體項目
將上圖src文件夾拷貝到該項目路徑中
之后雙擊項目中的.pro文件
將如下代碼拷貝到.pro文件中
include(src/xlsx/qtxlsx.pri)
Ctrl + s?保存一下,就可以把QtXlsx源碼模塊加載進來啦!
可以在項目構造函數中添加如下代碼進行測試:
#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
之后,可以加入頭文件
#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的文件,雙擊打開
?數據也已經寫入,測試成功!?
四、QtXlsx
1. 知識點
a. 定義
QXlsx::Document xlsx;QXlsx::Document xlsx("Text.xlsx");
b. 往單元格中寫入數據
writexlsx.write(2, 2, "中文"); ? ? ? ? 參數一是行,參數二是列,參數三是數據xlsx.write("C3", "C3"); ? ? ? ?參數一是對應單元格名字,參數二是數據
c. 設置行高
setRowHeightxlsx.setRowHeight(4, 30); ? ? ? ?設置第四行高度為30
d. 設置列寬
setColumnWidthxlsx.setColumnWidth(3, 50); ? ? ? ? 設置第三列寬度為50
?e. 設置單元格樣式
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. 設置單元格方框
setBorderStyleformat.setBorderStyle(QXlsx::Format::BorderThin); ? ? ? ?更多參考enum BorderStyle枚舉
g. 合并單元格
mergeCellsxlsx.mergeCells("C4:E6"); ? ? ? ?參數指定那個單元格區間
h. 取消合并
unmergeCellsxlsx.unmergeCells("C4:E6"); ? ? ? ?參數指定的單元格區間一定是要已經合并的,否則打開xlsx文件報錯
i. 讀取單元格中的數據
readQString str1 = xlsx.read(1, 1).toString(); ? ? ? ?指定行列獲取QString str2 = xlsx.read("B2").toString(); ? ? ? ?指定單元格名字獲取
j. 獲得單元格對象
cellAtQXlsx::Cell *cell = xlsx.cellAt("C4"); ? ? ? ? ? ? ? ?獲取到的是指針對象QXlsx::Cell *cell = xlsx.cellAt(1, 1);cell->value(); ? ? ? ?可以通過value()函數獲取單元格中的值
k. 添加工作表
addSheetxlsx.addSheet("sheet_2"); ? ? ? ?添加這一張名為“sheet_2”的工作表
l. 工作表重命名
renameSheetxlsx.workbook()->renameSheet(1, "sheet_3"); ? ? ? ?將索引為1(也就是第二張)的工作表命名為“sheet_3”
m. 選擇當前工作表
selectSheetxlsx.selectSheet("sheet_3"); ? ? ? ?選擇名為“sheet_3”的工作表為當前xlsx工作表
n. 獲得所有工作表的名字
sheetNames
QStringList sheetList = xlsx.sheetNames(); ? ? ? ?獲取返回的是一個字符串鏈表
o. 獲取工作簿對象
workbookQXlsx::Workbook *workBook = xlsx.workbook();
p. 獲取當前工作簿的第一張sheet工作表
QXlsx::Worksheet *workSheet = static_cast<QXlsx::Worksheet*>(workBook->sheet(0));
q. 獲取當前sheet表所使用到的行數
int row = workSheet->dimension().rowCount();
r. 獲取當前sheet表所使用到的列數
int colum = workSheet->dimension().columnCount();
s. 遍歷sheet表中有數據的單元格
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. 刪除單元格數據
xlsx.write("G5", ""); ? ? ? ?直接重新設置為空即可
u. 修改單元格數據
xlsx.write("G6", "修改"); ? ? ? ?重新對單元格寫入數據即可
v. 保存
saveAsxlsx.saveAs("Text.xlsx"); ? ? ? ?初始化xlsx對象時沒有指定excel文件,那么保存時使用這個savexlsx.save(); ? ? ? ?初始化xlsx對象時,指定了excel文件,那么保存時使用這個
w. 設置單元格中字符串不同字體顏色
RichString
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. 給單元格命名
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. 賦值
xlsx.defineName("Factor", "=0.5");???????? // 將0.5賦值給Factor,相當于變量賦值一樣,我們就可以使用這個變量了
z. 使用公式
xlsx.write(11, 1, "=SUM(Cell_1)"); ?// 計算A1-A10數據總和,并寫入(11,1)單元格中
xlsx.write(15, 1, "=SUM($A$1:$A$10)"); ?// 計算A1-A10數據總和,并寫入(15,1)單元格中
使用公式和變量
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???????