Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions Example.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# QXlsx Examples

---

## [HelloWorld](https://github.com/QtExcel/QXlsx/tree/master/HelloWorld)

- Hello world example
Expand Down Expand Up @@ -53,6 +55,10 @@ int main(int argc, char *argv[])
}
```

<br />

---

## [TestExcel](https://github.com/QtExcel/QXlsx/tree/master/TestExcel)

- :zap: Basic examples (based on QtXlsx examples)
Expand All @@ -77,6 +83,11 @@ int main(int argc, char *argv[])

![](markdown.data/testexcel.png)


<br />

---

## [HelloAndroid](https://github.com/QtExcel/QXlsx/tree/master/HelloAndroid)

- See 'HelloAndroid' example using QML and native C++.
Expand All @@ -87,25 +98,45 @@ int main(int argc, char *argv[])

![](markdown.data/android.jpg)


<br />

---

## [WebServer](https://github.com/QtExcel/QXlsx/tree/master/WebServer)
- Load xlsx file and display on Web.
- Connect to `http://127.0.0.1:3001`
- C++ 14(17) is required. Old compilers is not supported.

![](markdown.data/webserver.png)


<br />

---

## [ShowConsole](https://github.com/QtExcel/QXlsx/tree/master/ShowConsole)
- Load xlsx file and display in console.
- [Usage] ShowConsole *.xlsx
- C++ 11 is required. Old compilers is not supported.

![](markdown.data/show-console.jpg)


<br />

---

## [ReadColor](https://github.com/QtExcel/QXlsx/tree/master/ReadColor)
- Read cell color

![](markdown.data/read-color.jpg)


<br />

---

## [csv](https://github.com/QtExcel/QXlsx/tree/master/csv)
- Save the `xlsx` file as a `csv` file.
```cpp
Expand All @@ -121,11 +152,19 @@ int main(int argc, char *argv[])
}
```

<br />

---

## [ExcelViewer](https://github.com/QtExcel/QXlsx/tree/master/ExcelViewer)
- Load xlsx file and display on Qt widgets.

![](markdown.data/excel-viewer.jpg)

<br />

---

## XlsxFactory
- Load xlsx file and display on Qt widgets.
- Moved to personal repository for advanced app.
Expand All @@ -135,6 +174,10 @@ int main(int argc, char *argv[])
![](markdown.data/copycat.png)
![](markdown.data/copycat2.jpg)

<br />

---

