You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWATI/Include/iBase/iPlugin/ExcelEngine.h

223 lines
8.3 KiB
C

#pragma once
#include "Defines.h"
#include "iPlugin_global.h"
typedef unsigned int UINT;
class QAxObject;
// 借用 enum RectPos 进行方向选择(四个)
#define XlsDirection RectPos
// 基础Excel引擎
class I_PLUGIN_EXPORT ExcelEngine : public QObject
{
Q_OBJECT
public:
ExcelEngine();
~ExcelEngine();
/// @brief 开启Excel进程这是通常最慢的一步
bool runExcel();
/// @brief 获取excel的数据信息
/// @note bAutoLoad是否自动加载首页信息
virtual bool loadExcel(const QString& sFilePath, bool bAutoLoad = true);
/// @brief 新建一个工作簿,方便后续另存
virtual bool addWorkBook(QString sDefaultSheet = "");
/// @brief 激活sheet不存在则创建方便后续另存
virtual bool activateWorkSheet(QString sSheetName, \
bool bFirstIfNotExists = true, \
bool bCreateIfNotExists = false);
/// @brief 获取excel的Sheet页
virtual bool getSheetNames(QStringList &listNames);
/// @brief 设定操作的Sheet
/// @param nSheetIndex Sheet索引从1开始
/// @param sSheetName Sheet名称
/// @note 以nSheetIndex为主如果考虑sSheetName此时需要把nSheetIndex=-1
/// setDefaultSheet(-1, “sheet1”
virtual bool setDefaultSheet(int nSheetIndex = 1, QString sSheetName = "");
/// @brief 获取excel的数据(组成的矩形网格)Excel的索引均是从1开始
/// @param vvecData 获取到的数据
/// @param nRowFrom Excel开始行从1开始
/// @param nColFrom Excel开始列从1开始
/// @param nRowTo Excel结束行从1开始默认为-1nRowTo=最大行数
/// @param nColTo Excel结束列从1开始默认为-1nColTo=最大列数
virtual bool getCellValues(VVecVariant& vvecData, \
int nRowFrom = 1, int nColFrom = 1, \
int nRowTo = -1, int nColTo = -1);
/// @brief 设置excel的数据(组成的矩形网格)Excel的索引均是从1开始
/// @param vvecData 需要填充设置的数据
/// @param nRowFrom Excel开始行从1开始
/// @param nColFrom Excel开始列从1开始
/// @param bFormat 设置数据之后,是否重置表格样式
virtual bool setCellValues(const VVecVariant& vvecData, \
int nRowFrom = 1, int nColFrom = 1, \
bool bFormat = false);
/// @brief 设置excel某列的数据Excel的索引均是从1开始
/// @param vecData 需要填充设置的数据
/// @param nCol Excel列从1开始
/// @param nRowFrom Excel开始行从1开始如果为1则第一个为标题
virtual bool setColValues(const VecVariant& vecData, \
int nCol, int nRowFrom = 1);
/// @brief 设置excel某列的数据Excel的索引均是从1开始
/// @param vecData 需要填充设置的数据
/// @param nCol Excel列从1开始
/// @param nRowFrom Excel开始行从1开始如果为1则第一个为标题
/// @param sColTitle 列标题
virtual bool setColValues(const VecDouble& vecData, \
int nCol, int nRowFrom = 2, \
QString sColTitle = "");
/// @brief 执行最后的excel保存动作
virtual bool saveExcel(bool bAdjustLayout = true);
virtual bool saveAsExcel(QString sFile, bool bAdjustLayout = true);
/// @brief bFinalMode为false时暂时释放内存,非最终
virtual bool release(bool bFinalMode = false);
// 数据格式转换为方便llist内的QVariant依然为QList
bool llistToVVec(const QList<QVariant>& llist, VVecVariant& vvec);
bool vvecToLlist(QList<QVariant>& llist, const VVecVariant& vvec);
protected:
/// @brief 新建或打开WorkBook
virtual bool makesureWorkBook(QString sFile = "");
/// @brief 拼装格式,如 A1:E20然后得到Range
virtual QAxObject* makesureRange(int nRowFrom, int nColFrom, \
int nRowTo, int nColTo);
/// @brief 读取所有sheet名称
virtual bool makesureSheetNames();
/// @brief 获取excel的Sheet
virtual bool loadSheetStruct(int nIndex);
/// @brief 设置range
virtual bool resetSheetRange();
/// @brief 设置excel的数据(组成的矩形网格)Excel的索引均是从1开始
virtual bool setCellValues(const QList<QVariant>& llistData, \
int nRowFrom, int nColFrom, \
int nRowTo, int nColTo, \
bool bFormat = false);
/// @brief 规范化网格范围各数据索引从1开始
virtual bool normalizeRange(int& nRowFrom, int& nColFrom, int& nRowTo, int& nColTo);
/// @brief 在设置完毕数据后对Range进行格式调整
virtual bool formatRange(QAxObject*& pRange);
// 算法来自微软官方网站 (http://support.microsoft.com/kb/833402)
// 列号转换
QString colIndexToLetter(int nColIndex);
private:
void reset(bool fFinalMode);
public:
/// @brief 利用Cell进行列宽设置单位像素
/// @note 1.输入d的范围为像素pix输出返回的也是像素pix
/// 2.对于Excel的列宽比较特殊实际以字符长为主
/// 需要进行字符宽度与像素宽度的转换,目前只是拼凑,有待精确计算
/// 简单测试char * 8 + 5 = pix
virtual void setCellWidth(QAxObject* pCell, double d);
virtual double getCellWidth(QAxObject* pCell);
/// @brief 利用Cell进行高设置单位
/// @note Excel行高设置、插入图片Size全部以磅为单位
virtual void setCellHeight(QAxObject* pCell, double d);
virtual double getCellHeight(QAxObject* pCell);
/// @brief 根据索引进行列宽设置,单位:像素
/// @note 1.输入d的范围为像素pix输出返回的也是像素pix
/// 2.对于Excel的列宽比较特殊实际以字符长为主
/// 需要进行字符宽度与像素宽度的转换,目前只是拼凑,有待精确计算
/// 简单测试char * 8 + 5 = pix
virtual void setColWidth(int c, double d);
virtual double getColWidth(int c);
/// @brief 根据索引进行行高设置,单位:磅
/// @note Excel行高设置、插入图片Size全部以磅为单位
virtual void setRowHeight(int r, double d);
virtual double getRowHeight(int r);
/// @brief 设置备注慎用TODO未测试
virtual void setCellComment(int r, int c, QString sComment);
virtual void setCellComment(QAxObject* pCell, QString sComment);
/// @brief 合并并且边界设置颜色m_oBorderClr
bool mergeRanges(int r1, int r2, int c1, int c2, bool bColorBorder = true);
/// @brief 批量插入行或列根据o来定
bool insertRowOrCols(int nFrom, int nCount, XlsDirection o);
public:
void setTextClr(QColor clr);
void setBackgndClr(QColor clr);
void setBorderClr(QColor clr);
void setAlignFlag(int flag);
void setWrapText(bool b);
protected:
/// @brief 像素和磅的转换
double getPoundFromPix(double d);
double getPixFromPound(double d);
/// @brief 获取行/列对象
/// @note 内部包括了两种获取方法(作用一样)
virtual QAxObject* getColumnAt(int c);
virtual QAxObject* getRowAt(int r);
/// @brief 获取Cell对象
virtual QAxObject* getCellAt(int r, int c);
protected:
// 具体的表格相关
QString m_sFileName;
QAxObject* m_pExcel;
QAxObject* m_pWorkBooks;
QAxObject* m_pWorkBook;
QAxObject* m_pWorkSheets;
QAxObject* m_pWorkSheet;
QAxObject* m_pUsedRange;
// 表格行列
int m_nRowStart;
int m_nColStart;
int m_nRowCount;
int m_nColCount;
int m_nLastSheetIndex;
QStringList m_listSheets;
// 写入时的格式Format
QColor m_oTextClr; //文本颜色
QColor m_oBackgndClr; //背景颜色
QColor m_oBorderClr; //边框颜色
int m_nAlignFlag; //对齐方式
bool m_bWrapText; //自动换行
double m_dRatioPP; //像素/磅 的比值通常1.3333
//目前只是用于导出表格图片时设定高度/宽度时使用
};