VS打印思想

前言

  当.NET时代到来时,我们在高兴激动的时候,把自己的系统升级到.NET或是用它开发新的系统。

  打印--管理信息系统永恒的话题。于是,我们在开发业务系统的时候不得不再专门做一个打印组件或是购买一个中间件完成单据合同、清单、文档、工资单、报表等等的打印。


在开始之前,如果您还想了解更多关于打印的信息,可以查看我曾经写的一篇技术文档:
NET环境下有关打印页面设置、打印机设置、打印预览对话框的实现及应用,二次封装了.NET类库的打印页面设置、打印机设置、打印预览对话框。对于想了解VB.NET与C#打印分页原理与实现的朋友有一些益处,应用封装后的dll开发的示例实现了一个完整的文档打印。
此文曾经被CSDN主页收录为头条精华,从本文的最后部分的相关资源中可以找到它的链接及源码。

历史的天空

  当你还在兴奋为自己在网上找到了一个打印程序完成DataGrid的打印的时候,当你还在高高兴兴的跟着微软走的时候,2005年12月2日的这一天,MS在北京奥体中心以“Ready To Rock 撼动未来”为主题发布了SQLServer2005、Visual Studio2005和BizTalkServer2006三个重量级产品。

  MS的Fans热烈欢呼庆幸,快快欢迎新时代的到来吧。

  当你打安装了VS2005后,当你打开IDE的时候,当你找ToolBox的时候,你会发现,DataGrid悄然的离开了我们的视线。不要奇怪,经典的ToolBar都被取代了,人家都是Window元老了,DataGrid才几年时间?该退下来就退下来,让年轻有为的上去嘛。

  DataGrid光荣的退居二线了,只是为了兼容,要不然,估计就得养老了,还要它继续以前它完成的任务呢。MS建议使用DataGridView,不要惊诧,DataGridView无论是在界面上还是在功能上还是在控件的设计时支持上,确实比DataGrid强多了。你大可不必再对那个双击啊、单击啊、选择多个单元格等等一系列烦恼了。单元格操作选择上很像EXCEL,还有了固定列(冻结列),有了这句话,估计您这下放心了吧。

打印思想:以不变应万变

  很多打印程序,都是针对特定的网格控件如DataGrid打印,这一下,当VS2005隆重登录的时候,当DataGridView登上宝座的时候,我们的打印程序还能用吗?

   回答是肯定的,只要您使用的打印核心是针对二维数据的打印。无论它是VB6的MSHFlexGrid,还是VB5的DBGrid...,还是VS.NET2002/3/5的DataGrid,还是现在新登场DataGridView,打印它们,还不是件简单的事情?

  还有人说,我想打印ListView?没关系,写一个把ListView导出到二维数组的程序就搞定了,一切照样,即使是DataTable、Asp.NET的DataGrid、GridView,一样轻松搞定它。

  总之,实现网格、报表的打印,你要把握这个思想:
  打印单元格文本,加上绘制线,就组成了网格,多个网格就组成了报表、单据等。

  也许您还要问上一句:
  那么打印文本呢?哈哈,还是网格,只是一行一列,不用绘制网格线。

  也许有人要还要问:
  我的报表或单据合同之类的太复杂了,能实现吗?回答是肯定的,我们可以通过组合多个网格,合并网格的单元格进行实现。

  总之,四个字:二维打印,也就是,无论你是往前走还是往后看,以不变应万变。往前走怎么说?也就是即使你还留念VB6的MSHFlexGrid,没关系,添加它的引用,照样在.NET窗口中可以使用它,它也是二维的,应用上面的方法,照打不误。往后看怎么解?也就是说如果你还在使用VS2002、2003,那么以后用VS2005也可以打印DataGridView啊?再进一步,哪一天MS把DataGridView用新的网格取代了或者你自己开发一个或三方网格取代了它,还是那句话,照打不误,以不变应万变。

打印精髓

  二维数据及网格的绘制,无非就是绘制单元格文本及网格线,接下来我将给出具体的实现,你可以自己封装并修改它。至于成型的架构,从本文的最后部分的相关资源中可以找到它的链接及源码。下载源码

    核心是DrawGrid网格,亮点是合并打印算法,因此把源码列出来!