## [LargeData](https://github.com/QtExcel/QXlsx/tree/master/LargeData)
- `LargeData` example demonstrates how to efficiently generate, write, and read large Excel `.xlsx` files using `QXlsx`.
- It showcases:
Expand Down Expand Up @@ -172,4 +215,24 @@ LargeData -r 300000 -c 15 -S 60000 --use-style
All options combined
```

<br />

---

## [ExcelTableEditor](https://github.com/QtExcel/QXlsx/tree/master/ExcelTableEditor)

![](markdown.data/excel-table-editor.jpg)

- Load Excel files with `multiple sheets`
- Display sheet contents in a `QTableView`
- Edit all cells (including row 1)
- Boolean values displayed as checkboxes
- Read & preserve basic cell formatting (font, alignment, colors)
- Sheet operations:
- Rename sheet
- Add new sheet
- Delete sheet
- Reorder sheets (move left/right)
- Save or Save As to produce a modified workbook


34 changes: 34 additions & 0 deletions ExcelTableEditor/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
cmake_minimum_required(VERSION 3.26)

project(ExcelTableEditor LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC OFF)

# QXlsx library
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../QXlsx QXlsx_build)

# Qt 6
find_package(Qt6 COMPONENTS Core Widgets REQUIRED)

add_executable(ExcelTableEditor
main.cpp
mainwindow.h
mainwindow.cpp
excelitemdelegate.h
excelitemdelegate.cpp
)

target_link_libraries(ExcelTableEditor
PRIVATE
Qt6::Core
Qt6::Widgets
QXlsx::QXlsx
)

set(CMAKE_WIN32_EXECUTABLE ON)
36 changes: 36 additions & 0 deletions ExcelTableEditor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

# ExcelTableEditor

This example demonstrates how to build a simple Excel editor using **Qt Widgets** and **QXlsx**.
It shows how to load workbook data into Qt models, edit sheets, and write the modified content back to an `.xlsx` file.

## Features

* Load Excel files with **multiple sheets**
* Display sheet contents in a `QTableView`
* Edit all cells (including row 1)
* Boolean values displayed as checkboxes
* Read & preserve basic cell formatting (font, alignment, colors)
* Sheet operations:
* **Rename sheet**
* **Add new sheet**
* **Delete sheet**
* **Reorder sheets** (move left/right)
* Save or Save As to produce a modified workbook

## User Interface

* A sheet toolbar allows selecting the active worksheet, renaming it, adding/removing sheets, and changing sheet order.
* The main area is a `QTableView` backed by a `QStandardItemModel`, making the sheet fully editable.

## How it Works

* Each worksheet is mapped to its own `QStandardItemModel`.
* All sheet data (including row 1) is loaded as editable items.
* Formatting is stored per-cell and reapplied to the item view.
* When saving:
* A new `QXlsx::Document` is created
* Sheets are added in the current order
* Cell values and (available) formatting are written back


111 changes: 111 additions & 0 deletions ExcelTableEditor/excelitemdelegate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include "excelitemdelegate.h"

#include <QDoubleSpinBox>
#include <QDateEdit>
#include <QDateTimeEdit>
#include <QLineEdit>

// Implement Delegate to provide appropriate editors based on Excel cell type

ExcelItemDelegate::ExcelItemDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}

QWidget *ExcelItemDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
Q_UNUSED(option);

// Determine the type based on EditRole data
const QVariant value = index.data(Qt::EditRole);
const int type_id = value.userType();

// numeric series: editing with double/spinbox
if (value.canConvert<double>() &&
type_id != QMetaType::QString &&
type_id != QMetaType::Bool) {
auto *spin = new QDoubleSpinBox(parent);
spin->setDecimals(6);
spin->setRange(-1e9, 1e9);
spin->setSingleStep(1.0);
return spin;
}

// Date/Time: QDateEdit / QDateTimeEdit
if (type_id == QMetaType::QDate) {
auto *date_edit = new QDateEdit(parent);
date_edit->setCalendarPopup(true);
date_edit->setDisplayFormat("yyyy-MM-dd");
return date_edit;
}

if (type_id == QMetaType::QDateTime) {
auto *dt_edit = new QDateTimeEdit(parent);
dt_edit->setCalendarPopup(true);
dt_edit->setDisplayFormat("yyyy-MM-dd hh:mm:ss");
return dt_edit;
}

// String and others: using default QLineEdit
auto *line_edit = new QLineEdit(parent);
return line_edit;
}

void ExcelItemDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
const QVariant value = index.data(Qt::EditRole);
const int type_id = value.userType();

if (auto *spin = qobject_cast<QDoubleSpinBox *>(editor)) {
spin->setValue(value.toDouble());
return;
}

if (auto *date_edit = qobject_cast<QDateEdit *>(editor)) {
date_edit->setDate(value.toDate());
return;
}

if (auto *dt_edit = qobject_cast<QDateTimeEdit *>(editor)) {
dt_edit->setDateTime(value.toDateTime());
return;
}

if (auto *line_edit = qobject_cast<QLineEdit *>(editor)) {
// Number/date can be shown after string conversion
line_edit->setText(value.toString());
return;
}

QStyledItemDelegate::setEditorData(editor, index);
}

void ExcelItemDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const
{
if (auto *spin = qobject_cast<QDoubleSpinBox *>(editor)) {
model->setData(index, spin->value(), Qt::EditRole);
return;
}

if (auto *date_edit = qobject_cast<QDateEdit *>(editor)) {
model->setData(index, date_edit->date(), Qt::EditRole);
return;
}

if (auto *dt_edit = qobject_cast<QDateTimeEdit *>(editor)) {
model->setData(index, dt_edit->dateTime(), Qt::EditRole);
return;
}

if (auto *line_edit = qobject_cast<QLineEdit *>(editor)) {
model->setData(index, line_edit->text(), Qt::EditRole);
return;
}

QStyledItemDelegate::setModelData(editor, model, index);
}
24 changes: 24 additions & 0 deletions ExcelTableEditor/excelitemdelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef EXCELITEMDELEGATE_H
#define EXCELITEMDELEGATE_H

#include <QStyledItemDelegate>

class ExcelItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit ExcelItemDelegate(QObject *parent = nullptr);

QWidget *createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override;

void setEditorData(QWidget *editor,
const QModelIndex &index) const override;

void setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const override;
};

#endif // EXCELITEMDELEGATE_H
13 changes: 13 additions & 0 deletions ExcelTableEditor/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

MainWindow w;
w.resize(900, 600);
w.show();

return app.exec();
}
Loading