无需导入com组件,无需绑定Datatable,将 listview 声明为此类的实例,再直接调用 doprint()方法就可以进行打印了,非常方便简单。
下面是源代码:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing .Printing ;
using System.Windows.Forms;
namespace LogOperator.Class
{
public class PrintListView : ListView
{
/// <summary>
/// 指示是否进行打印预览,默认值为 true
/// </summary>
private bool m_bIsPreview;
/// <summary>
/// 指示是否总是打印标题,默认值为 true
/// </summary>
private bool m_bIsAlwaysPrintHeader;
/// <summary>
/// 需要打印的页首字符串
/// </summary>
private string m_sPrintHeaderString;
/// <summary>
/// 标题的字体
/// </summary>
private Font m_oHeaderFont;
/// <summary>
/// 正文字体
/// </summary>
private Font m_oBodyFont;
/// <summary>
/// 页尾字体
/// </summary>
private Font m_oTailFont;
/// <summary>
/// 正文部分的 ColumnHeader 字体,该字体为正文字体的加粗形式
/// </summary>
private Font m_oColumnHeaderFont;
/// <summary>
/// 打印文档
/// </summary>
private PrintDocument m_oPrintDoc;
/// <summary>
/// 行间距
/// </summary>
private int m_nLineSpace ;
private int m_nPrintWidth; // 打印区域宽度
private int m_nPrintHeight; // 打印区域长度
private int m_nPageCount; // 打印页数
private int m_nCurPrintPage; // 当前正在打印的页码
private int m_nTotalPage; // 共有的页数
private int m_nFromPage; // 用户选择的打印起始页
private int m_nCurPrintItem; // 当前正在打印的元素
private Rectangle m_oHeaderRect; // 打印页首的区域
private Rectangle m_oBodyRect; // 打印正文的区域
private Rectangle m_oTailRect; // 打印页尾的区域
private Brush defaultBrush;
private Pen defaultPen;
/// <summary>
/// 设置或获取是否进行打印预览
/// </summary>
public bool IsPreview {
get { return m_bIsPreview;}
set { m_bIsPreview = value;}
}
/// <summary>
/// 设置或获取是否总是打印标题
/// </summary>
public bool IsAlwaysPrintHeader {
get { return m_bIsAlwaysPrintHeader;}
set { m_bIsAlwaysPrintHeader = value;}
}
/// <summary>
/// 设置或获取打印的页首字符串
/// </summary>
public string PrintHeaderString {
get { return m_sPrintHeaderString ;}
set { if (value != null ) m_sPrintHeaderString = value;}
}
/// <summary>
/// 设置或获取页首字体
/// </summary>
public Font HeaderFont {
set { m_oHeaderFont = value;}
get { return m_oHeaderFont;}
}
/// <summary>
/// 设置或获取正文字体
/// 如果对正文字体的 Bold 属性设置为 true ,则发生 Exception 类型的异常
/// </summary>
public Font BodyFont {
set{
if ( value == null )
return ;
if (value.Bold == true ){
//throw new Exception ("正文字体不能进行 [加粗] 设置.");
MessageBox.Show("正文字体不能进行 [加粗] 设置.","警告",MessageBoxButtons.OK,MessageBoxIcon.Warning);
return;
}else{
m_oBodyFont = value;
}
}
get { return m_oBodyFont;}
}
/// <summary>
/// 设置或获取页尾字体
/// </summary>
public Font TailFont {
set { m_oTailFont = value;}
get { return m_oTailFont;}
}
/// <summary>
/// 设置或获取行间距
/// </summary>
public int LineSpace{
get { return m_nLineSpace;}
set {
if ( value < 0 ){
m_nLineSpace = 0;
}
m_nLineSpace = value;
}
}
/// <summary>
/// 构造函数,设置打印信息的一些默认值
/// </summary>
public PrintListView() {
m_bIsPreview = true;
m_bIsAlwaysPrintHeader = true;
IsAlwaysPrintHeader=true;
m_sPrintHeaderString = "";
m_oHeaderFont = null;
m_oTailFont = null;
m_oBodyFont = null;
m_oColumnHeaderFont = null;
m_oPrintDoc = null;
m_nPrintWidth = 0;
m_nPrintHeight = 0;
m_nPageCount = 0;
m_nCurPrintPage = 1;
m_nFromPage = 1;
m_nLineSpace = 0;
m_nCurPrintItem = 0;
defaultBrush = Brushes.Black ;
defaultPen = new Pen ( defaultBrush,1 );
}
/// <summary>
/// 初始化打印文档的属性
/// </summary>
/// <returns></returns>
private void InitPrintDocument () {
m_oPrintDoc = new PrintDocument ();
m_oPrintDoc.DocumentName = m_sPrintHeaderString;
if (m_oPrintDoc.PrinterSettings.PrinterName == "<no default printer>"){
//throw new Exception ("未找到默认打印机.");
MessageBox.Show("未找到默认打印机.","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
return;
} else {
m_oPrintDoc.PrintPage +=new PrintPageEventHandler(PrintPage);
m_oPrintDoc.BeginPrint +=new PrintEventHandler(BeginPrint);
m_oPrintDoc.EndPrint +=new PrintEventHandler(EndPrint);
}
/* 设置打印字体 */
if ( m_oHeaderFont == null ){
m_oHeaderFont = new Font ("宋体",24,FontStyle.Bold,GraphicsUnit.World );
}
if ( m_oBodyFont == null ) {
m_oBodyFont = new Font ("宋体",20,FontStyle.Regular ,GraphicsUnit.World );
}
m_oColumnHeaderFont = new Font (m_oBodyFont,FontStyle.Bold );
if ( m_oTailFont == null ) {
m_oTailFont = new Font ("宋体",14,FontStyle.Regular ,GraphicsUnit.World );
}
}
/// <summary>
/// 初始化打印纸张设置
/// </summary>
private bool InitPrintPage (out Margins margins) {
margins = null;
/* 获取当前 listview 的分辨率 */
Graphics g = this.CreateGraphics ();
float x = g.DpiX ;
g.Dispose ();
/* 显示纸张设置对话框 */
PageSetupDialog ps = new PageSetupDialog ();
ps.Document = m_oPrintDoc;
if ( ps.ShowDialog () == DialogResult.Cancel ) {
return false;
} else { // 根据用户设置的纸张信息计算打印区域,计算结果的单位为 1/100 Inch
m_nPrintWidth = ps.PageSettings .Bounds .Width - ps.PageSettings .Margins .Left - ps.PageSettings .Margins .Right ;
m_nPrintHeight = ps.PageSettings .Bounds .Height - ps.PageSettings .Margins .Top - ps.PageSettings .Margins .Bottom ;
margins = ps.PageSettings .Margins ;
}
if ( m_nPrintWidth <= 0 || m_nPrintHeight <= 0 ) {
//throw new Exception ("纸张设置错误.");
MessageBox.Show("纸张设置错误.","提示",MessageBoxButtons.OK,MessageBoxIcon.Warning);
return false;
}
/* 将当前 listview 的各column的长度和转换为英寸,判断打印范围是否越界 */
int listViewWidth = 0;
for ( int i = 0 ; i < this.Columns.Count ; i ++ ) {
listViewWidth += this.Columns [i].Width ;
}
if ( Convert.ToInt32 ( listViewWidth / x * 100 ) > m_nPrintWidth ) {
//throw new Exception ("打印内容超出纸张范围 !/r/n请尝试调整纸张或纸张边距;/r/n或缩小表格各列的宽度。");
MessageBox.Show("打印内容超出纸张范围 !/r/n请尝试调整纸张或纸张边距;/r/n或缩小表格各列的宽度。","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
return false;
}
m_oPrintDoc.DefaultPageSettings = ps.PageSettings ;
return true;
}
/// <summary>
/// 初始化打印页码设置
/// </summary>
private bool InitPrintPageNumber(Margins margins) {
/* 计算页数 */
int headerFontHeight = m_oHeaderFont.Height ;
int columnHeaderFontHeight = m_oColumnHeaderFont.Height ;
int bodyFontHeight = m_oBodyFont.Height ;
int tailFontHeight = m_oTailFont.Height ;
// 页首区域打印 页首字符串 以及一条横线
m_oHeaderRect = new Rectangle ( margins.Left ,margins.Top ,m_nPrintWidth,headerFontHeight + m_nLineSpace + 3);
int tailHeight = tailFontHeight + m_nLineSpace + 3;
// 页尾区域打印 一条横线,页码和打印时间(在同一行)
m_oTailRect = new Rectangle ( margins.Left ,margins.Top + m_nPrintHeight - tailHeight,m_nPrintWidth,tailHeight);
//正文区域为去掉页首和页尾区域的部分
m_oBodyRect = new Rectangle ( margins.Left ,m_oHeaderRect.Bottom + 2,m_nPrintWidth,m_oTailRect.Top - m_oHeaderRect.Bottom - 4 );
/* 计算第一页能打印的元素个数 */
int printItemPerPage = 0;
int firstPageItem = Convert.ToInt32 ( (m_oBodyRect.Height - columnHeaderFontHeight - m_nLineSpace) /(bodyFontHeight + m_nLineSpace ));
if ( firstPageItem >= this.Items .Count ){ // 需打印的元素只有一页
m_nPageCount = 1;
} else { // 需要打印的元素有多页
printItemPerPage = firstPageItem;
int leftItems = this.Items .Count - firstPageItem;
if ( m_bIsAlwaysPrintHeader == false ){
printItemPerPage =( m_oBodyRect.Height + m_oHeaderRect.Height + 2 - columnHeaderFontHeight - m_nLineSpace) / ( bodyFontHeight + m_nLineSpace);
}
if ( leftItems % printItemPerPage == 0 ){
m_nPageCount = leftItems / printItemPerPage + 1;
} else {
m_nPageCount = leftItems / printItemPerPage + 2;
}
}
m_nTotalPage = m_nPageCount;
/* 显示打印对话框 */
PrintDialog pd = new PrintDialog ();
pd.Document = m_oPrintDoc;
pd.PrinterSettings .MinimumPage = 1;
pd.PrinterSettings .MaximumPage = m_nPageCount;
pd.PrinterSettings .FromPage = 1;
pd.PrinterSettings .ToPage = m_nPageCount;
pd.AllowPrintToFile = false; // 不设置打印到文件
if ( m_nPageCount > 1 ){
pd.AllowSelection = true;
} else {
pd.AllowSelection = false ;
}
pd.AllowSomePages = true;
if ( pd.ShowDialog ()== DialogResult.OK ){
m_nPageCount = pd.PrinterSettings .ToPage - pd.PrinterSettings .FromPage + 1;
if ( pd.PrinterSettings .FromPage > 1 ) {
m_nCurPrintItem = firstPageItem + ( pd.PrinterSettings .FromPage -2 )* printItemPerPage ;
} else {
m_nCurPrintItem = 0 ;
}
m_nFromPage = pd.PrinterSettings .FromPage ;
m_oPrintDoc.DocumentName = m_nPageCount.ToString ();
m_oPrintDoc.PrinterSettings = pd.PrinterSettings ;
return true;
}else{
return false;
}
}
/// <summary>
/// 启动 ListView 的打印工作
/// </summary>
public virtual void DoPrint ( ) {
if ( this.Items.Count <= 0 ) {
//throw new Exception ("没有需要打印的元素.");
MessageBox.Show("没有需要打印的元素.","提示",MessageBoxButtons.OK,MessageBoxIcon.Information);
return;
}
InitPrintDocument ();
Margins margins = null;
if (InitPrintPage( out margins ) == false )
return;
if ( InitPrintPageNumber( margins )== false )
return;
if ( m_bIsPreview == false ) {
m_oPrintDoc.Print ();
} else {
PrintPreviewDialog pd = new PrintPreviewDialog();
pd.Document = m_oPrintDoc;
pd.PrintPreviewControl.Zoom = 1.0;
pd.WindowState = FormWindowState.Maximized;
pd.ShowInTaskbar = true;
pd.ShowDialog ();
}
}
/// <summary>
/// 打印页首
/// </summary>
/// <param name="g"></param>
protected virtual void PrintPageHeader(Graphics g){
RectangleF textRect = new RectangleF (m_oHeaderRect.X ,m_oHeaderRect.Y ,m_oHeaderRect.Width ,m_oHeaderRect.Height - 3 );
CenterText(g,m_sPrintHeaderString,m_oHeaderFont,defaultBrush,textRect );
g.DrawLine (defaultPen,m_oHeaderRect.X ,m_oHeaderRect.Bottom -2 ,m_oHeaderRect.Right ,m_oHeaderRect.Bottom - 2);
}
/// <summary>
/// 打印正文
/// </summary>
/// <param name="g"></param>
protected virtual void PrintPageBody( Graphics g ) {
Rectangle textRect = m_oBodyRect;
if ( m_bIsAlwaysPrintHeader == false && m_nCurPrintPage != 1 ) {
textRect = new Rectangle ( m_oHeaderRect.X ,m_oHeaderRect.Y ,m_oHeaderRect.Width ,m_oHeaderRect.Height + 2 + m_oBodyRect.Height );
}
/* 打印标题,也就是 columnHeader */
int columnHeaderFontHeight = m_oColumnHeaderFont.Height ;
int bodyFontHeight = m_oBodyFont.Height ;
Rectangle columnHeaderRect = new Rectangle (textRect.X ,textRect.Y ,textRect.Width ,columnHeaderFontHeight + m_nLineSpace );
DrawColumnHeader(g,m_oColumnHeaderFont,defaultBrush,columnHeaderRect);
/* 打印元素 */
int itemHeight = bodyFontHeight + m_nLineSpace;
Rectangle itemRect;
int yPos = columnHeaderRect.Bottom ;
int printItemPerPage = ( textRect.Height - columnHeaderRect.Height ) / ( bodyFontHeight + m_nLineSpace);
for ( int i = 0 ; (i < printItemPerPage) && (m_nCurPrintItem < this.Items .Count ); i ++ ) {
itemRect = new Rectangle (textRect.X ,yPos,textRect.Width ,itemHeight);
DrawItem(g,m_oBodyFont,defaultBrush,itemRect );
m_nCurPrintItem ++;
yPos += itemHeight;
}
}
/// <summary>
/// 打印页尾
/// </summary>
/// <param name="g"></param>
protected virtual void PrintPageTail ( Graphics g ){
g.DrawLine (defaultPen,m_oTailRect.X,m_oTailRect.Top +1,m_oTailRect.Right ,m_oTailRect.Top +1);
RectangleF textRect = new RectangleF (m_oTailRect.X ,m_oTailRect.Y+ 3 ,m_oTailRect.Width ,m_oTailRect.Height -3);
string text = "第 "+ m_nFromPage.ToString ()+" 页 共 "+ m_nTotalPage.ToString () + " 页";
m_nFromPage ++ ;
CenterText(g,text,m_oTailFont,defaultBrush,textRect );
string time = "打印时间:"+DateTime.Now.ToLongDateString ()+" ";
RightText(g,time,m_oTailFont,defaultBrush,textRect);
}
/// <summary>
/// 打印一页
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PrintPage(object sender, PrintPageEventArgs e) {
e.Graphics.PageUnit = GraphicsUnit.Inch;
e.Graphics.PageScale = .01f;
if ( m_bIsAlwaysPrintHeader == true ) {
PrintPageHeader ( e.Graphics );
} else {
if ( m_nCurPrintPage == 1 ) {
PrintPageHeader ( e.Graphics );
}
}
PrintPageBody( e.Graphics );
PrintPageTail ( e.Graphics );
if ( m_nCurPrintPage == m_nPageCount ){
e.HasMorePages = false;
} else {
e.HasMorePages = true;
}
m_nCurPrintPage ++;
}
/// <summary>
/// 打印前的初始化设置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BeginPrint(object sender, PrintEventArgs e){
m_nCurPrintPage = 1;
}
/// <summary>
/// 打印结束后的资源释放
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void EndPrint(object sender, PrintEventArgs e) {
}
/// <summary>
/// 居中显示文本信息
/// </summary>
private void CenterText(Graphics g, string t, Font f, Brush b, RectangleF rect) {
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
g.DrawString(t, f, b, rect, sf);
}
/// <summary>
/// 居右显示文本信息
/// </summary>
private void RightText (Graphics g, string t, Font f, Brush b, RectangleF rect){
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Far ;
sf.LineAlignment = StringAlignment.Center;
g.DrawString(t, f, b, rect, sf);
}
/// <summary>
/// 居左显示文本信息
/// </summary>
private void LeftText (Graphics g, string t, Font f, Brush b, RectangleF rect){
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near ;
sf.LineAlignment = StringAlignment.Center;
g.DrawString(t, f, b, rect, sf);
}
/// <summary>
/// 打印 listview 的 columnheader
/// </summary>
private void DrawColumnHeader ( Graphics g,Font f,Brush b,Rectangle rect ){
StringFormat sf = new StringFormat ();
sf.Alignment = StringAlignment.Center ;
sf.LineAlignment = StringAlignment.Center ;
Rectangle itemRect;
Point location = new Point (rect.Location.X ,rect.Location .Y );
Size itemSize ;
for ( int i = 0 ;i < this.Columns .Count ;i ++ ){
itemSize = new Size (this.Columns [i].Width ,rect.Height );
itemRect = new Rectangle ( location,itemSize );
g.DrawRectangle (defaultPen,itemRect);
g.DrawString (this.Columns [i].Text ,f,b,itemRect,sf);
location.X += this.Columns [i].Width ;
}
}
/// <summary>
/// 打印 listview 的 item
/// </summary>
private void DrawItem ( Graphics g,Font f,Brush b,Rectangle rect ) {
StringFormat sf = new StringFormat ();
sf.Alignment = StringAlignment.Near ;
sf.LineAlignment = StringAlignment.Center ;
Rectangle itemRect;
Point location = new Point (rect.Location.X ,rect.Location .Y );
Size itemSize ;
for ( int i = 0 ;i < this.Columns .Count ;i ++ ) {
itemSize = new Size (this.Columns [i].Width ,rect.Height );
itemRect = new Rectangle ( location,itemSize );
g.DrawRectangle (defaultPen,itemRect);
g.DrawString (this.Items [m_nCurPrintItem].SubItems [i].Text ,f,b,itemRect,sf);
location.X += this.Columns [i].Width ;
}
}
}
}