#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开始,默认为-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某列的数据,注: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& llist, VVecVariant& vvec); bool vvecToLlist(QList& 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& 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 //目前只是用于导出表格图片时设定高度/宽度时使用 };