#region 画标准横坚网格线核心
/// <summary>
/// 画网格线,标准备的横竖线交叉的线
/// </summary>
/// <param name="g">绘图表面</param>
/// <param name="p_rec">绘图区</param>
/// <param name="p_pen">绘图线的笔,可以定义颜色与线宽</param>
/// <param name="p_rows">行数</param>
/// <param name="p_cols">列数</param>
/// <param name="p_rowHeight">行高</param>
/// <param name="p_arrColsWidth">列宽</param>
/// <param name="p_gridLineFlag">网格线类型</param>
/// <param name="p_gridBorderFlag">边框类型</param>
/// <param name="p_scaleXY">水平与垂直方向缩放量</param>
/// <remarks>
/// 作 者:周方勇[长江支流]
/// 修改日期:2004-08-07
/// </remarks>
protected void DrawGridLine(Graphics g,Rectangle p_rec,Pen p_pen,int p_rows,int p_cols,int p_rowHeight,int[] p_arrColsWidth,GridLineFlag p_gridLineFlag,GridBorderFlag p_gridBorderFlag,PointF p_scaleXY)
{
//缩放矩阵,用于绘图
Rectangle rec = new Rectangle(p_rec.X,p_rec.Y,p_rec.Width,p_rec.Height);

//缩放程序
this.TransGrid(g,rec,p_scaleXY);

#region 有网格线才画
if (p_gridLineFlag != GridLineFlag.None)
{
int lngRows = p_rows; //arrStrGrid.GetLength(0); //行数,也可由二维数组算出
int lngCols = p_cols; //arrStrGrid.GetLength(1); //列数

int lngRowIndex; //当前行
int lngColIndex; //当前列

//起止坐标
int X1, X2,Y1, Y2;

int lngLineLen; //线长
int lngLineHei; //线高


//计算坐标、线长、线高
lngLineLen = rec.Width;
lngLineHei = rec.Height;

#region 包括横线就画
if (p_gridLineFlag == GridLineFlag.Horizontal || p_gridLineFlag == GridLineFlag.Both)
{
//******先画横线******
X1 = rec.X;
Y1 = rec.Y;
X2 = X1 + lngLineLen;

//最上边与最下边的线不画
for(lngRowIndex = 1 ; lngRowIndex < lngRows ; lngRowIndex++)
{
Y1 += p_rowHeight; //这里可以换成行高数组

//Y1 += p_arrRowsWidth[lngRowIndex - 1];//这里可以换成行高数组

Y2 = Y1;
g.DrawLine(p_pen,X1,Y1,X2,Y2);
}
}
#endregion

#region 包括竖线就画
if (p_gridLineFlag == GridLineFlag.Vertical || p_gridLineFlag == GridLineFlag.Both)
{
//******再画竖线******
//列宽
int[] mArrColWidth = new int[lngCols];
mArrColWidth = p_arrColsWidth;

//Y不变
X1 = rec.X;
Y1 = rec.Y;
Y2 = Y1 + lngLineHei;

//最左边与右边的线不画
for(lngColIndex = 0 ; lngColIndex < lngCols-1 ; lngColIndex++)
{
X1 += mArrColWidth[lngColIndex];
X2 = X1;
g.DrawLine(p_pen,X1,Y1,X2,Y2);
}
}
#endregion

}//End If
#endregion

//******边框******
if (p_gridBorderFlag != GridBorderFlag.None)
{
this.DrawGridBorder(g,rec,p_pen,p_gridBorderFlag);
}

//重置,不再变换
this.ResetTransGrid();

}
#endregion

 

