mirror of
https://github.com/QtExcel/QXlsx.git
synced 2025-01-30 05:02:52 +08:00
move copycat to personal repository
This commit is contained in:
parent
8b0d3cf838
commit
4d849bf739
@ -1,54 +0,0 @@
|
||||
# Copycat.pro
|
||||
|
||||
TARGET = Copycat
|
||||
TEMPLATE = app
|
||||
|
||||
QT += core
|
||||
QT += gui
|
||||
QT += widgets
|
||||
QT += printsupport
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
# NOTE: You can fix value of QXlsx path of source code.
|
||||
# QXLSX_PARENTPATH=./
|
||||
# QXLSX_HEADERPATH=./header/
|
||||
# QXLSX_SOURCEPATH=./source/
|
||||
include(../QXlsx/QXlsx.pri)
|
||||
|
||||
INCLUDEPATH += \
|
||||
./Qt-Table-Printer
|
||||
|
||||
HEADERS += \
|
||||
./Qt-Table-Printer/tableprinter.h \
|
||||
MainWindow.h \
|
||||
XlsxTab.h \
|
||||
xlsx.h \
|
||||
CopycatTableModel.h \
|
||||
XlsxTableWidget.h
|
||||
|
||||
SOURCES += \
|
||||
./Qt-Table-Printer/tableprinter.cpp \
|
||||
main.cpp \
|
||||
MainWindow.cpp \
|
||||
XlsxTab.cpp \
|
||||
CopycatTableModel.cpp \
|
||||
XlsxTableWidget.cpp
|
||||
|
||||
FORMS += \
|
||||
MainWindow.ui
|
||||
|
||||
RESOURCES += \
|
||||
resources.qrc
|
||||
|
@ -1,122 +0,0 @@
|
||||
// CopycatTableModel.cpp
|
||||
// QXlsx // MIT License // https://github.com/j2doll/QXlsx
|
||||
|
||||
#include "CopycatTableModel.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QVariant>
|
||||
|
||||
CopycatTableModel::CopycatTableModel(QList<QString> colTitle, QList<VLIST> data, QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
// [1] set name of column
|
||||
|
||||
for ( int ic = 0; ic < colTitle.size() ; ic++ )
|
||||
{
|
||||
std::string colString = convertFromNumberToExcelColumn( ic );
|
||||
// QString strCol = colTitle.at(ic);
|
||||
QString strCol = QString::fromStdString( colString );
|
||||
m_colNames.append( strCol );
|
||||
}
|
||||
m_roleCount = m_colNames.size();
|
||||
|
||||
// [2] set data
|
||||
|
||||
for ( int dc = 0; dc < data.size() ; dc++ )
|
||||
{
|
||||
VLIST vList = data.at(dc);
|
||||
m_the_data.append( vList );
|
||||
}
|
||||
}
|
||||
|
||||
int CopycatTableModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_the_data.size();
|
||||
}
|
||||
|
||||
int CopycatTableModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
return m_roleCount;
|
||||
}
|
||||
|
||||
QVariant CopycatTableModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
// current column & row
|
||||
int col = index.column();
|
||||
int row = index.row();
|
||||
|
||||
// check boudaries
|
||||
if ( col < 0 || columnCount() <= col ||
|
||||
row < 0 || rowCount() <= row )
|
||||
{
|
||||
qDebug() << "[Warning]" << " col=" << col << ", row=" << row;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// Nominal case
|
||||
|
||||
QVariant ret;
|
||||
int cmpRole;
|
||||
|
||||
for (int ic = 0; ic < m_the_data.size() ; ic++)
|
||||
{
|
||||
if ( row == ic )
|
||||
{
|
||||
QList<QVariant> vList = m_the_data.at(ic);
|
||||
for (int jc = 0; jc < vList.size() ; jc++ )
|
||||
{
|
||||
if ( col == jc &&
|
||||
row == ic )
|
||||
{
|
||||
QVariant var = vList.at(jc);
|
||||
if ( ! var.isValid() )
|
||||
var.setValue( QString("") ) ;
|
||||
if ( var.isNull() )
|
||||
var.setValue( QString("") ) ;
|
||||
ret = var;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string CopycatTableModel::convertFromNumberToExcelColumn(int n)
|
||||
{
|
||||
// main code from https://www.geeksforgeeks.org/find-excel-column-name-given-number/
|
||||
// Function to print Excel column name for a given column number
|
||||
|
||||
std::string stdString;
|
||||
|
||||
char str[1000]; // To store result (Excel column name)
|
||||
int i = 0; // To store current index in str which is result
|
||||
|
||||
while ( n > 0 )
|
||||
{
|
||||
// Find remainder
|
||||
int rem = n % 26;
|
||||
|
||||
// If remainder is 0, then a 'Z' must be there in output
|
||||
if ( rem == 0 )
|
||||
{
|
||||
str[i++] = 'Z';
|
||||
n = (n/26) - 1;
|
||||
}
|
||||
else // If remainder is non-zero
|
||||
{
|
||||
str[i++] = (rem-1) + 'A';
|
||||
n = n / 26;
|
||||
}
|
||||
}
|
||||
str[i] = '\0';
|
||||
|
||||
// Reverse the string and print result
|
||||
std::reverse( str, str + strlen(str) );
|
||||
|
||||
stdString = str;
|
||||
return stdString;
|
||||
}
|
||||
|
@ -1,46 +0,0 @@
|
||||
// CopycatTableModel.h
|
||||
// QXlsx // MIT License // https://github.com/j2doll/QXlsx
|
||||
|
||||
#ifndef XLSX_MODEL_H
|
||||
#define XLSX_MODEL_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
typedef QList<QVariant> VLIST;
|
||||
|
||||
class CopycatTableModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public: // constrcutor
|
||||
CopycatTableModel(QList<QString> colTitle, QList<VLIST> data, QObject *parent = NULL);
|
||||
|
||||
public: // virtual function of parent object
|
||||
int rowCount(const QModelIndex & parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
|
||||
|
||||
protected:
|
||||
QList<VLIST> m_the_data; // table cell data
|
||||
QList<QString> m_colNames; // column name
|
||||
quint32 m_roleCount; // role count (same as column count)
|
||||
|
||||
std::string convertFromNumberToExcelColumn(int n);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,363 +0,0 @@
|
||||
// MainWindow.cpp
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QString>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QPrinter>
|
||||
#include <QPrintPreviewDialog>
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
#include <QVector>
|
||||
#include <QList>
|
||||
#include <QSharedPointer>
|
||||
#include <QInputDialog>
|
||||
#include <QStringList>
|
||||
#include <QVarLengthArray>
|
||||
|
||||
#include "xlsxcelllocation.h"
|
||||
#include "xlsxcell.h"
|
||||
#include "CopycatTableModel.h"
|
||||
#include "tableprinter.h"
|
||||
#include "MainWindow.h"
|
||||
#include "ui_MainWindow.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
{
|
||||
xlsxDoc = NULL;
|
||||
tabWidget = NULL;
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
tabWidget = new QTabWidget(this);
|
||||
setCentralWidget(tabWidget);
|
||||
|
||||
this->setWindowTitle(QString("Copycat"));
|
||||
|
||||
setWindowIcon(QIcon(":/excel.ico"));
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete ui;
|
||||
|
||||
if ( NULL != xlsxDoc )
|
||||
{
|
||||
delete xlsxDoc;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_action_Quit_triggered()
|
||||
{
|
||||
// quit
|
||||
this->close();
|
||||
}
|
||||
|
||||
void MainWindow::on_action_Open_triggered()
|
||||
{
|
||||
// open file dialog
|
||||
QString fileName = QFileDialog::getOpenFileName(this,
|
||||
tr("Open Excel"), ".", tr("Excel Files (*.xlsx)"));
|
||||
|
||||
if ( ! loadXlsx(fileName) ) // load xlsx
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
QString alertMsg = QString("Failed to load file.\n %1").arg(fileName);
|
||||
msgBox.setIcon( QMessageBox::Critical );
|
||||
msgBox.setText( alertMsg );
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
this->setWindowTitle(fileName);
|
||||
|
||||
}
|
||||
|
||||
bool MainWindow::loadXlsx(QString fileName)
|
||||
{
|
||||
// tried to load xlsx using temporary document
|
||||
QXlsx::Document xlsxTmp( fileName );
|
||||
if ( !xlsxTmp.isLoadPackage() )
|
||||
{
|
||||
return false; // failed to load
|
||||
}
|
||||
|
||||
// clear xlsxDoc
|
||||
if ( NULL != xlsxDoc )
|
||||
{
|
||||
delete xlsxDoc;
|
||||
xlsxDoc = NULL;
|
||||
}
|
||||
|
||||
// load new xlsx using new document
|
||||
xlsxDoc = new QXlsx::Document( fileName );
|
||||
xlsxDoc->isLoadPackage();
|
||||
|
||||
// clear tab widget
|
||||
tabWidget->clear();
|
||||
// Removes all the pages, but does not delete them.
|
||||
// Calling this function is equivalent to calling removeTab()
|
||||
// until the tab widget is empty.
|
||||
|
||||
// clear sub-items of every tab
|
||||
foreach ( XlsxTab* ptrTab, xlsxTabList )
|
||||
{
|
||||
if ( NULL == ptrTab )
|
||||
continue;
|
||||
delete ptrTab;
|
||||
}
|
||||
xlsxTabList.clear();
|
||||
|
||||
int sheetIndexNumber = 0;
|
||||
int activeSheetNumber = -1;
|
||||
|
||||
AbstractSheet* activeSheet = xlsxDoc->workbook()->activeSheet();
|
||||
// NOTICE: active sheet is lastest sheet. It's not focused sheet.
|
||||
|
||||
foreach( QString curretnSheetName, xlsxDoc->sheetNames() )
|
||||
{
|
||||
QXlsx::AbstractSheet* currentSheet = xlsxDoc->sheet( curretnSheetName );
|
||||
if ( NULL == currentSheet )
|
||||
continue;
|
||||
|
||||
if ( activeSheet == currentSheet )
|
||||
{
|
||||
// current sheet is active sheet.
|
||||
activeSheetNumber = sheetIndexNumber;
|
||||
}
|
||||
|
||||
XlsxTab* newSheet = new XlsxTab( this, xlsxDoc, currentSheet, sheetIndexNumber ); // create new tab
|
||||
xlsxTabList.push_back( newSheet ); // append to xlsx pointer list
|
||||
tabWidget->addTab( newSheet, curretnSheetName ); // add tab widget
|
||||
sheetIndexNumber++; // increase sheet index number
|
||||
}
|
||||
|
||||
if ( (-1) != activeSheetNumber )
|
||||
tabWidget->setCurrentIndex(activeSheetNumber);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MainWindow::on_action_About_triggered()
|
||||
{
|
||||
QString text =
|
||||
"QXlsx Copycat<br />"
|
||||
"<a href=\"https://github.com/QtExcel/QXlsx\">https://github.com/QtExcel/QXlsx</a><br />" ;
|
||||
|
||||
QMessageBox::about(this, "QXlsx", text);
|
||||
}
|
||||
|
||||
void MainWindow::on_action_New_triggered()
|
||||
{
|
||||
// TODO: new document
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( "TODO: New xlsx" );
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
void MainWindow::on_action_Save_triggered()
|
||||
{
|
||||
// TODO: save document
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( "TODO: Save xlsx" );
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
void MainWindow::on_action_Print_triggered()
|
||||
{
|
||||
if ( NULL == xlsxDoc )
|
||||
return;
|
||||
|
||||
QPrintPreviewDialog dialog;
|
||||
connect(&dialog, SIGNAL(paintRequested(QPrinter*)), this, SLOT(print(QPrinter*)));
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void MainWindow::print(QPrinter *printer)
|
||||
{
|
||||
if ( NULL == xlsxDoc )
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( "xlsx document is empty." );
|
||||
msgBox.setIcon( QMessageBox::Warning );
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
Worksheet* wsheet = (Worksheet*) xlsxDoc->workbook()->activeSheet();
|
||||
if ( NULL == wsheet )
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( "worksheet is set." );
|
||||
msgBox.setIcon( QMessageBox::Warning );
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList items;
|
||||
foreach( QString curretnSheetName, xlsxDoc->sheetNames() )
|
||||
{
|
||||
items << curretnSheetName;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
QString selectedItem
|
||||
= QInputDialog::getItem( this, tr("QXlsx"), tr("Select sheet:"), items, 0, false, &ok );
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( "Please select printable sheet" );
|
||||
msgBox.setIcon( QMessageBox::Warning );
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
foreach (const QString& varList, items)
|
||||
{
|
||||
if ( varList == selectedItem )
|
||||
{
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
xlsxDoc->workbook()->setActiveSheet( idx );
|
||||
wsheet = (Worksheet*) xlsxDoc->workbook()->activeSheet(); // set active sheet
|
||||
|
||||
QList<QString> colTitle;
|
||||
QList<VLIST> xlsxData;
|
||||
QVector<int> printColumnStretch;
|
||||
int sheetIndexNumber = 0;
|
||||
|
||||
int maxRow = -1;
|
||||
int maxCol = -1;
|
||||
QVector<CellLocation> clList = wsheet->getFullCells( &maxRow, &maxCol );
|
||||
|
||||
// Fixed for Visual C++, cause VC++ does not support C99.
|
||||
// https://docs.microsoft.com/en-us/cpp/c-language/ansi-conformance?view=vs-2017
|
||||
// QString arr[maxRow][maxCol];
|
||||
|
||||
QVector <QVector <QString> > arr;
|
||||
|
||||
for (int i = 0; i < maxRow; i++)
|
||||
{
|
||||
QVector<QString> tempVector;
|
||||
for (int j = 0; j < maxCol; j++)
|
||||
{
|
||||
tempVector.push_back(QString(""));
|
||||
}
|
||||
arr.push_back(tempVector);
|
||||
}
|
||||
|
||||
for ( int ic = 0; ic < clList.size(); ++ic )
|
||||
{
|
||||
CellLocation cl = clList.at(ic);
|
||||
|
||||
int row = cl.row - 1;
|
||||
int col = cl.col - 1;
|
||||
|
||||
QSharedPointer<Cell> ptrCell = cl.cell; // cell pointer
|
||||
|
||||
QString strValue = ptrCell->value().toString();
|
||||
|
||||
arr[row][col] = strValue;
|
||||
}
|
||||
|
||||
for (int ir = 0 ; ir < maxRow; ir++)
|
||||
{
|
||||
VLIST vl;
|
||||
|
||||
for (int ic = 0 ; ic < maxCol; ic++)
|
||||
{
|
||||
QString strValue = arr[ir][ic];
|
||||
if ( strValue.isNull() )
|
||||
strValue = QString("");
|
||||
|
||||
vl.append( strValue );
|
||||
}
|
||||
|
||||
xlsxData.append( vl );
|
||||
}
|
||||
|
||||
QVector<QString> printHeaders;
|
||||
|
||||
for ( int ic = 0 ; ic < maxCol; ic++ )
|
||||
{
|
||||
std::string colString = convertFromNumberToExcelColumn( ( ic + 1 ) );
|
||||
QString strCol = QString::fromStdString( colString );
|
||||
|
||||
colTitle.append( strCol );
|
||||
printHeaders.append( strCol );
|
||||
|
||||
printColumnStretch.append( wsheet->columnWidth( (ic + 1) ) ); // TODO: check this code
|
||||
}
|
||||
|
||||
CopycatTableModel copycatTableModel(colTitle, xlsxData); // model
|
||||
|
||||
QPainter painter;
|
||||
if ( !painter.begin(printer) )
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( "Can't start printer" );
|
||||
msgBox.setIcon( QMessageBox::Critical );
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
// print table
|
||||
TablePrinter tablePrinter(&painter, printer);
|
||||
if ( !tablePrinter.printTable( ©catTableModel, printColumnStretch, printHeaders ) )
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText( tablePrinter.lastError() );
|
||||
msgBox.setIcon( QMessageBox::Warning );
|
||||
msgBox.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
// tablePrinter.setCellMargin( l, r, t, b );
|
||||
// tablePrinter.setPageMargin( l, r, t, b );
|
||||
|
||||
painter.end();
|
||||
}
|
||||
|
||||
std::string MainWindow::convertFromNumberToExcelColumn(int n)
|
||||
{
|
||||
// main code from https://www.geeksforgeeks.org/find-excel-column-name-given-number/
|
||||
// Function to print Excel column name for a given column number
|
||||
|
||||
std::string stdString;
|
||||
|
||||
char str[1000]; // To store result (Excel column name)
|
||||
int i = 0; // To store current index in str which is result
|
||||
|
||||
while ( n > 0 )
|
||||
{
|
||||
// Find remainder
|
||||
int rem = n % 26;
|
||||
|
||||
// If remainder is 0, then a 'Z' must be there in output
|
||||
if ( rem == 0 )
|
||||
{
|
||||
str[i++] = 'Z';
|
||||
n = (n/26) - 1;
|
||||
}
|
||||
else // If remainder is non-zero
|
||||
{
|
||||
str[i++] = (rem-1) + 'A';
|
||||
n = n / 26;
|
||||
}
|
||||
}
|
||||
str[i] = '\0';
|
||||
|
||||
// Reverse the string and print result
|
||||
std::reverse( str, str + strlen(str) );
|
||||
|
||||
stdString = str;
|
||||
return stdString;
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <QList>
|
||||
#include <QWidget>
|
||||
#include <QMainWindow>
|
||||
#include <QTabWidget>
|
||||
#include <QPrinter>
|
||||
|
||||
#include "xlsx.h"
|
||||
#include "XlsxTab.h"
|
||||
#include "CopycatTableModel.h"
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = 0);
|
||||
~MainWindow();
|
||||
|
||||
private slots:
|
||||
void on_action_Quit_triggered();
|
||||
void on_action_Open_triggered();
|
||||
void on_action_About_triggered();
|
||||
void on_action_New_triggered();
|
||||
void on_action_Save_triggered();
|
||||
void on_action_Print_triggered();
|
||||
void print(QPrinter *printer);
|
||||
|
||||
protected:
|
||||
Ui::MainWindow *ui;
|
||||
QXlsx::Document* xlsxDoc;
|
||||
QTabWidget *tabWidget;
|
||||
QVector<XlsxTab*> xlsxTabList;
|
||||
|
||||
protected:
|
||||
bool loadXlsx(QString xlsxFilename);
|
||||
std::string convertFromNumberToExcelColumn(int n);
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
@ -1,90 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>480</width>
|
||||
<height>320</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget"/>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>480</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu_File">
|
||||
<property name="title">
|
||||
<string>&File</string>
|
||||
</property>
|
||||
<addaction name="action_New"/>
|
||||
<addaction name="action_Open"/>
|
||||
<addaction name="action_Save"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_Print"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_Quit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_Help">
|
||||
<property name="title">
|
||||
<string>&Help</string>
|
||||
</property>
|
||||
<addaction name="action_About"/>
|
||||
</widget>
|
||||
<addaction name="menu_File"/>
|
||||
<addaction name="menu_Help"/>
|
||||
</widget>
|
||||
<widget class="QToolBar" name="mainToolBar">
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusBar"/>
|
||||
<action name="action_New">
|
||||
<property name="text">
|
||||
<string>&New</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Open">
|
||||
<property name="text">
|
||||
<string>&Open</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Save">
|
||||
<property name="text">
|
||||
<string>&Save</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Quit">
|
||||
<property name="text">
|
||||
<string>&Quit</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_About">
|
||||
<property name="text">
|
||||
<string>&About</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Print">
|
||||
<property name="text">
|
||||
<string>&Print</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -1,27 +0,0 @@
|
||||
Copyright (c) 2016, Anton Onishchenko
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,285 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2016, Anton Onishchenko
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright notice, this
|
||||
** list of conditions and the following disclaimer.
|
||||
**
|
||||
** 2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||
** list of conditions and the following disclaimer in the documentation and/or other
|
||||
** materials provided with the distribution.
|
||||
**
|
||||
** 3. Neither the name of the copyright holder nor the names of its contributors may
|
||||
** be used to endorse or promote products derived from this software without
|
||||
** specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "tableprinter.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QPainter>
|
||||
#include <QPrinter>
|
||||
#include <QDebug>
|
||||
|
||||
TablePrinter::TablePrinter(QPainter* painter, QPrinter* printer) :
|
||||
painter(painter),
|
||||
printer(printer)
|
||||
{
|
||||
topMargin = 5;
|
||||
bottomMargin = 5;
|
||||
leftMargin = 10;
|
||||
rightMargin = 5;
|
||||
|
||||
headerHeight = 0;
|
||||
bottomHeight = 0;
|
||||
|
||||
leftBlank = 0;
|
||||
rightBlank = 0;
|
||||
|
||||
maxRowHeight = 1000;
|
||||
|
||||
pen = painter->pen();
|
||||
headersFont = painter->font();
|
||||
contentFont = painter->font();
|
||||
headerColor = painter->pen().color();
|
||||
contentColor = painter->pen().color();
|
||||
prepare = NULL;
|
||||
error = "No error";
|
||||
}
|
||||
|
||||
bool TablePrinter::printTable(const QAbstractItemModel* model, const QVector<int> columnStretch,
|
||||
const QVector<QString> headers) {
|
||||
|
||||
//--------------------------------- error checking -------------------------------------
|
||||
|
||||
int columnCount = model->columnCount();
|
||||
int count = columnStretch.count();
|
||||
if(count != columnCount) {
|
||||
error = "Different columns count in model and in columnStretch";
|
||||
return false;
|
||||
}
|
||||
count = headers.count();
|
||||
if(count != columnCount && count != 0) {
|
||||
error = "Different columns count in model and in headers";
|
||||
return false;
|
||||
}
|
||||
if(!printer->isValid()) {
|
||||
error = "printer.isValid() == false";
|
||||
return false;
|
||||
}
|
||||
if(!painter->isActive()) {
|
||||
error = "painter.isActive() == false";
|
||||
return false;
|
||||
}
|
||||
double tableWidth = painter->viewport().width() - leftBlank - rightBlank;
|
||||
if(tableWidth <= 0) {
|
||||
error = "wrong table width";
|
||||
return false;
|
||||
}
|
||||
int totalStretch = 0;
|
||||
for (int i = 0; i < columnStretch.count(); i++) {
|
||||
if(columnStretch[i] < 0) {
|
||||
error = QString("wrong column stretch, columnt: %1 stretch: %2").arg(i).arg(columnStretch[i]);
|
||||
return false;
|
||||
}
|
||||
totalStretch += columnStretch[i];
|
||||
}
|
||||
if(totalStretch <= 0) {
|
||||
error = QString("wrong stretch");
|
||||
return false;
|
||||
}
|
||||
QVector<double> columnWidth;
|
||||
for (int i = 0; i < columnStretch.count(); i++) {
|
||||
columnWidth.append(tableWidth / totalStretch * columnStretch[i]);
|
||||
}
|
||||
int initValue;
|
||||
headers.isEmpty() ? initValue = 0 : initValue = -1;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
painter->save(); // before table print
|
||||
|
||||
// to know row height before printing
|
||||
// at first print to test image
|
||||
QPainter testSize;
|
||||
QImage* image = new QImage(10, 10, QImage::Format_RGB32);
|
||||
image->setDotsPerMeterX(printer->logicalDpiX() * 100 / 2.54); // 2.54 cm = 1 inch
|
||||
image->setDotsPerMeterY(printer->logicalDpiY() * 100 / 2.54);
|
||||
testSize.begin(image);
|
||||
|
||||
if(prepare) {
|
||||
painter->save();
|
||||
painter->translate(-painter->transform().dx(), -painter->transform().dy());
|
||||
prepare->preparePage(painter);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
painter->setPen(pen);
|
||||
painter->setFont(contentFont);
|
||||
testSize.setFont(contentFont);
|
||||
painter->translate(-painter->transform().dx() + leftBlank, 0);
|
||||
painter->save();
|
||||
painter->setFont(headersFont);
|
||||
testSize.setFont(headersFont);
|
||||
painter->drawLine(0, 0, tableWidth, 0); // first horizontal line
|
||||
|
||||
float max_y;
|
||||
|
||||
for(int j = initValue; j < model->rowCount(); j++) { // for each row
|
||||
if(j == 0) {
|
||||
painter->setFont(contentFont);
|
||||
testSize.setFont(contentFont);
|
||||
}
|
||||
|
||||
// --------------------------- row height counting ----------------------------
|
||||
|
||||
int maxHeight = 0; // max row Height
|
||||
for(int i = 0; i < columnCount; i++) { // for each column
|
||||
QString str;
|
||||
if(j >= 0) {
|
||||
// NOTE: j is row. i is column.
|
||||
str = model->data(model->index(j,i), Qt::DisplayRole).toString();
|
||||
} else {
|
||||
str = headers.at(i);
|
||||
}
|
||||
// qDebug() << "\t\t\t\t[Printer] " << " i=" << i << " j=" << j << " : " << str;
|
||||
|
||||
QRect rect(0, 0, columnWidth[i] - rightMargin - leftMargin, maxRowHeight);
|
||||
QRect realRect;
|
||||
int flags = Qt::AlignLeft | Qt::TextWordWrap;
|
||||
testSize.drawText( rect, flags, str, &realRect );
|
||||
if (realRect.height() > maxHeight && columnStretch[i] != 0)
|
||||
{
|
||||
realRect.height() > maxRowHeight ? maxHeight = maxRowHeight : maxHeight = realRect.height();
|
||||
}
|
||||
}
|
||||
|
||||
if(painter->transform().dy() + maxHeight + topMargin + bottomMargin > painter->viewport().height() -
|
||||
bottomHeight) { // begin from new page
|
||||
int y = painter->transform().dy();
|
||||
painter->restore();
|
||||
painter->save();
|
||||
for(int i = 0; i < columnCount; i++) { // vertical lines
|
||||
painter->drawLine(0, 0, 0,
|
||||
- painter->transform().dy() + y);
|
||||
painter->translate(columnWidth[i], 0);
|
||||
}
|
||||
painter->drawLine(0, 0, 0, - painter->transform().dy() + y); // last vertical line
|
||||
painter->restore();
|
||||
printer->newPage();
|
||||
if(prepare) {
|
||||
painter->save();
|
||||
painter->translate(-painter->transform().dx(), -painter->transform().dy());
|
||||
prepare->preparePage(painter);
|
||||
painter->restore();
|
||||
}
|
||||
painter->translate(-painter->transform().dx() + leftBlank, -painter->transform().dy() + headerHeight);
|
||||
painter->save();
|
||||
painter->drawLine(0, 0, tableWidth,
|
||||
0); // first horizontal line
|
||||
}
|
||||
|
||||
//------------------------------ content printing -------------------------------------------
|
||||
|
||||
painter->save();
|
||||
j >= 0 ? painter->setPen(QPen(contentColor)) : painter->setPen(QPen(headerColor));
|
||||
for(int i = 0; i < columnCount; i++) { // for each column
|
||||
QString str;
|
||||
if(j >= 0) {
|
||||
str = model->data(model->index(j,i), Qt::DisplayRole).toString();
|
||||
} else {
|
||||
str = headers.at(i);
|
||||
}
|
||||
QRect rec(leftMargin, topMargin, columnWidth[i] - rightMargin - leftMargin, maxHeight);
|
||||
painter->drawText(rec, Qt::AlignLeft | Qt::TextWordWrap, str);
|
||||
painter->translate(columnWidth[i], 0);
|
||||
}
|
||||
painter->restore();
|
||||
|
||||
painter->drawLine(0, maxHeight + topMargin + bottomMargin, tableWidth,
|
||||
maxHeight + topMargin + bottomMargin); // last horizontal line
|
||||
painter->translate(0, maxHeight + topMargin + bottomMargin);
|
||||
max_y = painter->transform().dy();
|
||||
}
|
||||
int y = painter->transform().dy();
|
||||
painter->restore();
|
||||
painter->save();
|
||||
for(int i = 0; i < columnCount; i++) { // vertical lines
|
||||
painter->drawLine(0, 0, 0,
|
||||
- painter->transform().dy() + y);
|
||||
painter->translate(columnWidth[i], 0);
|
||||
}
|
||||
painter->drawLine(0, 0, 0, - painter->transform().dy() + y); // last vertical line
|
||||
painter->restore();
|
||||
|
||||
testSize.end();
|
||||
delete image;
|
||||
|
||||
painter->restore(); // before table print
|
||||
|
||||
painter->translate(0, max_y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString TablePrinter::lastError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
void TablePrinter::setCellMargin(int left, int right, int top, int bottom) {
|
||||
topMargin = top;
|
||||
bottomMargin = bottom;
|
||||
leftMargin = left;
|
||||
rightMargin = right;
|
||||
}
|
||||
|
||||
void TablePrinter::setPageMargin(int left, int right, int top, int bottom) {
|
||||
headerHeight = top;
|
||||
bottomHeight = bottom;
|
||||
leftBlank = left;
|
||||
rightBlank = right;
|
||||
}
|
||||
|
||||
void TablePrinter::setPagePrepare(PagePrepare *prep) {
|
||||
prepare = prep;
|
||||
}
|
||||
|
||||
void TablePrinter::setPen(QPen p) {
|
||||
pen = p;
|
||||
}
|
||||
|
||||
void TablePrinter::setHeadersFont(QFont f) {
|
||||
headersFont = f;
|
||||
}
|
||||
|
||||
void TablePrinter::setContentFont(QFont f) {
|
||||
contentFont = f;
|
||||
}
|
||||
|
||||
void TablePrinter::setHeaderColor(QColor color) {
|
||||
headerColor = color;
|
||||
}
|
||||
|
||||
void TablePrinter::setContentColor(QColor color) {
|
||||
contentColor = color;
|
||||
}
|
||||
|
||||
void TablePrinter::setMaxRowHeight(int height) {
|
||||
maxRowHeight = height;
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (c) 2016, Anton Onishchenko
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without modification,
|
||||
** are permitted provided that the following conditions are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright notice, this
|
||||
** list of conditions and the following disclaimer.
|
||||
**
|
||||
** 2. Redistributions in binary form must reproduce the above copyright notice, this
|
||||
** list of conditions and the following disclaimer in the documentation and/or other
|
||||
** materials provided with the distribution.
|
||||
**
|
||||
** 3. Neither the name of the copyright holder nor the names of its contributors may
|
||||
** be used to endorse or promote products derived from this software without
|
||||
** specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef TABLEPRINTER_H
|
||||
#define TABLEPRINTER_H
|
||||
|
||||
#include <QPen>
|
||||
#include <QFont>
|
||||
|
||||
class QPrinter;
|
||||
class QPainter;
|
||||
class QAbstractItemModel;
|
||||
|
||||
/**
|
||||
* @brief The PagePrepare Abstract class - base class for
|
||||
* classes that will print something like headers, borders...
|
||||
* on each page with table
|
||||
*/
|
||||
class PagePrepare {
|
||||
public:
|
||||
virtual void preparePage(QPainter *painter) = 0;
|
||||
virtual ~PagePrepare() {}
|
||||
};
|
||||
|
||||
class TablePrinter
|
||||
{
|
||||
public:
|
||||
TablePrinter(QPainter *painter, QPrinter *printer);
|
||||
bool printTable(const QAbstractItemModel* model, const QVector<int> columnStretch,
|
||||
const QVector<QString> headers = QVector<QString>());
|
||||
QString lastError();
|
||||
void setCellMargin(int left = 10, int right = 5, int top = 5, int bottom = 5);
|
||||
void setPageMargin(int left = 50, int right = 20, int top = 20, int bottom = 20);
|
||||
void setPagePrepare(PagePrepare *prepare);
|
||||
void setPen(QPen pen); // for table borders
|
||||
void setHeadersFont(QFont font);
|
||||
void setContentFont(QFont font);
|
||||
void setHeaderColor(QColor color);
|
||||
void setContentColor(QColor color);
|
||||
void setMaxRowHeight(int height);
|
||||
private:
|
||||
QPainter *painter;
|
||||
QPrinter *printer;
|
||||
PagePrepare *prepare;
|
||||
QPen pen; // for table borders
|
||||
QFont headersFont;
|
||||
QFont contentFont;
|
||||
QColor headerColor;
|
||||
QColor contentColor;
|
||||
|
||||
// cell margins
|
||||
int topMargin;
|
||||
int bottomMargin;
|
||||
int leftMargin;
|
||||
int rightMargin;
|
||||
|
||||
// margins for table
|
||||
int headerHeight;
|
||||
int bottomHeight;
|
||||
int leftBlank;
|
||||
int rightBlank;
|
||||
|
||||
int maxRowHeight;
|
||||
|
||||
QString error;
|
||||
};
|
||||
|
||||
#endif // TABLEPRINTER_H
|
@ -1,378 +0,0 @@
|
||||
// XlsxTab.cpp
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QSharedPointer>
|
||||
#include <QLayout>
|
||||
#include <QVBoxLayout>
|
||||
#include <QVariant>
|
||||
#include <QFont>
|
||||
#include <QBrush>
|
||||
#include <QDebug>
|
||||
#include <QTextCharFormat>
|
||||
|
||||
#include "XlsxTab.h"
|
||||
#include "xlsxcell.h"
|
||||
#include "xlsxformat.h"
|
||||
|
||||
XlsxTab::XlsxTab(QWidget* parent,
|
||||
QXlsx::Document* ptrDoc,
|
||||
QXlsx::AbstractSheet* ptrSheet,
|
||||
int SheetIndex)
|
||||
: QWidget(parent)
|
||||
{
|
||||
table = NULL;
|
||||
sheet = NULL;
|
||||
sheetIndex = -1;
|
||||
|
||||
if ( NULL == ptrSheet )
|
||||
return;
|
||||
|
||||
table = new XlsxTableWidget( this );
|
||||
Q_ASSERT( NULL != table );
|
||||
|
||||
// set layout
|
||||
vLayout = new QVBoxLayout;
|
||||
vLayout->addWidget(table);
|
||||
this->setLayout(vLayout);
|
||||
|
||||
document = ptrDoc; // set document
|
||||
sheet = ptrSheet; // set sheet data
|
||||
sheetIndex = SheetIndex; // set shett index
|
||||
if ( ! setSheet() )
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
XlsxTab::~XlsxTab()
|
||||
{
|
||||
|
||||
if ( NULL != vLayout )
|
||||
{
|
||||
vLayout->deleteLater();
|
||||
vLayout = NULL;
|
||||
}
|
||||
|
||||
if ( NULL != table )
|
||||
{
|
||||
table->clear();
|
||||
table->deleteLater();
|
||||
table = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool XlsxTab::setSheet()
|
||||
{
|
||||
if ( NULL == sheet )
|
||||
return false;
|
||||
|
||||
if ( NULL == table )
|
||||
return false;
|
||||
|
||||
// set active sheet
|
||||
sheet->workbook()->setActiveSheet( sheetIndex );
|
||||
|
||||
// dev57
|
||||
if ( sheet->workbook()->activeSheet()->sheetType() != AbstractSheet::ST_WorkSheet )
|
||||
return false;
|
||||
|
||||
Worksheet* wsheet = (Worksheet*) sheet->workbook()->activeSheet();
|
||||
if ( NULL == wsheet )
|
||||
return false;
|
||||
|
||||
// get full cells of sheet
|
||||
int maxRow = -1;
|
||||
int maxCol = -1;
|
||||
QVector<CellLocation> clList = wsheet->getFullCells( &maxRow, &maxCol );
|
||||
|
||||
// set max count of row,col
|
||||
// NOTE: This part should be modified later.
|
||||
// The maximum value of the sheet should be set to an appropriate value.
|
||||
table->setRowCount( maxRow );
|
||||
table->setColumnCount( maxCol );
|
||||
|
||||
for ( int ic = 0; ic < clList.size(); ++ic )
|
||||
{
|
||||
// cell location
|
||||
CellLocation cl = clList.at(ic);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// NOTE: First cell index of tableWidget is 0(zero).
|
||||
/// But, first cell of Qxlsx document is 1(one).
|
||||
|
||||
int row = cl.row - 1;
|
||||
int col = cl.col - 1;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// cell pointer
|
||||
|
||||
QSharedPointer<Cell> ptrCell = cl.cell;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// create new item of table widget
|
||||
|
||||
QTableWidgetItem* newItem = new QTableWidgetItem();
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
/// value of cell
|
||||
|
||||
QVariant var = cl.cell.data()->value(); // cell value
|
||||
QString str;
|
||||
Cell::CellType cType = cl.cell->cellType();
|
||||
|
||||
// qDebug() << "(r,c) = " << cl.row << cl.col << var.toString() ;
|
||||
|
||||
str = var.toString();
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// set text
|
||||
|
||||
newItem->setText( str );
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// set item
|
||||
|
||||
table->setItem( row, col, newItem );
|
||||
|
||||
// TODO: set label of table widget ('A', 'B', 'C', ...)
|
||||
// QTableWidgetItem *QTableWidget::horizontalHeaderItem(int column) const
|
||||
// QTableWidgetItem *QTableWidget::verticalHeaderItem(int row) const
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// row height and column width
|
||||
|
||||
double dRowHeight = wsheet->rowHeight( cl.row );
|
||||
double dColWidth = wsheet->columnWidth( cl.col );
|
||||
|
||||
// qDebug() <<" ROW HEIGHT: " << dRowHeight << " COLUMN WIDTH: " << dColWidth;
|
||||
|
||||
double wWidth = cellWidthToWidgetWidth( dColWidth );
|
||||
double wHeight = cellHeightToWidgetHeight( dRowHeight );
|
||||
|
||||
table->setRowHeight( row, wHeight );
|
||||
table->setColumnWidth( col, wWidth );
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// font
|
||||
|
||||
newItem->setFont( ptrCell->format().font() );
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// font color
|
||||
|
||||
if ( ptrCell->format().fontColor().isValid() )
|
||||
{
|
||||
newItem->setTextColor( ptrCell->format().fontColor() );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// background color
|
||||
|
||||
{
|
||||
QColor clrForeGround = ptrCell->format().patternForegroundColor();
|
||||
if ( clrForeGround.isValid() )
|
||||
{
|
||||
// qDebug() << "[debug] ForeGround : " << clrForeGround;
|
||||
}
|
||||
|
||||
QColor clrBackGround = ptrCell->format().patternBackgroundColor();
|
||||
if ( clrBackGround.isValid() )
|
||||
{
|
||||
// TODO: You must use various patterns.
|
||||
newItem->setBackground( Qt::SolidPattern );
|
||||
newItem->setBackgroundColor( clrBackGround );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// pattern
|
||||
|
||||
Format::FillPattern fp = ptrCell->format().fillPattern();
|
||||
Qt::BrushStyle qbs = Qt::NoBrush;
|
||||
switch(fp)
|
||||
{
|
||||
case Format::PatternNone : qbs = Qt::NoBrush; break;
|
||||
case Format::PatternSolid : qbs = Qt::SolidPattern; break;
|
||||
case Format::PatternMediumGray :
|
||||
case Format::PatternDarkGray :
|
||||
case Format::PatternLightGray :
|
||||
case Format::PatternDarkHorizontal :
|
||||
case Format::PatternDarkVertical :
|
||||
case Format::PatternDarkDown :
|
||||
case Format::PatternDarkUp :
|
||||
case Format::PatternDarkGrid :
|
||||
case Format::PatternDarkTrellis :
|
||||
case Format::PatternLightHorizontal :
|
||||
case Format::PatternLightVertical :
|
||||
case Format::PatternLightDown :
|
||||
case Format::PatternLightUp :
|
||||
case Format::PatternLightTrellis :
|
||||
case Format::PatternGray125 :
|
||||
case Format::PatternGray0625 :
|
||||
case Format::PatternLightGrid :
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
QBrush qbr( ptrCell->format().patternForegroundColor(), qbs );
|
||||
newItem->setBackground( qbr );
|
||||
newItem->setBackgroundColor( ptrCell->format().patternBackgroundColor() );
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// alignment
|
||||
|
||||
int alignment = 0;
|
||||
Format::HorizontalAlignment ha = ptrCell->format().horizontalAlignment();
|
||||
switch(ha)
|
||||
{
|
||||
case Format::AlignHCenter :
|
||||
case Format::AlignHFill :
|
||||
case Format::AlignHMerge :
|
||||
case Format::AlignHDistributed :
|
||||
alignment = alignment | Qt::AlignHCenter;
|
||||
break;
|
||||
|
||||
case Format::AlignRight :
|
||||
alignment = alignment | Qt::AlignRight;
|
||||
break;
|
||||
|
||||
case Format::AlignHJustify :
|
||||
alignment = alignment | Qt::AlignJustify;
|
||||
break;
|
||||
|
||||
case Format::AlignLeft :
|
||||
case Format::AlignHGeneral :
|
||||
default:
|
||||
alignment = alignment | Qt::AlignLeft;
|
||||
break;
|
||||
}
|
||||
|
||||
Format::VerticalAlignment va = ptrCell->format().verticalAlignment();
|
||||
switch(va)
|
||||
{
|
||||
case Format::AlignTop :
|
||||
alignment = alignment | Qt::AlignTop;
|
||||
break;
|
||||
|
||||
case Format::AlignVCenter :
|
||||
alignment = alignment | Qt::AlignVCenter;
|
||||
break;
|
||||
|
||||
case Format::AlignBottom :
|
||||
alignment = alignment | Qt::AlignBottom;
|
||||
break;
|
||||
|
||||
case Format::AlignVJustify :
|
||||
case Format::AlignVDistributed :
|
||||
default:
|
||||
// alignment = alignment | (int)(Qt::AlignBaseline);
|
||||
alignment = alignment | QTextCharFormat::AlignBaseline;
|
||||
break;
|
||||
}
|
||||
|
||||
newItem->setTextAlignment( alignment );
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
|
||||
// dev56
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/// merged cell
|
||||
|
||||
if ( sheet->workbook()->activeSheet()->sheetType() == AbstractSheet::ST_WorkSheet )
|
||||
{
|
||||
QList<CellRange> mergeCellRangeList = wsheet->mergedCells();
|
||||
for ( int mc = 0; mc < mergeCellRangeList.size(); ++mc )
|
||||
{
|
||||
CellRange mergedCellRange = mergeCellRangeList.at(mc);
|
||||
|
||||
CellReference crTopLeft = mergedCellRange.topLeft();
|
||||
int tlCol = crTopLeft.column();
|
||||
int tlRow = crTopLeft.row();
|
||||
|
||||
CellReference crBottomRight = mergedCellRange.bottomRight();
|
||||
int brCol = crBottomRight.column();
|
||||
int brRow = crBottomRight.row();
|
||||
|
||||
// row : tlRow ~ brRow
|
||||
// col : tlCol ~ brCol
|
||||
|
||||
/// NOTE: First cell index of tableWidget is 0(zero).
|
||||
/// But, first cell of Qxlsx document is 1(one).
|
||||
|
||||
int rowSpan = brRow - tlRow + 1;
|
||||
int colSpan = brCol - tlCol + 1;
|
||||
|
||||
table->setSpan( (tlRow - 1), (tlCol - 1), rowSpan, colSpan );
|
||||
} // for ( int mc = 0; mc < mergeCellRangeList.size(); ++mc ) ...
|
||||
} // if ( sheet->workbook()->activeSheet()->sheetType() == AbstractSheet::ST_WorkSheet ) ...
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string XlsxTab::convertFromNumberToExcelColumn(int n)
|
||||
{
|
||||
// main code from https://www.geeksforgeeks.org/find-excel-column-name-given-number/
|
||||
// Function to print Excel column name for a given column number
|
||||
|
||||
std::string stdString;
|
||||
|
||||
char str[1000]; // To store result (Excel column name)
|
||||
int i = 0; // To store current index in str which is result
|
||||
|
||||
while ( n > 0 )
|
||||
{
|
||||
// Find remainder
|
||||
int rem = n % 26;
|
||||
|
||||
// If remainder is 0, then a 'Z' must be there in output
|
||||
if ( rem == 0 )
|
||||
{
|
||||
str[i++] = 'Z';
|
||||
n = (n/26) - 1;
|
||||
}
|
||||
else // If remainder is non-zero
|
||||
{
|
||||
str[i++] = (rem-1) + 'A';
|
||||
n = n / 26;
|
||||
}
|
||||
}
|
||||
str[i] = '\0';
|
||||
|
||||
// Reverse the string and print result
|
||||
std::reverse( str, str + strlen(str) );
|
||||
|
||||
stdString = str;
|
||||
return stdString;
|
||||
}
|
||||
|
||||
// 72 points (DPI) = 1 inch = 2.54 cm = 96 pixels
|
||||
// 1 PT(point) = 1.333 PX(pixel) (point is a absolute unit.)
|
||||
// 1 PX(pixel) = 0.75 PT(point) (pixel is a relative unit.) (In Windows. Mac is diffrent.)
|
||||
|
||||
double XlsxTab::cellWidthToWidgetWidth(double width)
|
||||
{
|
||||
// unit of width is a character. default value is 8.43.
|
||||
// 8.43 characters = 64 pixel = 48 point (in Windows)
|
||||
|
||||
double ret = width * (double(64) / double(8.43));
|
||||
return ret;
|
||||
}
|
||||
|
||||
double XlsxTab::cellHeightToWidgetHeight(double height)
|
||||
{
|
||||
// default value is 16.5 point
|
||||
// 3 point = 4 pixel
|
||||
|
||||
double ret = height * (double(3) / double(4));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,53 +0,0 @@
|
||||
// XlsxTab.h
|
||||
|
||||
#ifndef XLSXTAB_H
|
||||
#define XLSXTAB_H
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
#include <QTableWidget>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "xlsx.h"
|
||||
#include "XlsxTableWidget.h"
|
||||
|
||||
/**
|
||||
* @brief xlsx sub-tab widget
|
||||
*/
|
||||
class XlsxTab : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit XlsxTab(QWidget* parent = NULL,
|
||||
QXlsx::Document* ptrDoc = NULL,
|
||||
QXlsx::AbstractSheet* ptrSheet = NULL,
|
||||
int SheetIndex = -1);
|
||||
virtual ~XlsxTab();
|
||||
|
||||
public slots:
|
||||
signals:
|
||||
|
||||
protected:
|
||||
QXlsx::Document* document;
|
||||
QXlsx::AbstractSheet* sheet;
|
||||
int sheetIndex;
|
||||
|
||||
protected:
|
||||
XlsxTableWidget* table;
|
||||
QVBoxLayout *vLayout;
|
||||
|
||||
protected:
|
||||
bool setSheet();
|
||||
std::string convertFromNumberToExcelColumn(int n);
|
||||
double cellWidthToWidgetWidth(double width);
|
||||
double cellHeightToWidgetHeight(double height);
|
||||
|
||||
};
|
||||
|
||||
#endif // XLSXTAB_H
|
@ -1,66 +0,0 @@
|
||||
// XlsxTableWidget.cpp
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTime>
|
||||
|
||||
#include <QList>
|
||||
#include <QTableWidgetSelectionRange>
|
||||
|
||||
#include "XlsxTableWidget.h"
|
||||
|
||||
XlsxTableWidget::XlsxTableWidget(QWidget* parent)
|
||||
: QTableWidget(parent)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
XlsxTableWidget::~XlsxTableWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void XlsxTableWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QTableWidget::mousePressEvent(event);
|
||||
|
||||
if ( event->button() == Qt::RightButton )
|
||||
{
|
||||
// qDebug() << "right button is pressed";
|
||||
|
||||
QList<QTableWidgetItem *> items = this->selectedItems();
|
||||
|
||||
// selected range
|
||||
|
||||
QList<QTableWidgetSelectionRange> ranges = this->selectedRanges();
|
||||
for (int ic = 0 ; ic < ranges.size(); ic++ )
|
||||
{
|
||||
QTableWidgetSelectionRange range = ranges.at(ic);
|
||||
|
||||
int rowCount = range.rowCount();
|
||||
|
||||
int topRow = range.topRow();
|
||||
int bottomRow = range.bottomRow();
|
||||
|
||||
int colCount = range.columnCount();
|
||||
|
||||
int leftCol = range.leftColumn();
|
||||
int rightCol = range.rightColumn();
|
||||
|
||||
// qDebug()
|
||||
// << QTime::currentTime();
|
||||
|
||||
// qDebug()
|
||||
// << "row: " << rowCount << " : "
|
||||
// << " top:" << topRow
|
||||
// << ", bottom:" << bottomRow ;
|
||||
|
||||
// qDebug()
|
||||
// << "col: " << colCount << " : "
|
||||
// << " left:" << leftCol
|
||||
// << " right:" << rightCol ;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
// XlsxTableWidget.h
|
||||
|
||||
#ifndef XLSX_TABLE_WIDGET_H
|
||||
#define XLSX_TABLE_WIDGET_H
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QList>
|
||||
#include <QVector>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTableWidget>
|
||||
#include <QMouseEvent>
|
||||
#include <QTableWidgetItem>
|
||||
#include <QTableWidgetSelectionRange>
|
||||
|
||||
class XlsxTableWidget : public QTableWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit XlsxTableWidget(QWidget* parent = NULL);
|
||||
virtual ~XlsxTableWidget();
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent *event);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
Binary file not shown.
Before Width: | Height: | Size: 66 KiB |
@ -1,17 +0,0 @@
|
||||
// main.cpp
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
|
||||
MainWindow w;
|
||||
w.show();
|
||||
|
||||
int ret = a.exec();
|
||||
return ret;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>excel.ico</file>
|
||||
</qresource>
|
||||
</RCC>
|
Binary file not shown.
Binary file not shown.
@ -1,14 +0,0 @@
|
||||
#ifndef XLSX_H
|
||||
#define XLSX_H
|
||||
|
||||
#include "xlsxdocument.h"
|
||||
#include "xlsxchartsheet.h"
|
||||
#include "xlsxcellrange.h"
|
||||
#include "xlsxchart.h"
|
||||
#include "xlsxrichstring.h"
|
||||
#include "xlsxworkbook.h"
|
||||
#include "xlsxabstractsheet.h"
|
||||
|
||||
using namespace QXlsx;
|
||||
|
||||
#endif // XLSX_H
|
16
Example.md
16
Example.md
@ -83,14 +83,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
![](markdown.data/android.jpg)
|
||||
|
||||
## [Copycat : Windows Widget Example](https://github.com/QtExcel/QXlsx/tree/master/Copycat)
|
||||
- Load xlsx file and display on Qt widgets.
|
||||
- Print xlsx to paper. (based on Qt-Table-Printer)
|
||||
- TODO: save xlsx.
|
||||
|
||||
![](markdown.data/copycat.png)
|
||||
![](markdown.data/copycat2.jpg)
|
||||
|
||||
## [WebServer : Web Server Example](https://github.com/QtExcel/QXlsx/tree/master/WebServer)
|
||||
- Load xlsx file and display on Web.
|
||||
- Connect to `http://127.0.0.1:3001`
|
||||
@ -104,3 +96,11 @@ int main(int argc, char *argv[])
|
||||
- C++ 11 is required. Old compilers is not supported. (based on libfort)
|
||||
|
||||
![](markdown.data/show-console.jpg)
|
||||
|
||||
## Copycat : Windows Widget Example
|
||||
- Load xlsx file and display on Qt widgets.
|
||||
- Print xlsx to paper. (based on Qt-Table-Printer)
|
||||
- Moved to personal repository for advanced app.
|
||||
|
||||
![](markdown.data/copycat.png)
|
||||
![](markdown.data/copycat2.jpg)
|
||||
|
@ -14,7 +14,6 @@
|
||||
- HelloWorld : 헬로우 월드 예제 (가장 기본적인 구조)
|
||||
- TestExcel : QtXlsx 예제에 기반한 기본 예제
|
||||
- HelloAndroid : 안드로이드에서 xlsx 파일 열기
|
||||
- Copycat : xlsx 파일을 읽어 위젯으로 표시. xlsx 파일 인쇄.
|
||||
- WebServer : xlsx 파일을 읽어 웹으로 표시
|
||||
- ShowConsole : xlsx 파일을 읽어 콘솔에 표시
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
- HelloWorld : Hello world example (the most basic structure)
|
||||
- TestExcel : basic samples based on QtXlsx samples
|
||||
- HelloAndroid : read xlsx on Android
|
||||
- Copycat : load xlsx file and display on widget. print xlsx file.
|
||||
- WebServer : load xlsx and display to web
|
||||
- ShowConsole : load xlsx and display to console
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user