你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

QAxObject类操作Excel过程总结

2021/12/7 15:19:14

使用Qt自带的axcontainer模块中的QAxObject类操作Excel需要知道其中的方法和属性,以下总结也是工作过程中用到过的。

使用QAxObject不足之处:

  1. 依赖本地Excel软件,否则无法正常导出
  2. 导出数据量太大时,会影响性能,亲测,60w条数据需要两分钟
bool ExportExcel::addWorkbook()
{
    m_pExcel = new QAxObject();
    
     //连接Excel控件
    if (!m_pExcel->setControl("Excel.Application"))
        return false; 
        
    //窗体显示控制,用于调试,此处放开,导出excel整个过程都可以看到,想放电影一样
    //m_pExcel->dynamicCall("SetVisible (bool Visible)", true);
    
    //不显示任何警告信息。如果为true那么在关闭是会出现类似“文件已修改,是否保存”的提示
    m_pExcel->setProperty("DisplayAlerts", false);
    
    //获取工作簿集合
    auto pWorkbooks = m_pExcel->querySubObject("WorkBooks");
    if (!pWorkbooks) 
        return false;
        
    //新建一个工作簿    
    pWorkbooks->dynamicCall("Add");
    
	//获取当前工作簿
    m_pWorkbook = m_pExcel->querySubObject("ActiveWorkBook");
    if (!m_pWorkbook)
        return false;
        
    return true;
}
QAxObject* GTJRuleContrastExportExcel::setWorkBook(QString strSheetName)
{
    if (!m_pWorkbook)
    {
        return nullptr;
    }

    QAxObject *worksheets = m_pWorkbook->querySubObject("Sheets");//获取工作表集合
    int sheet_count = worksheets->property("Count").toInt();  //获取工作表数目
    QAxObject *last_sheet = worksheets->querySubObject("Item(int)", sheet_count);
    QAxObject *work_sheet = worksheets->querySubObject("Add(QVariant)", last_sheet->asVariant());
    work_sheet->dynamicCall("Move(QVariant)", last_sheet->asVariant());
    work_sheet->setProperty("Name", strSheetName);  //设置工作表Sheet名
    
    return work_sheet;
}
void ExportExcel::endExport()  //在析构函数中调用
{
    if (m_pWorkbook)
    {
        QAxObject *worksheets = m_pWorkbook->querySubObject("Sheets");//获取工作表集合
        QAxObject *first_sheet = worksheets->querySubObject("Item(int)", 1);
        first_sheet->dynamicCall("Select()");//选中 sheet

        int sheet_count = worksheets->property("Count").toInt();  //获取工作表数目
        first_sheet = worksheets->querySubObject("Item(int)", sheet_count);
        first_sheet->dynamicCall("delete");//删除最后一个sheet页,为:sheet1

        m_pWorkbook->dynamicCall("SaveAs(const QString&)", QDir::toNativeSeparators(m_strSavePath));//保存至filepath,注意一定要用QDir::toNativeSeparators将路径中的"/"转换为"\",不然一定保存不了。
        m_pWorkbook->dynamicCall("Close()");//关闭工作簿
    }

    if (m_pExcel)
    {
        m_pExcel->dynamicCall("Quit()");//关闭excel
        delete m_pExcel;
        m_pExcel = nullptr;
    }
}
void ExportExcel::startExport()
{
    if (!addWorkbook())
    {
        return;
    }
    
    QAxObject *work_sheet = setWorkBook(strSheetName);
    if (!work_sheet)
    {
        return;
    }
    
    //以下开始乱炖
    //以下有些指针没有判空,一定要养成指针判空的好习惯
    
   	//处理写入excel单元格数据
	//方式一,使用Range方法统一写入excel表格,数据量过大时,可以提升性能
    {
	    QList<QVariant> oRowdata;
	    QList<QVariant> aline;	    
	    aline.append(QVariant(QStringLiteral("哈哈")));
	    aline.append(QVariant(QStringLiteral("呵呵")));
	    aline.append(QVariant(QStringLiteral("嘿嘿")));   
	    QVariant conv(aline);
	    oRowdata.append(conv);
	    QVariant oData(oRowdata);
	    QString strRange = "A"+ QString::number(1) + ":" + "C" + QString::number(1);//A1:C1,需写入数据的表格范围
	    QAxObject *oRange = work_sheet->querySubObject("Range(QString)", strRange);
	    if (oRange)
	    {
	        oRange->setProperty("Value2", oData);//设置单元格值,使用Value2 wps 和 office可以正常导出数据
	    }
	}
	
	//方式二,指定行列写入数据,这种方式不仅显得很笨拙,而且数据量很大时,慢的要死,主要是每写入一个数据都要访问一次表格,性能很低。
	{
		//第5行第3列
		QAxObject *cell_5_3 = work_sheet->querySubObject("Cells(int,int)", 5, 3);
		cell_5_3->setProperty("Value2", "C++"); 
	}
	
	{
	    QAxObject *pCell = work_sheet->querySubObject("Range(const QString&)", "A1:C1");
	    if (pCell)
	    {	    	        	
        	//字体对齐(居中)
	        pCell ->setProperty("HorizontalAlignment", -4108);//左对齐(xlLeft):-4131  居中(xlCenter):-4108  右对齐(xlRight):-4152
	        pCell ->setProperty("VerticalAlignment", -4108); //上对齐(xlTop)-4160 居中(xlCenter):-4108  下对齐(xlBottom):-4107
	    	        
	        //设置字体
	        QAxObject *font = pCell->querySubObject("Font");  //获取单元格字体
	        font->setProperty("Bold", true);  //字体加粗
			font->setProperty("Name", QStringLiteral("华文彩云"));  //设置单元格字体
			font->setProperty("Bold", true);  //设置单元格字体加粗
			font->setProperty("Size", 20);  //设置单元格字体大小
			font->setProperty("Italic", true);  //设置单元格字体斜体
			font->setProperty("Underline", 2);  //设置单元格下划线
			font->setProperty("Color", QColor(255, 0, 0));  //设置单元格字体颜色(红色)
	
	        //设置单元格背景色(灰色)
	        QColor bkColor(125, 125, 125);
	        QAxObject* interior = pCell->querySubObject("Interior");
	        interior->setProperty("Color", bkColor);
	        
	        //绘制单元格边框(黑色)
	        QAxObject* border = pCell->querySubObject("Borders");
	        border->setProperty("Color", QColor(0, 0, 0)); 
	       
	       //创建组
        	QAxObject* rows = pCell->querySubObject("Rows");
        	rows->querySubObject("Group");
	    }

		//宽度自适应
	  	auto range = work_sheet->querySubObject("UsedRange");
		QAxObject * cells = range->querySubObject("Columns");
	  	if (cells)
	   	{
	       cells->dynamicCall("AutoFit");
	   	}	

		//设置单元格格式(文本)
		QAxObject *oRange = work_sheet->querySubObject("Range(QString)", "A1:A99");
   		if (oRange)
   		{
       		oRange->setProperty("NumberFormatLocal", "@");
   		}
   		
   		oRange = work_sheet->querySBubObject("Range(QString)", "A1:B1");
   		if (oRange)
   		{
       		pCell ->setProperty("WrapText", true); //内容过多,自动换行
        	pCell ->setProperty("MergeCells", true); //合并单元格
        	//pCell ->setProperty("MergeCells", false);  //拆分单元格
        	//cell->dynamicCall("ClearContents()");  //清空单元格内容
   		}
	}
}