⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 easyreport.cpp

📁 这是一个不用任何控件的的纯VC报表源码。而且写得相当好!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	m_NumDataCols = inColCount;

	
	nRows = nMaxRows = 1;
	aLeft = m_LeftMargin;
	aMax = m_PageWidth - m_RightMargin;
	i = 0;
	do
	{
		m_TabStops.Add( (WORD)aLeft );
		aCol = inCols + i;
		aLeft += aCol->m_CharCount * m_TextSizes[eDataFont].cx;
		ASSERT(aLeft < aMax);	// check that we do not overflow the right edge

		// Calculate the height of this heading text...
		nRows = 1;
		s = aCol->m_Heading;
		if( s)
		{
			do
			{
				s = strchr(s,TCHAR('\n'));
				if(s==NULL)
					break;
				++s;		// past the '\n'
				++nRows;	// bump row count
			}
			while(1);
		}
		if( nRows > nMaxRows )
			nMaxRows = nRows;
		++i;
	}
	while(i < inColCount );
	m_TabStops.Add( (WORD)aLeft );
	m_TableHeadingHt = nMaxRows * m_TextSizes[ eColHeadingFont ].cy;

	if( !m_SuppressBlankTbl )
	{
		// We need to draw the heading. Check if there is enough room
		// on this page to draw the headings.
		if( m_DataTop + m_TableHeadingHt + GetDataFontSize().cy > (GetBottomEdge() - m_PageFtrHt) )
			EjectPage(false);
		if( !m_RepeatTblHdr )
			WriteTableHeader();
	}
	else
	{
		// deffer drawing the columns till something is written to this table
		m_RedrawTblHdr = true; 
	}
}




/*****************************************************************
 * 
 * method :void	CEasyReport::EjectPage(bool inIsLastPage)
 *
 * parameters : inIsLastPage : true if this is the last page
 * of the report.
 *
 * returns : nothing
 *
 * description: Call this function to eject the current page. if this
 * is the last page, we print the report footer. If there
 * is a page footer defined, it will be printed before starting the 
 * new page. 
 *
 ****************************************************************/
bool	CEasyReport::EjectPage(bool inIsLastPage)
{
	CRect	aRect;
	int		aRequiredHt, aAbsBottom;
	bool	aAllPrinted = true;


	aRect.left = m_LeftMargin;
	aRect.right = m_PageWidth - m_RightMargin;
	aAbsBottom = m_PageHeight - m_BottomMargin;

	if(inIsLastPage)
	{
		// check to see if the PageFooter and the ReportFooter 
		// will fit on to the remaining area on this page. If so, 
		// print the page footer and the report footer. 
		aRequiredHt = m_PageFtrHt + m_ReportFtrHt;
		if( m_DataTop + aRequiredHt <= aAbsBottom )
		{
			aRect.top = aAbsBottom - (m_PageFtrHt+ m_ReportFtrHt);
			aRect.bottom = aRect.top + m_PageFtrHt;
			WritePageFooter(aRect);
			if( m_ReportFtrHt)
			{
				aRect.top = aRect.bottom;
				aRect.bottom += m_ReportFtrHt;
				WriteReportFooter(aRect);
			}
		}
		else
		{
			aRect.top = aAbsBottom - m_PageFtrHt;
			aRect.bottom = aRect.top + m_PageFtrHt;
			WritePageFooter(aRect);
			aAllPrinted = (m_ReportFtrHt >0 ? false : true);
		}
	}
	else
	{
		// not the last page of the report. Simply draw the page 
		// footer bottom aligned on the page
		if(m_PageFtrHt > 0 )
		{
			// bottom align the page footer on the page
			aRect.top = aAbsBottom - m_PageFtrHt;
			aRect.bottom = aRect.top + m_PageFtrHt;
			WritePageFooter(aRect);
		}
	}

	m_PageItems.Add(m_ReportItems.GetSize());
	++m_PageCount;

	m_DataTop = m_TopMargin;

	// If not the last page, then print the page header if there
	// is a page header.
	if( !inIsLastPage && m_PageHdrHt > 0 )
	{
		aRect.top = m_DataTop;
		aRect.bottom = aRect.top + m_PageHdrHt;
		WritePageHeader(aRect);
		m_DataTop += m_PageHdrHt;
	}

	// Print the table header only if needed
	// m_RedrawTblHdr = false;	
	if( !inIsLastPage && m_RepeatTblHdr && m_NumDataCols != 0 )
	{
		if( !m_SuppressBlankTbl )
			WriteTableHeader();
		else
			m_RedrawTblHdr = true;
	}
	return aAllPrinted;
}



/*****************************************************************
 * 
 * method :void	CEasyReport::WriteTableHeader(void)
 *
 * parameters : 
 *
 * returns : 
 *
 * description: If a tabular section is in place, write the table
 * header.
 *
 ****************************************************************/