#region 画合并线的核心
/// <summary>
/// 画网格线,根据合并方式判断相邻单元格内容一格一格的画
/// </summary>
/// <param name="g">绘图表面</param>
/// <param name="p_rec">绘图区</param>
/// <param name="p_pen">绘图线的笔,可以定义颜色与线宽</param>
/// <param name="arrStrGrid">二维数组</param>
/// <param name="p_rowHeight">行高</param>
/// <param name="p_arrColsWidth">列宽</param>
/// <param name="p_gridLineFlag">网格线类型</param>
/// <param name="p_gridBorderFlag">边框类型</param>
/// <param name="p_scaleXY">水平与垂直方向缩放量</param>
/// <param name="gridMergeFlag">网格单元格合并方式</param>
/// <remarks>
/// 作 者:周方勇[长江支流]
/// 修改日期:2004-08-07
/// </remarks>
protected void DrawGridMergeLine(Graphics g,Rectangle p_rec,Pen p_pen,string[,] arrStrGrid,int p_rowHeight,int[] p_arrColsWidth,GridLineFlag p_gridLineFlag,GridBorderFlag p_gridBorderFlag,PointF p_scaleXY,GridMergeFlag gridMergeFlag)
{
//缩放矩阵,用于绘图
Rectangle rec = new Rectangle(p_rec.X,p_rec.Y,p_rec.Width,p_rec.Height);

int lngRows = arrStrGrid.GetLength(0); //行数
int lngCols = arrStrGrid.GetLength(1); //列数

//网格不合并直接画标准网格线,否则一个单元格一个单元格的画
if (gridMergeFlag == GridMergeFlag.None)
{
this.DrawGridLine(g,rec,p_pen,lngRows,lngCols,p_rowHeight,p_arrColsWidth,p_gridLineFlag,p_gridBorderFlag,p_scaleXY);
return;
}
else
{
#region 有网格线才画
if (p_gridLineFlag != GridLineFlag.None)
{
//变换
this.TransGrid(g,rec,p_scaleXY);

//起止坐标
int X1, X2,Y1, Y2;

//列宽
int[] mArrColWidth = new int[lngCols];
mArrColWidth = p_arrColsWidth;

#region 画单元格线

//边界不画
for(int i = 0 ; i < lngRows ; i++)
{
X1 = rec.X;
Y1 = rec.Y;

for(int j = 0 ; j < lngCols ; j++)
{
//-----水平线-----
X2 = X1 + mArrColWidth[j];

Y1 = rec.Y + p_rowHeight * i; //****可用行高数组
Y2 = Y1;
//画第二行开始及以下的横线,当前行与上一行文本不同
if (i > 0)
{
//任意合并,只要相邻单元格内容不同就画线,即只要相邻单元格内容相同就合并
if (gridMergeFlag == GridMergeFlag.Any)
{
//画线(条件:此列不合并 || 文本空 || 当前行与上一行文本不同)
if(arrStrGrid[i,j] == "" || arrStrGrid[i,j] != arrStrGrid[i-1,j])
{
g.DrawLine(p_pen,X1,Y1,X2,Y2);
}
}
}

//-----'竖线-----
//画第二列以后的竖线,当前列与上一列比较
if (j > 0)
{
Y2 = Y2 + p_rowHeight; //****可用行高数组
X2 = X1;
//任意合并,只要相邻单元格内容不同就画线,即只要相邻单元格内容相同就合并
if (gridMergeFlag == GridMergeFlag.Any)
{
//画线(条件:此行不合并 || 文本空 || 当前列与上一列文本不同)
if(arrStrGrid[i,j] == "" || arrStrGrid[i,j] != arrStrGrid[i,j-1])
{
g.DrawLine(p_pen,X1,Y1,X2,Y2);
}
}
}

//下一列,宽加上
X1 += mArrColWidth[j];

}//End For 列
}//End For 行
#endregion

//******边框******
if (p_gridBorderFlag != GridBorderFlag.None)
{
this.DrawGridBorder(g,rec,p_pen,p_gridBorderFlag);
}

//重置,不再变换
this.ResetTransGrid();
}//End If
#endregion

}//End If
}//End Function
#endregion
 

