Qt中快速读写Excel方法封装

#include "RwExcel.h"
/*快速读写的机制是实现获取有效区域只调用一次dynamicCall("Value");或setProperty("Value", var);即可,

*而不是在循环里多次被用

*/

RwExcel::RwExcel()
{
}

RwExcel::~RwExcel()
{
}
void RwExcel::castVariant2ListListVariant(const QVariant &var, QList<QList<QVariant> > &res)
{
QVariantList varRows = var.toList();
if (varRows.isEmpty())
{
return;
}
const int rowCount = varRows.size();
QVariantList rowData;
for (int i = 0; i < rowCount; ++i)
{
rowData = varRows[i].toList();
if (rowData[0].toString().isEmpty())
break;
res.push_back(rowData);
}
}

QString path_; // 文件路径
QVariant RwExcel::readExcel(QString path)
{
path_ = path;
QAxWidget excel("Excel.Application");
if (excel.isNull())
return QVariant();
excel.setProperty("Visible", false);
QAxObject *workbooks = excel.querySubObject("WorkBooks");
if (!workbooks)
return QVariant();
QAxObject *workbook = workbooks->querySubObject("Open(QString, QVariant)", QDir::toNativeSeparators(path), QVariant(0));
//成本地路径 QDir::toNativeSeparators(path)(分隔符)
if (!workbook)
return QVariant();
QAxObject *sheets = excel.querySubObject("ActiveWorkBook");
if (!sheets)
return QVariant();
QAxObject *sheet = sheets->querySubObject("Sheets(int )", 1);
if (!sheet)
return QVariant();
QVariant var;
if (sheet != NULL && !sheet->isNull())
{
QAxObject *usedRange = sheet->querySubObject("UsedRange");
if (NULL == usedRange || usedRange->isNull())
return QVariant();

var = usedRange->dynamicCall("Value");
delete usedRange;
}
excel.dynamicCall("Quit(void)");
return var;
}

QString RwExcel::to26AlphabetString(int data)
{
QChar ch = data + 0x40; //A对应0x41
return QString(ch);
}

void RwExcel::convertToColName(int data, QString &res)
{
Q_ASSERT(data > 0 && data<65535);
int tempData = data / 26;
if (tempData > 0)
{
int mode = data % 26;
convertToColName(mode, res);
convertToColName(tempData, res);
}
else
{
res = (to26AlphabetString(data) + res);
}
}

void RwExcel::castListListVariant2Variant(const QList<QList<QVariant>> &res, QVariant &var)
{
QVariantList vars;
const int rows = res.size();
for (int i = 0; i < rows; ++i)
{
vars.append(QVariant(res[i]));
}
var = QVariant(vars);
}

bool RwExcel::setCell(QList<QList<QVariant>> &v2List)
{
if (v2List.size() <= 0)
return false;
if (excl->isNull())
return false;
int row = v2List.size();
int col = v2List.at(0).size();
QString rangStr;
convertToColName(col, rangStr);
rangStr += QString::number(row);
rangStr = "A1:" + rangStr;
QAxObject *range = excl->querySubObject("Range(const QString&)", rangStr);
if (NULL == range || range->isNull())
return false;
QVariant var;
castListListVariant2Variant(v2List, var);

range->setProperty("VerticalAlignment", -4108); // 上对齐(xlTop)-4160 居中(xlCenter)-4108 下对齐(xlBottom)-4107
range->setProperty("HorizontalAlignment", -4131); // 左对齐(xlLeft)-4131 居中(xlCenter)-4108 右对齐(xlRight)-4152
range->setProperty("NumberFormatLocal", "@"); // 设置为文本
range->setProperty("Value", var);
delete range;

return true;
}

