DBGrid 导出到 Excel

 

     if ( SaveDialog->Execute() /*SelectDirectory("请选择存储目录","",Dir)*/ )

     {

         ExportToExcel( DBGrid,/*Dir*/ SaveDialog->FileName);

     }

 

 

 

 

 

/*****************************************************

函数说明: 讲DBGrid的数据导出到Excel中

参    数: *dbg 指向要导出的TDBGrid对象,saveDir保存的路径

备    注:数据的写入用了windows的粘贴板做暂存后再粘贴到excel,

          这样减少重复多次的读写操作,缩减导出时间。

          另外Excel一个sheet只能有65536行,如果导出的数据行数

          多于65530行(6行用掉了)应该要存到多个sheet,目前没有实现。

******************************************************/

void TF_report::ExportToExcel(TDBGrid *dbg, String saveDir)

{

 /*************************************************************

  以下为TExcelApplication、TExcelWorkbook、TExcelWorksheet方法

  虽然比较推荐,但是Excel进程只能在关闭窗体后才会退出,找不到

  导完数据后关闭的方法。

 ***********************************************************/

    try

    {

       ExcelApplication->Connect();

       ExcelApplication->set_DisplayAlerts(0,false);

    }

    catch(...)

    {

        MessageBox(0, "启动 Excel 出错,可能你没有安装Office .",

                "导出错误", MB_OK | MB_ICONERROR);

        return;

    }

 

    try

    {

      // 隐藏Excel界面

       ExcelApplication->set_Visible(0,false);

    }

    catch (...)

    {

       MessageBox(0, "启动 Excel 出错 .",

                "导出错误", MB_OK | MB_ICONERROR);

         ExcelApplication->Disconnect();

         ExcelApplication->Quit();

         return;

    }

 

 

    //载入模板

    String xls = ExtractFilePath(Application->ExeName) + "Template.xls";

 

    if( !FileExists(xls) )

    {

      MessageBox(0, "Excel模板文件不存在,请重新安装外接软件!",

                "导出错误", MB_OK | MB_ICONERROR);

 

      ExcelApplication->Disconnect();

      ExcelApplication->Quit();

      return;

    }

 

    try

    {

    // 载入模板到Excel

      WideString wxls  = xls;

      ExcelWorkbook->ConnectTo(ExcelApplication->Workbooks->Open(wxls.c_bstr(),

                                                                 TNoParam(),TNoParam(),TNoParam(),TNoParam(),

                                                                 TNoParam(),TNoParam(),TNoParam(),TNoParam(),

                                                                 TNoParam(),TNoParam(),TNoParam(),TNoParam(),0));

    }

    catch( ... )

    {

       MessageBox(0, "Excel模板载入错误!",

                "导出错误", MB_OK | MB_ICONERROR);

 

      ExcelWorkbook->Disconnect();

      ExcelApplication->Disconnect();

      ExcelApplication->Quit();

      return;

    }

 

   try

   {

    // 操作这个工作表

     ExcelWorksheet->ConnectTo( ExcelWorkbook->Worksheets->get_Item( TVariant(1) ) );

 

    // 表格的行数

    int nRowCount(dbg->DataSource->DataSet->RecordCount);

    nRowCount = nRowCount < 2? 2: nRowCount;

 

    if( nRowCount > 65530 )

    {

        ShowMessage("记录多于65530条,受Excel的工作表限制,将只导出前65530条。");

        nRowCount = 65530;

    }

 

    //插入nRowCount-1行

    for ( int i = 0; i < nRowCount -1 ; ++i)

    {

 

        Excel_2k::RangePtr rp;

        rp =  ExcelWorksheet->get_Range(TVariant("A3"),TVariant("A3"));

        rp->EntireRow->Insert(TNoParam());

 

    }

 

    // 表格的列数

    int nColCount(dbg->Columns->Count);

    nColCount = nColCount < 1? 1: nColCount;

 

 

    // 将DBGrid中的数据写入Excel表格

    int pcount = 0 , unpcount;

    String qual,rate,value,cell;

    char ct;

//    cell = "A" + IntToStr(1);

//    value = "我是标题";

//    ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );

 

    TStringList *sl=new TStringList();

    dbg->DataSource->DataSet->First();

    for(int i=0; i<nRowCount; i++)

    {

        value = "";

        for(int j=0; j<nColCount; j++)

        {

            if( j != 1)

            {

               // value = dbg->DataSource->DataSet->FieldByName(dbg->Columns->Items[j]->FieldName)->AsString;

               value += Trim(dbg->DataSource->DataSet->Fields->Fields[j]->AsString) + "/t";

            }

            else

            {   //DBGrid显示时间时自动加上了一个日期,在显示和导出时需要格式化,去掉日期( PS:显示用了字典格式化)

               // value = FormatDateTime("hh:nn:ss",dbg->DataSource->DataSet->FieldByName(dbg->Columns->Items[j]->FieldName)->AsDateTime);

               value += FormatDateTime("hh:nn:ss", Trim(dbg->DataSource->DataSet->Fields->Fields[j]->AsDateTime) ) + "/t";

            }

 

           //   ct = static_cast<char>('A' + j);

           //   cell = ct ;

           //   cell +=  IntToStr(i + 3);

           //   ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );

        }

        sl->Add(value);  //TStringList自动在末尾加上 /n 换行符

        qual = Trim(dbg->DataSource->DataSet->FieldByName("Test_qual")->AsString);

        if( qual == "合格")

           pcount++;

 

        dbg->DataSource->DataSet->Next();

    }

 

    Clipboard()->SetTextBuf(sl->Text.c_str());   //发送到粘贴板

    ExcelWorksheet->get_Range(TVariant("A3"),TVariant("A3"))->Select();

    ExcelWorksheet->Paste();

    ExcelWorksheet->get_Range(TVariant("A1"),TVariant("A1"))->Select();

    Clipboard()->Clear(); //清除粘贴板

 

    unpcount = nRowCount - pcount;

    rate = FormatFloat("0.00",100.0f*pcount/nRowCount);

    rate += "%";

 

    //设置总个数

    value =  IntToStr(nRowCount);

    ct = static_cast<char>('A' + 3);

    cell = ct;

    cell += IntToStr(nRowCount + 4);

    ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );

 

    //合格个数

     value =  IntToStr(pcount);

     ct = static_cast<char>('A' + 8);

     cell = ct;

     cell += IntToStr(nRowCount + 4);

    ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );

 

    //不合格个数

    value =  IntToStr(unpcount);

    ct = static_cast<char>('A' + 10);

     cell = ct ;

     cell += IntToStr(nRowCount + 4);

    ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );

 

 

    //合格率

    value =  rate;

    ct = static_cast<char>('A' + 12);

    cell = ct;

    cell += IntToStr(nRowCount + 4);

    ExcelWorksheet->get_Range(TVariant(cell),TVariant(cell))->set_Value( TVariant(value) );

 

    WideString Dir = saveDir;

    ExcelWorksheet->SaveAs(Dir.c_bstr(),

                             TNoParam(),TNoParam(),TNoParam(),TNoParam(),

                             TNoParam(),TNoParam(),TNoParam(),TNoParam(),0);

 

   }

   catch( ... )

   {

      ExcelWorksheet->Disconnect();

      ExcelWorkbook->Disconnect();

      ExcelApplication->Disconnect();

      ExcelApplication->Quit();

      ExcelQueryTable->Disconnect();

      return;

   }

 

      ExcelWorksheet->Disconnect();

      ExcelWorkbook->Disconnect();

      ExcelApplication->Disconnect();

      ExcelQueryTable->Disconnect();

      ExcelApplication->Quit();

 

 /*************************************************************

  以下为OLE方法,编译时无法判断错误的Excel操作,

  但能在导出后关闭Excel进程。

 ***********************************************************/

   /*

 

     Variant vExcelApp, vSheet,Range;

    try

    {

        vExcelApp = Variant::CreateObject("Excel.Application");

 

    }

    catch(...)

    {

        MessageBox(0, "启动 Excel 出错,可能你没有安装Office .",

                "导出错误", MB_OK | MB_ICONERROR);

        return;

    }

 

    try

    {

      // 隐藏Excel界面

     vExcelApp.OlePropertySet("Visible", false);

 

    }

    catch (...)

    {

       MessageBox(0, "启动 Excel 出错 .",

                "导出错误", MB_OK | MB_ICONERROR);

 

      vExcelApp.OleFunction("Quit");

       vSheet = Unassigned;

       vExcelApp = Unassigned;

       return;

    }

    //载入模板

    String xls = ExtractFilePath(Application->ExeName) + "Template.xls";

 

    if( !FileExists(xls) )

    {

      MessageBox(0, "Excel模板文件不存在,请重新安装外接软件!",

                "导出错误", MB_OK | MB_ICONERROR);

 

 

      vExcelApp.OleFunction("Quit");

      vSheet = Unassigned;

      vExcelApp = Unassigned;

      return;

    }

 

    try

    {

    // 载入模板到Excel

    vExcelApp.OlePropertyGet("Workbooks").OleFunction("Open",xls.c_str()); // 工作表

 

    }

    catch( ... )

    {

       MessageBox(0, "Excel模板载入错误!",

                "导出错误", MB_OK | MB_ICONERROR);

 

 

      vExcelApp.OleFunction("Quit");

      vSheet = Unassigned;

      vExcelApp = Unassigned;

      return;

    }

    // 操作这个工作表

    vSheet = vExcelApp.OlePropertyGet("ActiveWorkbook").OlePropertyGet("Sheets", 1);

 

 

    // 表格的行数

    int nRowCount(dbg->DataSource->DataSet->RecordCount);

    nRowCount = nRowCount < 2? 2: nRowCount;

 

    //插入nRowCount-1行

    for ( int i = 0; i < nRowCount -1 ; ++i)

    {

      vSheet.OlePropertyGet("Rows",3).OleProcedure("Insert");

 

    }

 

    // 表格的列数

    int nColCount(dbg->Columns->Count);

    nColCount = nColCount < 1? 1: nColCount;

 

    if( nRowCount > 65530 )

    {

        ShowMessage("记录多于65530条,受Excel的工作表限制,将只导出前65530条。");

        nRowCount = 65530;

    }

    S

    TStringList *sl=new TStringList();

    int pcount = 0 , unpcount;

    String qual,rate,value ="";

 

    dbg->DataSource->DataSet->First();

    for(int i=0; i<nRowCount; i++)

    {   value ="";

        for(int j=0; j<nColCount; j++)

        {

            if( j != 1)

            {

              //  value = dbg->DataSource->DataSet->FieldByName(dbg->Columns->Items[j]->FieldName)->AsString;

              value += Trim(dbg->DataSource->DataSet->Fields->Fields[j]->AsString) + "/t";

            }

            else

            {   //DBGrid显示时间时自动加上了一个日期,在显示和导出时需要格式化,去掉日期( PS:显示用了字典格式化)

               // value = FormatDateTime("hh:nn:ss",dbg->DataSource->DataSet->FieldByName(dbg->Columns->Items[j]->FieldName)->AsDateTime);

               value += FormatDateTime("hh:nn:ss",Trim(dbg->DataSource->DataSet->Fields->Fields[j]->AsDateTime)) + "/t";

            }

           // vSheet.OlePropertyGet("Cells", i + 3, j + 1).OlePropertySet("Value",value.c_str());

 

 

        }

        sl->Add(value);

        qual = Trim(dbg->DataSource->DataSet->FieldByName("Test_qual")->AsString);

        if( qual == "合格")

           pcount++;

 

        dbg->DataSource->DataSet->Next();

    }

 

 

    vExcelApp.Exec(PropertyGet("Range")<<"A3").Exec(Procedure("Select"));

 

    Clipboard()->SetTextBuf(sl->Text.c_str());   //发送到粘贴板

    vExcelApp.OlePropertyGet("ActiveSheet").OleProcedure("Paste");

 

    vSheet.OlePropertyGet("Cells", 1, 1).OleProcedure("Select"); //去除粘贴造成的选区

 

    Clipboard()->Clear(); //清除粘贴板

 

    unpcount = nRowCount - pcount;

 

    rate = FormatFloat("0.00",100.0f*pcount/nRowCount);

    rate += "%";

 

    //设置总个数

 

    vSheet.OlePropertyGet("Cells", nRowCount + 4,4).OlePropertySet("Value",IntToStr(nRowCount).c_str());

 

    //合格个数

 

    vSheet.OlePropertyGet("Cells", nRowCount + 4,9).OlePropertySet("Value",IntToStr(pcount).c_str());

 

    //不合格个数

 

    vSheet.OlePropertyGet("Cells", nRowCount + 4,11).OlePropertySet("Value",IntToStr(unpcount).c_str());

 

    //合格率

    vSheet.OlePropertyGet("Cells", nRowCount + 4,13).OlePropertySet("Value",rate.c_str());

 

   // 保存Excel文档并退出

   try

   {

    vExcelApp.OlePropertyGet("ActiveWorkbook").OleFunction("SaveAs", saveDir.c_str());

 

   }

   catch( ... )

   {

      vExcelApp.OleFunction("Quit");

      vSheet = Unassigned;

      vExcelApp = Unassigned;

 

      return;

   }

 

    vExcelApp.OleFunction("Quit");

    vSheet = Unassigned;

    vExcelApp = Unassigned;

 

  */

    // 工作结束

    MessageBox(0, "导出成功",

            "导出到Excel", MB_OK | MB_ICONINFORMATION);

 

 

}

 

你可能感兴趣的:(DBGrid 导出到 Excel)