#region 标准不合并网格的文本
/// <summary>
/// 绘制网格文本,标准的行与列单元格,无合并
/// </summary>
/// <param name="g">绘图表面</param>
/// <param name="p_rec">绘图区</param>
/// <param name="p_brush">绘图文本的画刷,可以定义颜色</param>
/// <param name="arrStrGrid">二维字符数组(网格)</param>
/// <param name="p_rowHeight">固定行高</param>
/// <param name="p_arrColsWidth">列宽数组,为null时则平均列宽</param>
/// <param name="alignment">由Left,Center,Right对齐方式第一个字母组成的串</param>
/// <param name="p_scaleXY">指定X与Y向缩放比例值</param>
/// <remarks>
/// 作 者:周方勇[长江支流]
/// 修改日期:2004-08-07
/// </remarks>
protected void DrawGridText(Graphics g,Rectangle p_rec,Brush p_brush,string[,] arrStrGrid,int p_rowHeight,int[] p_arrColsWidth,string alignment,Font p_font,PointF p_scaleXY)
{
try
{
//缩放矩阵,用于绘图
Rectangle rec = new Rectangle(p_rec.X,p_rec.Y,p_rec.Width,p_rec.Height);

Font font = p_font;
if (font == null)
{
font = new Font("宋体",12.0F);
}

int lngRows = arrStrGrid.GetLength(0); //行数
int lngCols = arrStrGrid.GetLength(1); //列数

//列宽
int[] mArrColWidth = new int[lngCols];
mArrColWidth = p_arrColsWidth;

//列对齐方式
AlignFlag[] arrAlign;
arrAlign = this.GetColsAlign(alignment);

//变换
this.TransGrid(g,rec,p_scaleXY);

//起止坐标
int X1,Y1,width;

#region 画单元格文本

StringFormat sf = new StringFormat(); //字符格式
sf.LineAlignment = StringAlignment.Center; //垂直居中
sf.FormatFlags = StringFormatFlags.LineLimit | StringFormatFlags.NoWrap;

for(int i = 0 ; i < lngRows ; i++)
{
X1 = rec.X;
Y1 = rec.Y + p_rowHeight*i; //****可用行数组

for(int j = 0 ; j < lngCols ; j++)
{
width = mArrColWidth[j];

Rectangle recCell = new Rectangle(X1,Y1,width,p_rowHeight + 4); //实际上居中会稍微偏上,因为字体有预留边距

sf.Alignment = StringAlignment.Near; //默认左对齐

if(arrAlign.Length > j)
{
if (arrAlign[j] == AlignFlag.Center)
{
sf.Alignment = StringAlignment.Center; //居中
}
else if (arrAlign[j] == AlignFlag.Right)
{
sf.Alignment = StringAlignment.Far ; //居右
}
}

g.DrawString(arrStrGrid[i,j],font,p_brush,recCell,sf);

X1 += width;

}//End For 列

}//End For 行
#endregion

//重置,不再变换
this.ResetTransGrid();

// font.Dispose();
}
catch(Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
}
finally
{

}

}//End Function
#endregion
 


#region 合并方式下的网格文本
/// <summary>
/// 绘制网格文本,标准的行与列单元格,有合并
/// </summary>
/// <param name="g">绘图表面</param>
/// <param name="p_rec">绘图区</param>
/// <param name="p_brush">绘图文本的画刷,可以定义颜色</param>
/// <param name="arrStrGrid">二维字符数组(网格)</param>
/// <param name="p_rowHeight">固定行高</param>
/// <param name="p_arrColsWidth">列宽数组,为null时则平均列宽</param>
/// <param name="alignment">由Left,Center,Right对齐方式第一个字母组成的串</param>
/// <param name="p_scaleXY">指定X与Y向缩放比例值</param>
/// <remarks>
/// 作 者:周方勇[长江支流]
/// 修改日期:2004-08-07
/// </remarks>
protected void DrawGridMergeText(Graphics g,Rectangle p_rec,Brush p_brush,string[,] arrStrGrid,int p_rowHeight,int[] p_arrColsWidth,string alignment,Font p_font,PointF p_scaleXY,GridMergeFlag gridMergeFlag)
{
if (gridMergeFlag == GridMergeFlag.None)
{
DrawGridText(g,p_rec,p_brush,arrStrGrid,p_rowHeight,p_arrColsWidth,alignment,p_font,p_scaleXY);
return;
}

try
{
//缩放矩阵,用于绘图
Rectangle rec = new Rectangle(p_rec.X,p_rec.Y,p_rec.Width,p_rec.Height);

Font font = p_font;
if (font == null)
{
font = new Font("宋体",12.0F);
}

int lngRows = arrStrGrid.GetLength(0); //行数
int lngCols = arrStrGrid.GetLength(1); //列数

//列宽
int[] mArrColWidth = new int[lngCols];
mArrColWidth = p_arrColsWidth;

//列对齐方式
AlignFlag[] arrAlign;
arrAlign = this.GetColsAlign(alignment);

//变换
this.TransGrid(g,rec,p_scaleXY);

#region 画单元格文本

StringFormat sf = new StringFormat(); //字符格式
sf.LineAlignment = StringAlignment.Center; //垂直居中
sf.FormatFlags = StringFormatFlags.LineLimit | StringFormatFlags.NoWrap;

CellRectangle cell = new CellRectangle(rec.X,rec.Y,0,p_rowHeight); //单元格

for(int i = 0 ; i < lngRows ; i++)
{
for(int j = 0 ; j < lngCols ; j++)
{
//.....
cell = this.GetMergeCell(new Point(rec.X,rec.Y),arrStrGrid,p_rowHeight,mArrColWidth,i,j);

Rectangle recCell = new Rectangle(cell.Left,cell.Top,cell.Width,cell.Height + 4); //实际上居中会稍微偏上,因为字体有预留边距

sf.Alignment = StringAlignment.Near; //默认左对齐

if(arrAlign.Length > j)
{
if (arrAlign[j] == AlignFlag.Center)
{
sf.Alignment = StringAlignment.Center; //居中
}
else if (arrAlign[j] == AlignFlag.Right)
{
sf.Alignment = StringAlignment.Far ; //居右
}
}

g.DrawString(arrStrGrid[i,j],font,p_brush,recCell,sf);
}//End For 列

}//End For 行
#endregion

//重置,不再变换
this.ResetTransGrid();

//font.Dispose();
}
catch(Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
}
finally
{

}
}//End Function
#endregion
 

  以上方法中用到的GetColWidth函数,算法比较简单,就是把总共的列宽除以列数,让每列平均。为了十分的精确,其实是让除最后一列的列的列宽为平均值,最后一列为总列宽减去前面列宽和。 另外,GridLineFlag枚举定义了Horizontal、Vertical和GridLineFlag.Both,表示水平、垂直及两者都有的网格线。

  其它支持函数,请下载源码

 

