# 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 ()
{
}
//************************************** *********
// Specify the HTML Document Interface
//************************************** ********
Void cshtmlreport: sethtmldocptr (ihtmldocument2 * pdoc)
{
M_phtmldoc2 = pdoc;
}
//************************************** *********
// Specify the name of the operation table, which is specified in the HTML Template
//************************************** *******
Void cshtmlreport: settablename (cstring name)
{
M_strtablename = Name;
}
//************************************** ************
// Obtain the HTML table COM interface and the internal interface
//************************************** ************
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;
}
//************************************** *****************
// Insert a row at the specified position. Index =-1 indicates 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 = "& nbsp ;";
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;
}
//************************************** *************************
// Modify the cell content: You can use the HTML syntax.
//************************************** *************************
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
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;
}
//************************************** **********
// Delete a specified row
//************************************** **********
Bool cshtmlreport: deleterow (INT index)
{
Ihtmltable * pitable = gettabledispatch ();
Hresult hR = pitable-> deleterow (INDEX );
Pitable-> release ();
Return hR = s_ OK;
}
//************************************** **********
// Merge cells with the same row data
//************************************** **********
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;
}
//************************************** **********
// Merge cells with the same data in the specified Column
//************************************** **********
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;
}
//************************************** *********
// Set the display format of the index column: Follow the sprintf function rules
//************************************** *********
Void cshtmlreport: setindexformat (cstring strindexformat)
{
M_strindexformat = strindexformat;
}
//************************************** ***********
// Obtain the characters of the element
//************************************** ***********
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;
}
//************************************** ******************
// Set element characters
//************************************** *****************
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 );
}
//************************************** ****************************
// Merge from the specified start and end positions in the specified row: internal function
//************************************** ****************************
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 ();
}
}
//************************************** ****************************
// Merge the specified columns from the specified start and end positions in the specified row set: internal function
//************************************** ****************************
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 ();
}
//************************************** ****************************
// Construct a set of specified columns: internal functions
//************************************** ****************************
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; // The index in the row.
Long icol; // index in the column
Long colspan; // Column Crossing
};
Struct colindexinfo * ciis = new struct colindexinfo [rows];
Memset (ciis, 0, rows * sizeof (struct colindexinfo ));
For (j = 1; j <= icol; j ++) // trace to column icol: The initialized data is the data in the first column, which does not need to be calculated.
{
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;
}