zoukankan      html  css  js  c++  java
  • VC操作HTML的TABLE的样例代码

    #include "stdafx.h"
    #include "sreport.h"
    #include "SHTMLReport.h"

    #ifdef _DEBUG
    #undef THIS_FILE
    static char THIS_FILE[]=__FILE__;
    #define new DEBUG_NEW
    #endif

    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////

    CSHTMLReport::CSHTMLReport()
    {
     m_pHtmlDoc2=NULL;
     m_iHeadLines=1;
    }

    CSHTMLReport::~CSHTMLReport()
    {

    }

    //***********************************************
    // 指定HTML文档接口
    //**********************************************
    void CSHTMLReport::SetHtmlDocPtr(IHTMLDocument2 *pDoc)
    {
     m_pHtmlDoc2=pDoc;
    }

    //***********************************************
    // 指定操作的表的名称,表名称在HTML模板中指定
    //*********************************************
    void CSHTMLReport::SetTableName(CString name)
    {
     m_strTableName=name;
    }

    //**************************************************
    // 获取HTML表格COM接口,内部接口
    //**************************************************
    IHTMLTable * CSHTMLReport::GetTableDispatch()
    {
     ASSERT(m_pHtmlDoc2);
     IHTMLElementCollection *all;
     m_pHtmlDoc2->get_all(&all);
     IDispatch *distable;
     all->item(COleVariant(m_strTableName),COleVariant(short(0)),&distable);
     IHTMLTable *pITable=NULL;
     HRESULT hr=distable->QueryInterface(IID_IHTMLTable, (void**)&pITable);//get table dispatch
     ASSERT(hr==S_OK);
     return pITable;
    }

    //*******************************************************
    // 在指定位置插入一行,index==-1表示append
    //*******************************************************
    BOOL CSHTMLReport::InsertRow(int index)
    {
     IHTMLTable *pITable=GetTableDispatch();
     IDispatch *disrow;
     HRESULT hr=pITable->insertRow(index,&disrow);//insert a  row at 1 position
     if(hr!=S_OK) return FALSE;

     IHTMLTableRow *pIRow;
     hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
     ASSERT(hr==S_OK);
     
     long cols;
     hr=pITable->get_cols(&cols);
     ASSERT(hr==S_OK&&cols!=0);
     
     IDispatch *discell;
     IHTMLElement *cell;

     CString str= " ";
     BSTR bsStr = str.AllocSysString();
     for(int i=0;i<cols;i++)
     {
      pIRow->insertCell(i,&discell);
      discell->QueryInterface(IID_IHTMLElement,(void **)&cell);
      cell->put_innerHTML(bsStr);
      cell->Release();
      discell->Release();
     }
     SysFreeString(bsStr);
     pIRow->Release();

     if(!m_strIndexFormat.IsEmpty())
     {
      IHTMLElementCollection *irows;
      hr=pITable->get_rows(&irows);
      ASSERT(hr==S_OK);
      long rows;
      hr=irows->get_length(&rows);
      ASSERT(hr==S_OK);
      CString strHead="";
      if(index==-1) index=rows-1;
      for(long i=index;i<rows;i++)
      {
       strHead.Format(m_strIndexFormat,i);
       BSTR bsStrHead=strHead.AllocSysString();
       hr=irows->item(COleVariant(long(i)),COleVariant(long(0)),&disrow);
       ASSERT(hr==S_OK);
       //get row interface
       hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
       ASSERT(hr==S_OK);
       IHTMLElementCollection *icells;
       hr=pIRow->get_cells(&icells);
       ASSERT(hr==S_OK);
       hr=icells->item(COleVariant(long(0)),COleVariant(long(0)),&discell);
       ASSERT(hr==S_OK);
       discell->QueryInterface(IID_IHTMLElement,(void **)&cell);
       ASSERT(hr==S_OK);
       cell->put_innerText(bsStrHead);
       SysFreeString(bsStrHead);
       cell->Release();
       pIRow->Release();
       disrow->Release();
      }
      irows->Release();
     }

     pIRow->Release();
     disrow->Release();
     pITable->Release();
     return TRUE;
    }

    //***************************************************************
    // 修改单元格的内容:可以使用html语法
    //***************************************************************
    BOOL CSHTMLReport::SetItemHTML(int iRow, int iCol, CString html)
    {
     IHTMLTable *pITable=GetTableDispatch();
     //get row collect
     IHTMLElementCollection *pIRows;
     HRESULT hr=pITable->get_rows(&pIRows);
     ASSERT(hr==S_OK);
     //get specisfied row
     IDispatch *disrow;
     hr=pIRows->item(COleVariant(long(iRow)),COleVariant(short(0)),&disrow);//iRow row
     if(hr!=S_OK||disrow==NULL) return FALSE;

     IHTMLTableRow *pIRow;
     hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
     ASSERT(hr==S_OK);
     //get cell collect
     IHTMLElementCollection *rowcells;
     pIRow->get_cells(&rowcells);
     //get cell
     IDispatch *discell;
     IHTMLElement *cell;
     hr=rowcells->item(COleVariant(long(iCol)),COleVariant(short(0)),&discell);//iCol col
     if(hr!=S_OK||discell==NULL) return FALSE;
     hr=discell->QueryInterface(IID_IHTMLElement,(void **)&cell);
     ASSERT(hr==S_OK);

     BSTR bsStr = html.AllocSysString();
     cell->put_innerHTML(bsStr);
     SysFreeString(bsStr);
     
     cell->Release();
     pIRow->Release();
     pITable->Release();
     return TRUE;
    }

    //************************************************
    // 删除指定行
    //************************************************
    BOOL CSHTMLReport::DeleteRow(int index)
    {
     IHTMLTable *pITable=GetTableDispatch();
     HRESULT hr=pITable->deleteRow(index);
     pITable->Release();
     return hr==S_OK;
    }

    //************************************************
    // 将指定行数据相同的单元格合并
    //************************************************
    BOOL CSHTMLReport::MergeRow(int iRow)
    {
     IHTMLTable *pITable=GetTableDispatch();
     //get row collect
     IHTMLElementCollection *pIRows;
     HRESULT hr=pITable->get_rows(&pIRows);
     ASSERT(hr==S_OK);
     //get specisfied row
     IDispatch *disrow;
     hr=pIRows->item(COleVariant(long(iRow)),COleVariant(short(0)),&disrow);//iRow row
     if(hr!=S_OK||disrow==NULL) return FALSE;

     IHTMLTableRow *pIRow;
     hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
     ASSERT(hr==S_OK);
     //get cell collect
     IHTMLElementCollection *rowcells;
     pIRow->get_cells(&rowcells);
     long cells;
     hr=rowcells->get_length(&cells);

     IDispatch *discell;
     IHTMLElement *icellElement;
     long begin=-1,end=-1;
     CString beginStr;
     CString cellStr;
     long    beginRowSpan=0,rowSpan;
     for(long i=m_strIndexFormat.IsEmpty()?0:1;i<cells;i++)
     {
      //get cell
      hr=rowcells->item(COleVariant(long(i)),COleVariant(short(0)),&discell);
      ASSERT(hr==S_OK&&discell!=NULL);
      hr=discell->QueryInterface(IID_IHTMLElement,(void **)&icellElement);
      ASSERT(hr==S_OK&&icellElement!=NULL);
      
      cellStr=GetElementText(icellElement,inner_text);
      IHTMLTableCell *icell;
      hr=discell->QueryInterface(IID_IHTMLTableCell,(void **)&icell);
      ASSERT(hr==S_OK&&icell!=NULL);
      icell->get_rowSpan(&rowSpan);
      if(cellStr!=beginStr||rowSpan!=beginRowSpan)
      {
       if(end-begin+1>1&&begin!=-1)
       {
        ASSERT(beginRowSpan!=0);
        MergeRowPrivate(pIRow,begin,end);
        cells-=end-begin;
        i-=end-begin;
       }
       begin=end=i;
       beginStr=cellStr;
       beginRowSpan=rowSpan;
      }else
       end=i;
      icell->Release();
      icellElement->Release();
     }

     if(begin!=end)
      MergeRowPrivate(pIRow,begin,end);
     pIRow->Release();
     pITable->Release();
     return TRUE;
    }

    //************************************************
    // 将指定列数据相同的单元格合并
    //************************************************
    BOOL CSHTMLReport::MergeCol(int iCol)
    {
     IHTMLTable *pITable=GetTableDispatch();
     //get row collect
     IHTMLElementCollection *pIRows;
     HRESULT hr=pITable->get_rows(&pIRows);
     ASSERT(hr==S_OK);
     CSArray<COLCELLINFO> colArray;
     if(!MakeColDispatchCollection(pIRows,iCol,colArray)) return FALSE;
     int colCells=colArray.GetSize();
     COLCELLINFO cci;
     CString beginStr,cellStr;
     long beginColSpan=0,colSpan;
     int  begin=-1,end;
     for(int i=0;i<colCells;i++)
     {
      cci=colArray.GetAt(i);
      if(cci.pDisCell==NULL)
       continue;
      IHTMLElement *icellElement;
      hr=cci.pDisCell->QueryInterface(IID_IHTMLElement,(void **)&icellElement);
      ASSERT(hr==S_OK&&icellElement!=NULL);
      cellStr=GetElementText(icellElement,inner_text);
      IHTMLTableCell *icell;
      hr=cci.pDisCell->QueryInterface(IID_IHTMLTableCell,(void **)&icell);
      ASSERT(hr==S_OK&&icell!=NULL);
      hr=icell->get_colSpan(&colSpan);
      if(cellStr!=beginStr||colSpan!=beginColSpan)
      {
       if(begin!=-1&&end-begin+1>1)
       {
        ASSERT(beginColSpan!=0);
        MergeColPrivate(pIRows,colArray,begin,end);
       }
       begin=end=i;
       beginStr=cellStr;
       beginColSpan=colSpan;
      }else
       end=i;
      icell->Release();
      icellElement->Release();
     }
     if(begin!=end)
      MergeColPrivate(pIRows,colArray,begin,end);
     pITable->Release();
     return TRUE;
    }

    //***********************************************
    // 设置索引列的显示格式:遵循sprintf函数的规则
    //***********************************************
    void CSHTMLReport::SetIndexFormat(CString strIndexFormat)
    {
     m_strIndexFormat=strIndexFormat;
    }

    //*************************************************
    // 获取元素的字符
    //*************************************************
    CString CSHTMLReport::GetElementText(IHTMLElement *pElement, int type)
    {
     CString str= "";
     BSTR bsStr = str.AllocSysString();
     switch(type)
     {
     case inner_text:
      pElement->get_innerText(&bsStr);
      break;
     case inner_html:
      pElement->get_innerHTML(&bsStr);
      break;
     case outer_text:
      pElement->get_outerText(&bsStr);
      break;
     case outer_html:
      pElement->get_outerHTML(&bsStr);
      break;
     default:
      ASSERT(0);
      break;
     }
     _bstr_t bstStr;
     bstStr = bsStr;
     str.Format("%s",(LPCTSTR)bstStr);
     SysFreeString(bsStr);
     return str;
    }

    //********************************************************
    // 设置元素字符
    //*******************************************************
    BOOL CSHTMLReport::SetElementText(IHTMLElement *pElement, int type,CString str)
    {
     BSTR bsStr = str.AllocSysString();
     HRESULT hr;
     switch(type)
     {
     case inner_text:
      hr=pElement->put_innerText(bsStr);
      break;
     case inner_html:
      hr=pElement->put_innerHTML(bsStr);
      break;
     case outer_text:
      hr=pElement->put_outerText(bsStr);
      break;
     case outer_html:
      hr=pElement->put_outerHTML(bsStr);
      break;
     default:
      ASSERT(0);
      break;
     }
     SysFreeString(bsStr);
     return (hr==S_OK);
    }

    //******************************************************************
    // 在指定的行中从指定的起始及终止位置进行合并:内部函数
    //******************************************************************
    void CSHTMLReport::MergeRowPrivate(IHTMLTableRow *pIRow, long begincol, long endcol)
    {
     long   colSpan=0;
     IHTMLElementCollection *picells;
     HRESULT hr=pIRow->get_cells(&picells);
     for(long i=endcol;i>=begincol;i--)
     {
      IDispatch *discell;
      hr=picells->item(COleVariant(i),COleVariant(short(0)),&discell);
      ASSERT(hr==S_OK&&discell!=NULL);
      IHTMLTableCell *picell;
      hr=discell->QueryInterface(IID_IHTMLTableCell,(void **)&picell);
      ASSERT(hr==S_OK&&picell!=NULL);
      long tmpColSpan;
      picell->get_colSpan(&tmpColSpan);
      colSpan+=tmpColSpan;
      if(i==begincol)
       picell->put_colSpan(colSpan);
      else
       pIRow->deleteCell(i);
      picell->Release();
     }
    }

    //******************************************************************
    // 在指定的行集中对指定列从指定的起始及终止位置进行合并:内部函数
    //******************************************************************
    void CSHTMLReport::MergeColPrivate(IHTMLElementCollection *pIRowArray,CSArray<COLCELLINFO> &colArray,long beginrow, long endrow)
    {
     IHTMLTableCell *ibegincell=NULL;
     long   rowSpan=0;
     for(int i=beginrow;i<=endrow;i++)
     {
      IHTMLTableCell *icell;
      COLCELLINFO cci=colArray.GetAt(i);
      ASSERT(cci.iIndexInRow!=-1);
      IDispatch *disrow;
      HRESULT hr=pIRowArray->item(COleVariant(cci.iRow),COleVariant(short(0)),&disrow);//iRow row
      if(hr!=S_OK||disrow==NULL) return ;
      IHTMLTableRow *pIRow;
      hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
      ASSERT(hr==S_OK);
      //get cell collection
      IHTMLElementCollection *rowcells;
      pIRow->get_cells(&rowcells);
      //get cell element
      IDispatch *discell;
      hr=rowcells->item(COleVariant(cci.iIndexInRow),COleVariant(short(0)),&discell);
      ASSERT(hr==S_OK&&discell!=NULL);
      
      hr=discell->QueryInterface(IID_IHTMLTableCell,(void **)&icell);
      ASSERT(hr==S_OK&&icell!=NULL);
      long       tmpRowSpan;
      hr=icell->get_rowSpan(&tmpRowSpan);
      ASSERT(hr==S_OK);
      rowSpan+=tmpRowSpan;
      if(i==beginrow)
      {
       ibegincell=icell;
      }else{
       icell->Release();          
       if(cci.iIndexInRow!=-1)
        pIRow->deleteCell(cci.iIndexInRow);
      }
      pIRow->Release();
     }
     ibegincell->put_rowSpan(rowSpan);
     ibegincell->Release();
    }

    //******************************************************************
    // 构造指定列的集合:内部函数
    //******************************************************************
    BOOL CSHTMLReport::MakeColDispatchCollection(
     IHTMLElementCollection *pIRowArray/*in*/,
     long iCol/*in*/,
     CSArray<COLCELLINFO> &colArray/*out*/)
    {
     long rows;
     HRESULT hr=pIRowArray->get_length(&rows);
     ASSERT(hr==S_OK);
     IHTMLElementCollection **rowcellsarray =new IHTMLElementCollection *[rows];

     //get cell collect array
     for(int j=0;j<rows;j++)
     {
      //get specisfied row
      IDispatch *disrow;
      hr=pIRowArray->item(COleVariant(long(j)),COleVariant(short(0)),&disrow);//iRow row
      if(hr!=S_OK||disrow==NULL) return FALSE;
      IHTMLTableRow *pIRow;
      hr=disrow->QueryInterface(IID_IHTMLTableRow, (void**)&pIRow);
      ASSERT(hr==S_OK);
      //get cell collection
      pIRow->get_cells(&rowcellsarray[j]);
      pIRow->Release();
     }
     
     struct colindexinfo{
      long index; //在行中的索引
      long iCol; //在列中的索引
      long colSpan;//列跨越
     };
     struct colindexinfo *ciis=new struct colindexinfo[rows];
     memset(ciis,0,rows*sizeof(struct colindexinfo));

     for(j=1;j<=iCol;j++)//追踪到第iCol列:初始化的数据即为第一列的数据,不需要计算
     {
      for(int k=0;k<rows;k++)
      {
       if(ciis[k].iCol+ciis[k].colSpan>j) continue;
       IDispatch *discell;
       hr=rowcellsarray[k]->item(COleVariant(ciis[k].index),COleVariant(short(0)),&discell);
       ASSERT(hr==S_OK&&discell!=NULL);
       IHTMLTableCell *icell;
       hr=discell->QueryInterface(IID_IHTMLTableCell,(void **)&icell);
       ASSERT(hr==S_OK&&icell!=NULL);
       long colSpan,rowSpan;
       hr=icell->get_colSpan(&colSpan);
       ASSERT(hr==S_OK);
       hr=icell->get_rowSpan(&rowSpan);
       icell->Release();

       ciis[k].index++;
       ciis[k].iCol+=colSpan;
       ciis[k].colSpan=colSpan-1;
       for(int kk=k+1;kk<k+rowSpan;kk++)
       {
        if(ciis[kk].iCol+ciis[kk].colSpan>j){
         delete []ciis;
         delete []rowcellsarray;
         return FALSE;
        }
        ciis[kk].iCol++;
        ciis[kk].colSpan=0;
       }
       k+=rowSpan-1;
      }
     }
     for(int i=0;i<rows;i++)
     {
      if(ciis[i].colSpan){
       COLCELLINFO cci={i,NULL,-1};
       colArray.Add(cci);
       continue;
      }
      IDispatch *discell;
      hr=rowcellsarray[i]->item(COleVariant(ciis[i].index),COleVariant(short(0)),&discell);
      ASSERT(hr==S_OK&&discell!=NULL);
      IHTMLTableCell *icell;
      hr=discell->QueryInterface(IID_IHTMLTableCell,(void **)&icell);
      ASSERT(hr==S_OK&&icell!=NULL);
      long rowSpan;
      hr=icell->get_rowSpan(&rowSpan);
      icell->Release();

      COLCELLINFO cci;
      cci.iRow=i;
      cci.iIndexInRow=ciis[i].index;
      cci.pDisCell=discell;
      colArray.Add(cci);
      i+=rowSpan-1;
     }
     delete []ciis;
     delete []rowcellsarray;
     return TRUE;
    }

     
  • 相关阅读:
    【题解】【BT】【Leetcode】Populating Next Right Pointers in Each Node
    【题解】【BT】【Leetcode】Binary Tree Level Order Traversal
    【题解】【BST】【Leetcode】Unique Binary Search Trees
    【题解】【矩阵】【回溯】【Leetcode】Rotate Image
    【题解】【排列组合】【素数】【Leetcode】Unique Paths
    【题解】【矩阵】【回溯】【Leetcode】Unique Paths II
    【题解】【BST】【Leetcode】Validate Binary Search Tree
    【题解】【BST】【Leetcode】Convert Sorted Array to Binary Search Tree
    第 10 章 判断用户是否登录
    第 8 章 动态管理资源结合自定义登录页面
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6157151.html
Copyright © 2011-2022 走看看