DataGridView转换为二维数组

/// <summary>
/// 将VS.Net 2005 DataGridView控件的数据导出到二维数组。
/// </summary>
/// <param name="dataGridView">VS.Net 2005 DataGridView控件。</param>
/// <param name="includeColumnText">是否要把列标题文本也导到数组中。</param>
///  <作者>长江支流</作者>
///  <日期></日期>
public string[,] ToStringArray(DataGridView dataGridView, bool includeColumnText)
{
#region 实现...
string[,] arrReturn = null;
int rowsCount = dataGridView.Rows.Count;
int colsCount = dataGridView.Columns.Count;
if (rowsCount > 0)
{
//最后一行是供输入的行时,不用读数据。
if (dataGridView.Rows[rowsCount - 1].IsNewRow)
{
rowsCount--;
}
}
int i = 0;
//包括列标题
if (includeColumnText)
{
rowsCount++;
arrReturn = new string[rowsCount, colsCount];
for (i = 0; i < colsCount; i++)
{
arrReturn[0, i] = dataGridView.Columns[i].HeaderText;
}
i = 1;
}
else
{
arrReturn = new string[rowsCount, colsCount];
}
//读取单元格数据
int rowIndex = 0;
for (; i < rowsCount; i++, rowIndex++)
{
for (int j = 0; j < colsCount; j++)
{
arrReturn[i, j] = dataGridView.Rows[rowIndex].Cells[j].Value.ToString();
}
}
return arrReturn;
#endregion 实现
}
 

ListView转换为二维数组

/// <summary>
/// 将ListView的数据导出到二维数组。
/// </summary>
/// <param name="listView">二维数据视图</param>
/// <param name="includeColumnText">是否要把列标题文本也导到数组中。</param>
/// <remarks>
///  <作者>长江支流</作者>
///  <日期>2005-08-21</日期>
/// </remarks>
/// <returns>二维数组。</returns>
public string[,] ToStringArray(ListView listView,bool includeColumnText)
{
 ListView lvw = listView;
 int rowsCount = lvw.Items.Count;
 int colsCount = lvw.Columns.Count;

 //包括列标题
 if (includeColumnText)
 {
  rowsCount++;
 }

 string[,] arrReturn = null;
 
 arrReturn = new string[rowsCount,colsCount];

 int i = 0;

 if (includeColumnText)
 {
  //写标题
  for(i = 0 ; i < colsCount; i++)
  {
   arrReturn[0,i] = lvw.Columns[i].Text;
  }

  i = 1;
 }

 //写数据行Items
 int rowIndex = 0;
 for(; i < rowsCount; i++,rowIndex++)
 {
  for (int j = 0; j < colsCount; j++)
  {
   arrReturn[i,j] = lvw.Items[rowIndex].SubItems[j].Text;
  }
 }

 return arrReturn;
}

