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.
nmWTAI-Platform/Include/iBase/iPlugin/ExcelEngineAx.h

211 lines
7.6 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#pragma once
#include "ExcelEngine.h"
#ifdef Q_OS_WIN
typedef unsigned int UINT;
class QAxObject;
// 借用 enum RectBoundPos 进行方向选择(四个)
#define XlsDirection RectBoundPos
#endif
// Excel+ActiveX,与Office关联的实现
class I_PLUGIN_EXPORT ExcelEngineAx : public ExcelEngine
{
Q_OBJECT
public:
ExcelEngineAx();
~ExcelEngineAx();
public:
/// @brief 获取excel的数据信息
/// @note bAutoLoad是否自动加载首页信息
virtual bool loadExcel(const QString& sFilePath, bool bAutoLoad = true);
/// @brief 新建一个工作簿,方便后续另存
virtual bool addWorkBook(QString sDefaultSheet = "");
/// @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开始,默认为-1,nRowTo=最大行数
/// @param nColTo Excel结束列,从1开始,默认为-1,nColTo=最大列数
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保存动作
virtual bool saveExcel(bool bAdjustLayout = true);
virtual bool saveAsExcel(QString sFile, bool bAdjustLayout = true);
#ifdef Q_OS_WIN
public:
/// @brief 判断Office[Excel]是否安装
/// @param bConsiderWPS 是否考虑WPS,如果是,顺序是先判断Office,再判断WPS
/// @param sProgID 返回Excel.Application,ET.Application之类
static bool isOfficeInstalled(bool bConsiderWPS, QString& sProgID);
// 只是为了少一次检测而已
virtual void setProgID(QString s) { m_sProgID = s; }
protected:
/// @brief 开启Excel进程,这是通常最慢的一步
virtual bool runExcel();
/// @brief 激活sheet,不存在则创建,方便后续另存
virtual bool activateWorkSheet(QString sSheetName, \
bool bFirstIfNotExists = true, \
bool bCreateIfNotExists = 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 bFinalMode为false时:暂时释放内存,非最终
virtual bool release(bool bFinalMode = false);
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 在设置完毕数据后,对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);
protected:
/// @brief 获取行/列对象
/// @note 内部包括了两种获取方法(作用一样)
virtual QAxObject* getColumnAt(int c);
virtual QAxObject* getRowAt(int r);
/// @brief 获取Cell对象
virtual QAxObject* getCellAt(int r, int c);
protected:
// 具体的表格相关
QAxObject* m_pExcel;
QAxObject* m_pWorkBooks;
QAxObject* m_pWorkBook;
QAxObject* m_pWorkSheets;
QAxObject* m_pWorkSheet;
QAxObject* m_pUsedRange;
// 应用ID
QString m_sProgID;
#endif
};