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