bool RwExcel::writeExcel(QList<QList<QVariant>> &cells,QString path)
{
if (path.isNull() || cells.count() == 0)
return false;
excl = new QAxWidget("Excel.Application");
if (excl->isNull() || excl == NULL)
return false;

excl->setProperty("Visible", false);
excl->setProperty("DisplayAlerts", false); //不显示任何警告信息。
QAxObject *workbooks = excl->querySubObject("WorkBooks");
if (!workbooks)
return false;
QAxObject *workbook = workbooks->querySubObject("Add");
if (!workbook)
return false;
QAxObject *worksheets = workbook->querySubObject("WorkSheets");
if (!worksheets)
return false;
QAxObject *worksheet = workbook->querySubObject("Worksheets(int)", 1);
if (!worksheet)
return false;
if (!setCell(cells))
return false;
worksheet->dynamicCall("SaveAs(QVariant)", QDir::toNativeSeparators(path));
workbook->dynamicCall("Close(Boolean)", false);
excl->dynamicCall("Quit(void)");

delete excl;
excl = NULL;

return true;
}

QString RwExcel::savePath()
{
return path_;
}

bool RwExcel::import(QList<ExcelBill> &list, QString &filePath, QWidget *parent)
{
path_ = filePath;
if (path_.contains("[") || path_.contains("]") || path_.contains("<") || path_.contains(">") || path_.contains("="))
return setError(ZH("文件的路径或文件名不符合!"));

QAxObject excel("Excel.Application");
if (excel.isNull())
return false;

ScopeTailed excelQuit([&excel](){excel.dynamicCall("Quit(void)"); });

excel.setProperty("Visible", false);
excel.setProperty("DisplayAlerts", false);

QAxObject *workBooks = excel.querySubObject("WorkBooks");
if (!workBooks)
return setError(ZH("Excel文件已打开"));

QAxObject *workBook = workBooks->querySubObject("Open(QString)", QDir::toNativeSeparators(filePath));
if (!workBook)
return setError(ZH("没有激活的工作簿"));

ScopeTailed closeBook([workBook](){ if (workBook) workBook->dynamicCall("Close(Boolean)", false); });

QAxObject *workSheets = workBook->querySubObject("Sheets");
if (!workSheets || workSheets->property("Count").toInt() == 0)
return setError(ZH("%1中没有工作表").arg(filePath));

QAxObject *workSheet = workBook->querySubObject("Sheets(int)", 1);
if (!workSheet)
return setError(ZH("无法获取工作表"));

QAxObject *usedRange = workSheet->querySubObject("UsedRange");
if (!usedRange)
return setError(ZH("无法获取有效单元格"));

usedRange->setProperty("VerticalAlignment", -4108);
usedRange->setProperty("HorizontalAlignment", -4131);
usedRange->setProperty("NumberFormatLocal", "@"); //设置文本格式
QVariant var = usedRange->dynamicCall("Value");
delete usedRange;
excel.dynamicCall("Quit(void)");

QList<QList<QVariant>> vList;
castVariant2ListListVariant(var,vList);
vList.removeAt(0);
if (vList[0].count() < 43 || vList.isEmpty() || vList.count() == 0)
return setError(ZH("导入数据有误,请检查!"));

list = daConver_.getExcel(vList, true);
QStringList hthList;
for (int i = 0; i < list.count();i++)
{
ExcelBill bill = list[i];
if (daExcl_.exist(bill.lsh_,bill))
{
hthList << bill.lsh_;
continue;
}
}
if (hthList.count() != 0 )
Common::showInfo(parent, ZH("流水号重复!"));

for (int i = 0; i < hthList.count();i++)
{
QString hth = hthList[i];
toDel_.deleteRepetition(list,hth);
}
if (!sp_.automaticSplit(list) || list.count() == 0)
{
Common::showError(parent, sp_.lastError());
return false;
}
return true;
}

时间: 2024-12-22 17:29:06

Qt中快速读写Excel方法封装的相关文章

在.net中序列化读写xml方法的总结

在.net中序列化读写xml方法的总结 阅读目录 开始 最简单的使用XML的方法 类型定义与XML结构的映射 使用 XmlElement 使用 XmlAttribute 使用 InnerText 重命名节点名称 列表和数组的序列化 列表和数组的做为数据成员的序列化 类型继承与反序列化 反序列化的实战演练 反序列化的使用总结 排除不需要序列化的成员 强制指定成员的序列化顺序 自定义序列化行为 序列化去掉XML命名空间及声明头 XML的使用建议 XML是一种很常见的数据保存方式,我经常用它来保存一些

C#_在.net中序列化读写xml方法的总结

阅读目录 开始 最简单的使用XML的方法 类型定义与XML结构的映射 使用 XmlElement 使用 XmlAttribute 使用 InnerText 重命名节点名称 列表和数组的序列化 列表和数组的做为数据成员的序列化 类型继承与反序列化 反序列化的实战演练 反序列化的使用总结 排除不需要序列化的成员 强制指定成员的序列化顺序 自定义序列化行为 序列化去掉XML命名空间及声明头 XML的使用建议 XML是一种很常见的数据保存方式,我经常用它来保存一些数据,或者是一些配置参数. 使用C#,我

Qt中静态变量使用方法

静态变量可以在各个页面之前使用 先定义一个用于存放静态变量的类 例如datavar 在datavar.h中添加如下代码 #ifndef DATAVAR_H #define DATAVAR_H #include <QObject> class dataVar : public QObject { Q_OBJECT public: explicit dataVar(QObject *parent = 0); static QString loginName ;//登录名 signals: publ

qt中线程的使用方法

QT中使用线程可以提高工作效率. 要使用线程要经过一下四个步骤: (1)先创建一个c++ class文件,记得继承Thread,创建步骤如下: a.第一步 b.第二步 (2)自定义一个run函数,以后启动线程的时候,程序就会跳转到run函数中 void run(); (3)初始化线程 HDThread mythread = new HDThread(); (4)启动线程 mythread->start(); 下面来看看线程使用的具体列子: 线程头文件hdthread.h: 1 #ifndef H

(转)在.net中序列化读写xml方法的总结

阅读目录 开始 最简单的使用XML的方法 类型定义与XML结构的映射 使用 XmlElement 使用 XmlAttribute 使用 InnerText 重命名节点名称 列表和数组的序列化 列表和数组的做为数据成员的序列化 类型继承与反序列化 反序列化的实战演练 反序列化的使用总结 排除不需要序列化的成员 强制指定成员的序列化顺序 自定义序列化行为 序列化去掉XML命名空间及声明头 XML的使用建议 XML是一种很常见的数据保存方式,我经常用它来保存一些数据,或者是一些配置参数. 使用C#,我

python读写Excel方法(xlwt和xlrd)

在我们做平常工作中都会遇到操作excel,那么今天写一篇,如何通过python操作excel,当然python操作excel的库有很多,比如pandas,xlwt/xlrd,openpyxl等,每个库都有不同的区别,具体的区别,大家一起研究下哈. xlrd模块 xlrd是对于Excel进行读取,xlrd 操作的是xls/xlxs格式的excel 安装 xlrd是python的第3方库,需要通过pip进行安装 pip install xlrd 读取excel数据 1.导入xlrd莫款 2.打开Ex

在项目中常用的JS方法封装

使用方法简单,只需要放在你的 utils.js 工具文件中,直接export const 加上下面封装方法,在别的文件中使用 {方法1,方法2,方法3...}引用后直接使用即可. 01.输入一个值.返回其数据类型 type = para =>{ return Object.toString.call(para).slice(8,-1) } 02.冒泡排序 升序 bubbleAsSort() bubbleAsSort = arr =>{ for(let i=0;i<arr.length -

Eclipse中快速 打出 main方法的签名

有时,我们创建一个空白类,需要打出main方法 public static void main(String [] args){ } 在Eclipse先敲main字符,然后按住ALT+/,再按回车即可. Eclipse就可以快速帮我写好main方法

php中get post请求方法封装

<span style="font-size:18px;">网站上的商城可以搭建ecshop实现,微信端的微商城也可以开发wap版商城,然后通过链接链到微信菜单上,这样实现起来就不需要远程调用数据了,但登陆上有个问题,在微信上进入微商城在用户体验上当然不需要再登陆只需要有微信openid即可.所以有个考虑是在微信端开发微商城,所以的数据是取自网站商城的,这时需要远程请求数据. 有了ihttp_request()方法后,可通过此方法获取远程数据</span> &l