打印ListView:

private void btnPrintEasy_Click(object sender, System.EventArgs e)
{
 MisGoldPrinter webmis = new MisGoldPrinter();   //打印组件
 webmis.Title = "MIS金质打印通/nWWW.WebMIS.COM.CN";  //网格标题   
 webmis.DataSource = ToStringArray(listView,true);    //任意二维的数据通通打印   
 webmis.Preview();      //打印预览
}

VB.Net:
Private Sub btnPrintEasy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrintEasy.Click
        Dim webmis As MisGoldPrinter      '打印组件
        webmis = New MisGoldPrinter
        webmis.Title = "MIS金质打印通"+vbCrLf+"WWW.WebMIS.COM.CN"  '网格标题
        webmis.DataSource = ToStringArray(listView,true)   '任意二维的数据通通打印   
        webmis.Preview();
        webmis.Dispose();
End Sub

打印DataGridView:

不用说,相信您已掌握到打印精髓,不就是一个二维数组么?

是的,就是一个二维数组。为了效率,你可以使用一个DataTable,分页将数据写到二维数组中打印。下面,就以DataGridView打印为例,再把网格的字体和列宽也都设置一下。

private void btnPrintEasy_Click(object sender, System.EventArgs e)
{
    GoldPrinter.MisGoldPrinter webmis = new GoldPrinter.MisGoldPrinter();   //打印组件
    webmis.Title = "MIS金质打印通/nWWW.WebMIS.COM.CN";                      //标题,还可设置子标题
    (webmis.Title as GoldPrinter.Title).Font = new System.Drawing.Font("宋体", 12, System.Drawing.FontStyle.Bold);

    //下面这一句就可以打印DataGridView
    //(webmis.Body as GoldPrinter.Body).DataSource = ToStringArray(dataGridView1, true);
   
    //为人特性化,自定义表体,可以设置字体、列宽、列对齐方式
    GoldPrinter.Body gridBody = new GoldPrinter.Body();
    //任意二维的数据通通打印,或者是设置GridText属性
    gridBody.DataSource = ToStringArray(dataGridView1, true);
    gridBody.Font = dataGridView1.Font;
    gridBody.ColsWidth = GetColsWidth(dataGridView1);
    webmis.Body = gridBody;

    webmis.Preview();
    webmis.Dispose();
}

 

有了ListView的打印示例,VB.NET的代码我想也不用写了吧,上面一段照搬,新增的部分把//改成',把;去掉就OK了。

这里还用到提取ListView/Vs2005DataGridView列宽的方法int[] GetColsWidth(ListView listView)、int[] GetColsWidth(DataGridView dataGridView)。

为方便读者ListView与Vs2005DataGridView打印,我加了一个类,请见金质打印通工程 GoldPrint/DataGridViewListViewHelper.cs,提供将ListView、VS2005DataGridView转换成二维数组的方法并提取列宽。 下载源码

 

相关内容:

相关源码下载信息请访问:

http://blog.csdn.net/flygoldfish
打印核心架构及源码(建议学习者下载,然后再对照全部源码看看应用设计模式及优化。):
http://www.webmis.com.cn/DownLoad/MisGoldPrinterOpenSource.rar

打印全部源码(软件公司、工作室、个人,无需再购三方打印控件,拿来就用,还可以再加工定制自己需要的打印。):
http://www.webmis.com.cn/DownLoad/MisGoldPrinter.rar


NET环境下有关打印页面设置、打印机设置、打印预览对话框的实现及应用: http://blog.csdn.net/flygoldfish/archive/2004/08/17/77208.aspx
http://blog.csdn.net/flygoldfish/archive/2004/09/06/95685.aspx