void	CEasyReport::WriteTableHeader(void)
{
	int		i;
	CRect	aRect;

	m_RedrawTblHdr = false;
	aRect.top = aRect.bottom = m_DataTop;
	aRect.bottom += m_TableHeadingHt;
	aRect.left= m_LeftMargin;
	for(i=0;i < m_NumDataCols; i++)
	{
		CColInfo	*aCol = m_DataCols+i;
		aRect.right = aRect.left + aCol->m_CharCount * m_TextSizes[eDataFont].cx;
		CTextBox	*aBox = new CTextBox(&aRect, aCol->m_Heading, eColHeadingFont);
		switch( aCol->m_align)
		{
			case CColInfo::eLeft:
				aBox->SetAlign(DT_LEFT);
				break;
			case CColInfo::eDecimal:
			case CColInfo::eRight:

				// for fixed width fonts, if you control the format of data, then
				// simply aligning the text right aligns the decimal places. For 
				// propotional fonts, you will have to adjust the left edge of
				// the box. Decimal cols will be supported in a later version

				aBox->SetAlign(DT_RIGHT);
				break;
			case CColInfo::eCenter:
				aBox->SetAlign( DT_CENTER );
				break;
		}

		aBox->SetDocPtr(this);
		m_ReportItems.Add(aBox);
		aRect.left = aRect.right;
	}
	m_DataTop += m_TableHeadingHt;
}

/*****************************************************************
 * 
 * method :void	CEasyReport::NextRow()
 *
 * parameters : 
 *
 * returns : 
 *
 * description: Advance the current point by one row height
 * If this moves the current point below the page margin, call 
 * EjectPage. EjectPage will automatically write the page footer 
 * and start a new page
 *
 ****************************************************************/
void	CEasyReport::NextRow()
{
	m_DataTop += m_TextSizes[eDataFont].cy;
	// see if at least one data row will fit into the remaining
	// space on the page. If it does not, call EjectPage
	if( m_DataTop + m_TextSizes[eDataFont].cy + m_PageFtrHt > GetBottomEdge())
		EjectPage();
}


/*****************************************************************
 * 
 * method :void	CEasyReport::Start(void)
 *
 * parameters : none
 *
 * returns : 
 *
 * description: Start the report generation. Create all the fonts, etc
 * Try and get the printer device context, If no printer is set up as 
 * the default printer on the system, create a screen device context. 
 *
 ****************************************************************/
void	CEasyReport::Start()
{

	ASSERT( m_PrinterDC == NULL );
	DoCleanup();
	
	// set up a print date ..
	CTime		aNow = CTime::GetCurrentTime();
	m_ReportDate.Format("Date: %2d/%2d/%4d", aNow.GetMonth(), aNow.GetDay(), aNow.GetYear());

	// NOTE: The following is most certainly not correct if there is 
	// no default printer defined ! If you do not have ANY printer, then
	// you might install a Fax printer (eg Microsoft Fax or Bitware etc)
	CPrintDialog	aPD(false);

	if(aPD.GetDefaults())
	{
		m_PrinterDC = aPD.m_pd.hDC;
	}
	else
	{
		m_PrinterDC = ::GetDC(NULL);	// get the screen device context
	}

	//::SetMapMode(m_PrinterDC, MM_ANISOTROPIC);
	//::SetWindowExtEx( m_PrinterDC, 254,254,NULL);
	//::SetViewportExtEx(m_PrinterDC, GetDeviceCaps(m_PrinterDC,LOGPIXELSX),GetDeviceCaps(m_PrinterDC,LOGPIXELSY),NULL);
	SetMapMode( m_PrinterDC, MM_LOMETRIC);
	SetupTextStyles( m_PrinterDC );

	m_DataTop = m_TopMargin;
	m_PageCount = 0;
	m_CurPage = 0;

	CRect		aRect;

	// Write the report header...
	if( m_ReportHdrHt > 0 )
	{
		aRect.SetRect(m_LeftMargin, m_TopMargin, m_PageWidth - m_RightMargin,m_TopMargin + m_ReportHdrHt );

		aRect.bottom = aRect.top + m_ReportHdrHt;
		WriteReportHeader(aRect);
		m_DataTop += m_ReportHdrHt;
	}

	if( m_PageHdrHt > 0)
	{
		aRect.SetRect(m_LeftMargin, m_DataTop, m_PageWidth - m_RightMargin, m_DataTop + m_PageHdrHt);
		WritePageHeader(aRect);
		m_DataTop += m_PageHdrHt;
	}
}

/*****************************************************************
 * 
 * method :void		CEasyReport::End()
 *
 * parameters : 
 *
 * returns : 
 *
 * description: End the report
 *
 ****************************************************************/
void		CEasyReport::End()
{
	EjectPage(true);
	m_CurPage = 0;

	DeleteDC(m_PrinterDC);
}



/*****************************************************************
 * 
 * method :void		WriteReportHeader(CRect inRect)
 *
 * parameters : 
 *
 * returns : 
 *
 * description: Write the default report header, which is a 
 * simply the CompanyName centered across the page. You might 
 * want to add the address, etc.
 *
 ****************************************************************/
