#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;
}