DataGridView打印控件和.NET打印控件5.6版(含报表模板设计组件)2014年6月22日修改完成,完全免费,在.NET2.0及以上环境下都可以使用(VB打印、C#打印都是可以的),有帮助文档与使用实例。 与上一版本的5.5版相比,新控件5.6版的主要更改如下: 1、增加了一个新打印组件SimpleReport组件,该组件与DGVPrint组件一样在运行时可进行打印参数设置,但比DGVPrint组件功能更强大,可以自动管理多个打印方案,在打印预览时可以自由在各个打印方案之间切换;可以在打印参数设置窗口中动态定义多表头,还可以像EasyReport组件一样设置和使用参数变量(具体使用效果参见实例程序); 2、解决了EasyReport组件在插入变量参数时,变量参数未排序导致查找不方便的问题; 3、在打印预览界面添加了简单的双面打印功能。(打印预览界面工具栏中的“打印\双面打印”菜单); 4、其他一些完善,比如DGVPrint组件中设置的行高无效等问题。 本控件特色: 1、强大的DataGridView打印功能,不仅可以以多种形式(普通打印、分栏打印、跨页打印、工资条打印打印DGV表格,基本上能完全按DGV控件本身设置的格式如字体、字号、背景颜色、前景颜色、单元格对齐方式等打印出来,文字图像都可以打印,而且是完全根据表格当前的显示顺序进行打印的,基本上做到了所见即所得的打印。 2、报表设计功能。报表模板设计组件EasyReport与WebEasyReport组件可以设计普通报表、分组报表、套打模板等,分别以DataGridView为数据源。控件的位置以毫米为计量单位,定位准确,很适合套打单据设计。 3、强大的图表打印功能。5.2版控件新增了一个Chartlet的组件,使用非常方便,可以生成柱形图、饼图、折线图等多种图形,而且可以设置2D或3D效果,既可以在打印控件中打印出来,也可以在Graphics对象中显示。 4、分组汇总打印DataGridVeiw功能,每组还可以自动换新页打印,还可以自动增加行号。 5、强大的文本打印输出功能,控件提供多个文本打印重载函数,打印文本时,如果需要,控件会自动换行和换页打印输出。还增加了以指定行间距及字符间距打印文本的功能,可以用固定行距,也可以用单倍或多倍行距打印文本。 6、强大的绘图功能,基本上.NET的GDI+的绘图函数(如直线、矩形、路径、多边形、曲线等)都有,只有个别函数的名称有点区别。 7、支持同一文档多种版面格式打印(类似于Word中的节的功能):对同一份文档,不同的页面可以设置不同的格式(纸张大小、纸张方向、页边距),只需要在新增一页时在NewPage方法中指定要使用的页面格式即可,使用非常简单。 8、报表文件保存功能。本控件允许将当前打印预览的内容保存为报表文件,以后使用本控件重新打开该报表文件即可重现原来保存报表时的打印内容。 9、Excel导出功能,可以将DataGridView和GridView导出为Excel文件,5.2版控件还增加了不依赖Office的导出Excel功能,而且速度非常快,5.4版还增加了合并单元格的导出功能。 10、打印DataGridView时的打印方案保存与读取功能。可以将当前打印参数保存为打印方案文件,或者从保存的打印方案文件中读取打印参数。 11、水印打印功能。根据需要,可以在页面中打印或不打印以半透明空心文字打印水印。 12、强大的容器控件打印功能(DrawPanel函数)。借助该函数,您只需要在您的容器控件中设计好要打印的内容及打印内容的相对位置,控件轻松帮你打印出来(如果超过一页,控件会自动换页续打)。 13、特殊文字效果打印功能。控件具有打印浮雕文字、阴影文字、空心文字、块文字的功能。 14、页眉页脚中既可打印文字,也可打印图像,或者即打印图像又打印输出文字。 15、图像与图标打印输出功能。 16、多表头(跨行跨列的复杂表头)打印功能,多表头组件支持多表头显示与打印、单元格内容的合并显示、打印与导出。 17、自定义纸张支持功能。 18、纸张背景图片设置打印功能。 19、.NET4.0支持功能(是单独的一个文件)。 20、直接打印窗口中的TreeView控件功能。 21、打印窗口中的ListView功能。 22、RichTextBox控件的RTF文本打印功能。 23、斜线表头打印功能(5.4版新增)。 24、二维码打印功能(5.5版本增加)。 25、5.6版新增的SimpleReport组件允许您在一个方案文件中管理多个打印方案,在打印预览时能自由在各个打印方案之间切换。 我将持续改进该控件,并将不断推出控件的新版本,要查看或下载控件的升级版本,请登陆网站:http://myyouping.download.csdn.n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值