void	CEasyReport::WriteReportHeader(CRect inRect)
{
	CTextBox	*aBox = new CTextBox(&inRect, m_CompanyName, eCaptionFont, DT_CENTER);
	aBox->SetDocPtr(this);
	m_ReportItems.Add(aBox);

}

/*****************************************************************
 * 
 * method :void	CEasyReport::WriteReportFooter(CRect inRect)
 *
 * parameters : 
 *
 * returns : 
 *
 * description: Write the report footer. The default Report footer
 * is blank.
 *
 *
 ****************************************************************/
void	CEasyReport::WriteReportFooter(CRect inRect)
{
//	CTextBox	*aBox = new CTextBox(&inRect, "Report Footer", eCaptionFont);
//	aBox->SetDocPtr(this);
//	m_ReportItems.Add(aBox);
}

/*****************************************************************
 * 
 * method :void		WritePageHeader(CRect inRect)
 *
 * parameters : 
 *
 * returns : 
 *
 * description: Write the default page header. By default, this
 * contains the report title (centered) and date field, 
 * right aligned
 *
 ****************************************************************/
void	CEasyReport::WritePageHeader(CRect inRect)
{
	CRect		aRect(inRect);
	CTextBox	*aBox;

	aRect.bottom = aRect.top + GetHeadingFontSize().cy;
	aBox = new CTextBox(&aRect,m_ReportTitle,eColHeadingFont);
	aBox->SetDocPtr(this);
	m_ReportItems.Add(aBox);

	// make a text area 1/4 of the page width
	aRect.right = inRect.right;
	aRect.left = inRect.right - inRect.Width()/4;
	aBox = new CTextBox(&aRect, m_ReportDate, eColHeadingFont, DT_LEFT);
	aBox->SetDocPtr(this);
	m_ReportItems.Add(aBox);

	aRect.top = inRect.bottom-10;	// 1mm from the bottom
	aRect.bottom = inRect.bottom;
	aRect.left = inRect.left;
	aRect.right = inRect.right;
	CHline	*aLine = new CHline(&aRect,0);
	aLine->SetDocPtr(this);
	m_ReportItems.Add(aLine);
}

/*****************************************************************
 * 
 * method :void	CEasyReport::WritePageFooter(CRect inRect)
 *
 * parameters : 
 *
 * returns : 
 *
 * description: Write the page footer
 *
 ****************************************************************/
void	CEasyReport::WritePageFooter(CRect inRect)
{
	CRect	aRect(inRect);

	aRect.top = aRect.bottom = inRect.top +10;	// 1mm below 
	CHline	*aLine = new CHline(&aRect,0);
	aLine->SetDocPtr(this);
	m_ReportItems.Add(aLine);

	aRect.top += 10;	// 1mm
	aRect.bottom = aRect.top + GetHeadingFontSize().cy;
	CPageNum	*aPgNumField = new CPageNum(&aRect,eColHeadingFont);
	aPgNumField->SetDocPtr(this);
	m_ReportItems.Add(aPgNumField);
}



/*****************************************************************
 * 
 * method :void		DrawCurrentPage(CDC *inDC)
 *
 * parameters : inCDC a device context
 *
 * returns : nothing
 *
 * description: Draw the current page
 *
 *
 ****************************************************************/
void		CEasyReport::DrawCurrentPage(CDC *inDC)
{
	int			i,aStart, aMax;
	CElement	*aElem;
	
	if( m_CurPage != 0 )
		aStart = m_PageItems[m_CurPage-1];
	else
		aStart = 0;
	aMax = m_PageItems[m_CurPage];
	for( i =aStart;i< aMax;i++)
	{
		aElem = (CElement *)m_ReportItems[i];
		aElem->Draw(inDC);
	}


/*	
	CRect	aRect(m_LeftMargin, -m_TopMargin, 
				m_PageWidth - m_RightMargin, -(m_PageHeight-m_BottomMargin));
	inDC->MoveTo(aRect.left, aRect.top);
	inDC->LineTo(aRect.right,aRect.top);
	inDC->LineTo(aRect.right, aRect.bottom);
	inDC->LineTo(aRect.left, aRect.bottom);
	inDC->LineTo(aRect.left, aRect.top);
*/	
}


/*****************************************************************
 * 
 * method :const CFont	*GetStyle(int inStyleIndex)
 *
 * parameters : inStyleIndex: integer 
 *
 * returns : CFont *
 *
 * description: Return a pointer to the font, NULL if the index
 * is out of range.
 *
 *
 ****************************************************************/
const CFont	*CEasyReport::GetStyle(int inStyleIndex)
{
	ASSERT(inStyleIndex >=0 && inStyleIndex < eMaxStyles );
	if( inStyleIndex < eMaxStyles )
		return m_Fonts[ inStyleIndex ];
	else
		return NULL;
}



//**** end of EasyReport.cpp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -