职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 2173|回复: 2

C# winform求助(关于打印问题)

[复制链接]
hopedilei 发表于 2008-10-23 21:51 | 显示全部楼层 |阅读模式
我需要做一个winform打印的功能,之前从来没有接触过,所以找了很久的资料!
现在我可以把gridview里面的数据全部打印出来了!
可是我现在需要做的事套打,就是在form上点击button
就是在一张纸上已经有N多文字了,如   姓名:
我现在要把 “张三” 这2个字打印到  姓名:  的后面,位置不能错
有人告诉我要用水晶报表!但是研究了下发现有难度
不知道论坛里面的大大们有没有好的办法?
最好能加我QQ4588482指点我下!不胜感激!

或者写一个简单的demo给我看看!我学习下就行了!
网上那些例子或者说明都太复杂!不适合我这个初学者!谢谢了!
莫唁 发表于 2008-10-24 21:42 | 显示全部楼层
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using PrintDataGridViewDemo.BFDataSetTableAdapters;
namespace PrintDataGridViewDemo
{
    public partial class Form1 : Form
    {
        BFDataSet ds = new BFDataSet();
        公司网站TableAdapter companyDA;
        int currentRow = 0;  //此变量用于记录打印行数
        public Form1()
        {
            InitializeComponent();
        }

        #region 一、搜索事件处理函数

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
           
            companyDA = new 公司网站TableAdapter();
            companyDA.Fill(ds.公司网站);
            this.dataGridView1.DataMember = ds.公司网站.TableName;
            this.dataGridView1.DataSource = ds;
            //冻结第二列
            this.dataGridView1.Columns[1].Frozen = true;
        }
        #endregion

        #region 二、退出事件处理函数

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            DialogResult dr=MessageBox.Show("你确定要退出?","提示",MessageBoxButtons.OKCancel,MessageBoxIcon.Information);
            if (dr == DialogResult.OK)
                Application.Exit();
            else
                return;
        }
        #endregion

        #region 三、页面设置事件处理函数

        private void 页面设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.pageSetupDialog1.ShowDialog();
        }
        #endregion

        #region 四、打印预览事件处理函数

        private void 打印预览ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.printPreviewDialog1.ShowDialog();
        }
        #endregion

        #region 五、打印事件处理函数

        private void 打印ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //1.判断是否要打印
            if (this.printDialog1.ShowDialog() == DialogResult.OK)
            {
                this.printDocument1.Print(); //开始打印过程,调用PintPage事件
            }
        }
        #endregion

        #region PrintPage事件处理函数

        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            int top = e.MarginBounds.Top;       //取得左上角的纵坐标
            int left = e.MarginBounds.Left;       //取得左上角的横坐标
            int right = e.MarginBounds.Right;      //取得右上角的横从标
            int width = e.MarginBounds.Width;       //取得打印区域的宽度
            int height = e.MarginBounds.Height;        //取得打印区域的高度
            int bottom = e.MarginBounds.Bottom;      //取得打印区域的下限
            
            //构造一支画笔(颜色,宽度
蓝色梦幻 发表于 2008-10-27 11:45 | 显示全部楼层
套打的话,程序是一样的,主要是位置没有调整好,所以最笨的方法可能就是你调整你的报表格式,
1)方法一:c#webform中,曾经做个这样一个项目,扫描客户的发票,放入HTML中作为背景,用多个DIV的绝对定位,调整到发票上需要打印的地方,然后用脚本控制DIV的text,打印效果不错。说真的试多几次位置的精确度是必要的.
2)另外一种的代码设置实现:[引用别人的,希望能有思路上的帮助]
·所有字体,边距,header 高,行高,都可以自定义。

·支持自动计算每页行数与每页固定行数。

·支持页脚显示页数。

由于自己用和本人比较懒,所以把属性都设置成公有,赋值的时候小心。

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Printing;
using System.Data;

using System.Windows.Forms;

namespace cjManager
{
public class cutePrinter
{
private DataGrid dataGrid;
private PrintDocument printDocument;
private PageSetupDialog pageSetupDialog;
private PrintPreviewDialog printPreviewDialog;

private string title="";

int currentPageIndex=0;
int rowCount=0;
int pageCount=0;

int titleSize=16;
bool isCustomHeader=false;

//Brush alertBrush=new SolidBrush(Color.Red);

string[] header=null;//如果自定义就填入字符串,如果需要斜线分隔,就用\表示,例如:个数#名字 其中#为splitChar
string[] uplineHeader=null;//上行文字数组
int[] upLineHeaderIndex=null;//上行的文字index,如果没有上行就设为-1;

public bool isEveryPagePrintTitle=false;//是否每一页都要打印标题。
public int headerHeight=50;//标题高度。
public int topMargin=60; //顶边距
public int cellTopMargin=6;//单元格顶边距
public int cellLeftMargin=4;//单元格左边距
public char splitChar=''#'';//当header要用斜线表示的时候
public string falseStr="×";//如果传进来的dataGrid中有 false,把其转换得字符。
public string trueStr="√";//如果传进来的dataGrid中有 true,把其转换得字符。
public int pageRowCount=7;//每页行数
public int rowGap = 30;//行高
public int colGap = 5;//每列间隔
public int leftMargin = 50;//左边距
public Font titleFont=new Font("Arial",14);//标题字体
public Font font = new Font("Arial", 10);//正文字体
public Font headerFont = new Font("Arial", 9, FontStyle.Bold);//列名标题
public Font footerFont=new Font("Arial",8);//页脚显示页数的字体
public Font upLineFont=new Font("Arial",9, FontStyle.Bold);//当header分两行显示的时候,上行显示的字体。
public Font underLineFont=new Font("Arial",8);//当header分两行显示的时候,下行显示的字体。
public Brush brush = new SolidBrush(Color.Black);//画刷
public bool isAutoPageRowCount=true;//是否自动计算行数。
public int buttomMargin=80;//底边距
public bool needPrintPageIndex=true;//是否打印页脚页数

//string filterStr="";

public cutePrinter(DataGrid dataGrid,string title,int titleSize)
{
this.title=title;
//this.titleSize=titleSize;


this.dataGrid = dataGrid;
printDocument = new PrintDocument();
printDocument.PrintPage += new PrintPageEventHandler(this.printDocument_PrintPage);


}
public cutePrinter(DataGrid dataGrid,string title)
{
this.title=title;


this.dataGrid = dataGrid;
printDocument = new PrintDocument();
printDocument.PrintPage += new PrintPageEventHandler(this.printDocument_PrintPage);
}
public cutePrinter(DataGrid dataGrid)
{
this.dataGrid = dataGrid;
printDocument = new PrintDocument();
printDocument.PrintPage += new PrintPageEventHandler(this.printDocument_PrintPage);
}

public bool setTowLineHeader(string[] upLineHeader,int[] upLineHeaderIndex)
{
this.uplineHeader=upLineHeader;
this.upLineHeaderIndex=upLineHeaderIndex;
this.isCustomHeader=true;
return true;
}
public bool setHeader(string[] header)
{
this.header=header;
return true;

}

private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{

int width=e.PageBounds.Width;
int height=e.PageBounds.Height;

if(this.isAutoPageRowCount)
pageRowCount=(int)((height-this.topMargin-titleSize-this.headerFont.Height-this.headerHeight-this.buttomMargin)/this.rowGap);

pageCount=(int)(rowCount/pageRowCount);
if(rowCount%pageRowCount>0)
pageCount++;

int xoffset=(int)((width-e.Graphics.MeasureString(this.title,this.titleFont).Width)/2);
int colCount = 0;
int x = 0;
int y =topMargin;
string cellValue = "";

int startRow=currentPageIndex*pageRowCount;
int endRow=startRow+this.pageRowCount<rowCount?startRow+pageRowCount:rowCount;
int currentPageRowCount=endRow-startRow;

if(this.currentPageIndex==0 || this.isEveryPagePrintTitle)
{
e.Graphics.DrawString(this.title,titleFont,brush,xoffset,y);
y+=titleSize;
}

colCount = dataGrid.TableStyles[0].GridColumnStyles.Count;

y += rowGap;
x = leftMargin;


DrawLine(new Point(x,y),new Point(x,y+currentPageRowCount*rowGap+this.headerHeight),e.Graphics);//最左边的竖线

int lastIndex=-1;
int lastLength=0;
int indexj=-1;

for(int j = 0; j < colCount; j++)
{
int colWidth=dataGrid.TableStyles[0].GridColumnStyles[j].Width;
if( colWidth> 0)
{
indexj++;
if(this.header==null || this.header[indexj]=="")
cellValue = dataGrid.TableStyles[0].GridColumnStyles[j].HeaderText;
else
cellValue=header[indexj];

if(this.isCustomHeader)
{
if(this.upLineHeaderIndex[indexj]!=lastIndex)
{

if(lastLength>0 && lastIndex>-1)//开始画上一个upline
{
string upLineStr=this.uplineHeader[lastIndex];
int upXOffset=(int)((lastLength-e.Graphics.MeasureString(upLineStr,this.upLineFont).Width)/2);
if(upXOffset<0)
upXOffset=0;
e.Graphics.DrawString(upLineStr,this.upLineFont,brush,x-lastLength+upXOffset,y+(int)(this.cellTopMargin/2));

DrawLine(new Point(x-lastLength,y+(int)(this.headerHeight/2)),new Point(x,y+(int)(this.headerHeight/2)),e.Graphics);//中线
DrawLine(new Point(x,y),new Point(x,y+(int)(this.headerHeight/2)),e.Graphics);
}
lastIndex=this.upLineHeaderIndex[indexj];
lastLength=colWidth+colGap;
}
else
{
lastLength+=colWidth+colGap;
}
}

//int currentY=y+cellTopMargin;


int Xoffset=10;
int Yoffset=20;
int leftWordIndex=cellValue.IndexOf(this.splitChar);
if(this.upLineHeaderIndex!=null && this.upLineHeaderIndex[indexj]>-1)
{

if(leftWordIndex>0)
{
string leftWord=cellValue.Substring(0,leftWordIndex);
string rightWord=cellValue.Substring(leftWordIndex+1,cellValue.Length-leftWordIndex-1);
//上面的字
Xoffset=(int)(colWidth+colGap-e.Graphics.MeasureString(rightWord,this.upLineFont).Width);
Yoffset=(int)(this.headerHeight/2-e.Graphics.MeasureString("a",this.underLineFont).Height);


//Xoffset=6;
//Yoffset=10;
e.Graphics.DrawString(rightWord,this.underLineFont,brush,x+Xoffset-4,y+(int)(this.headerHeight/2));
e.Graphics.DrawString(leftWord,this.underLineFont,brush,x+2,y+(int)(this.headerHeight/2)+(int)(this.cellTopMargin/2)+Yoffset-2);
DrawLine(new Point(x,y+(int)(this.headerHeight/2)),new Point(x+colWidth+colGap,y+headerHeight),e.Graphics);
x += colWidth + colGap;
DrawLine(new Point(x,y+(int)(this.headerHeight/2)),new Point(x,y+currentPageRowCount*rowGap+this.headerHeight),e.Graphics);
}
else
{

e.Graphics.DrawString(cellValue, headerFont, brush, x, y+(int)(this.headerHeight/2)+(int)(this.cellTopMargin/2));
x += colWidth + colGap;
DrawLine(new Point(x,y+(int)(this.headerHeight/2)),new Point(x,y+currentPageRowCount*rowGap+this.headerHeight),e.Graphics);
}

}
else
{
if(leftWordIndex>0)
{
string leftWord=cellValue.Substring(0,leftWordIndex);
string rightWord=cellValue.Substring(leftWordIndex+1,cellValue.Length-leftWordIndex-1);
//上面的字
Xoffset=(int)(colWidth+colGap-e.Graphics.MeasureString(rightWord,this.upLineFont).Width);
Yoffset=(int)(this.headerHeight-e.Graphics.MeasureString("a",this.underLineFont).Height);

e.Graphics.DrawString(rightWord,this.headerFont,brush,x+Xoffset-4,y+2);
e.Graphics.DrawString(leftWord,this.headerFont,brush,x+2,y+Yoffset-4);
DrawLine(new Point(x,y),new Point(x+colWidth+colGap,y+headerHeight),e.Graphics);
x += colWidth + colGap;
DrawLine(new Point(x,y),new Point(x,y+currentPageRowCount*rowGap+this.headerHeight),e.Graphics);
}
else
{
e.Graphics.DrawString(cellValue, headerFont, brush, x, y+cellTopMargin);
x += colWidth + colGap;
DrawLine(new Point(x,y),new Point(x,y+currentPageRowCount*rowGap+this.headerHeight),e.Graphics);
}

}

}
}
////循环结束,画最后一个的upLine
if(this.isCustomHeader)
{

if(lastLength>0 && lastIndex>-1)//开始画上一个upline
{
string upLineStr=this.uplineHeader[lastIndex];
int upXOffset=(int)((lastLength-e.Graphics.MeasureString(upLineStr,this.upLineFont).Width)/2);
if(upXOffset<0)
upXOffset=0;
e.Graphics.DrawString(upLineStr,this.upLineFont,brush,x-lastLength+upXOffset,y+(int)(this.cellTopMargin/2));

DrawLine(new Point(x-lastLength,y+(int)(this.headerHeight/2)),new Point(x,y+(int)(this.headerHeight/2)),e.Graphics);//中线
DrawLine(new Point(x,y),new Point(x,y+(int)(this.headerHeight/2)),e.Graphics);
}

}

int rightBound=x;

DrawLine(new Point(leftMargin,y),new Point(rightBound,y),e.Graphics); //最上面的线

//DrawLine(new Point(leftMargin,y+this.headerHeight),new Point(rightBound,y+this.headerHeight),e.Graphics);//列名的下面的线

y+=this.headerHeight;


//print all rows
for(int i = startRow; i < endRow; i++)
{

x = leftMargin;
for(int j = 0; j < colCount; j++)
{
if(dataGrid.TableStyles[0].GridColumnStyles[j].Width > 0)
{
cellValue = dataGrid[i,j].ToString();
if(cellValue=="False")
cellValue=falseStr;
if(cellValue=="True")
cellValue=trueStr;

e.Graphics.DrawString(cellValue, font, brush, x+this.cellLeftMargin, y+cellTopMargin);
x += dataGrid.TableStyles[0].GridColumnStyles[j].Width + colGap;
y = y + rowGap * (cellValue.Split(new char[] {''\r'', ''\n''}).Length - 1);
}
}
DrawLine(new Point(leftMargin,y),new Point(rightBound,y),e.Graphics);
y += rowGap;
}
DrawLine(new Point(leftMargin,y),new Point(rightBound,y),e.Graphics);

currentPageIndex++;

if(this.needPrintPageIndex)
e.Graphics.DrawString("共 "+pageCount.ToString()+" 页,当前第 "+this.currentPageIndex.ToString()+" 页",this.footerFont,brush,width-200,(int)(height-this.buttomMargin/2-this.footerFont.Height));

string s = cellValue;
string f3 = cellValue;



if(currentPageIndex<pageCount)
{
e.HasMorePages=true;
}
else
{
e.HasMorePages=false;
this.currentPageIndex=0;

}
//iPageNumber+=1;


}
private void DrawLine(Point sp,Point ep,Graphics gp)
{
Pen pen=new Pen(Color.Black);
gp.DrawLine(pen,sp,ep);
}

public PrintDocument GetPrintDocument()
{
return printDocument;
}



public void Print()
{

rowCount=0;

if(dataGrid.DataSource.GetType().ToString() == "System.Data.DataTable")
{
rowCount = ((DataTable)dataGrid.DataSource).Rows.Count;
}
else if(dataGrid.DataSource.GetType().ToString() == "System.Collections.ArrayList")
{
rowCount = ((ArrayList)dataGrid.DataSource).Count;
}


try
{
pageSetupDialog = new PageSetupDialog();
pageSetupDialog.Document = printDocument;
pageSetupDialog.ShowDialog();  

printPreviewDialog = new PrintPreviewDialog();
printPreviewDialog.Document = printDocument;
printPreviewDialog.Height = 600;
printPreviewDialog.Width = 800;

printPreviewDialog.ShowDialog();
}
catch(Exception e)
{
throw new Exception("rinter error." + e.Message);
}

}
}
}

//用法示例,显示结果如顶图。

private void bnPrint_Click(object sender, System.EventArgs e)
{

cutePrinter dgp=new cutePrinter(this.dataGrid1,this.dlSearchYear.Text+"年"+"专业",16);
string[] uplinestr={"呵呵,hehe","xixi"};
string[] header={"呵呵#xixi","Hee#xcc","kdfj#djjj","kk#jj","kdjf","","","",""};
dgp.setHeader(header);//如果不用改原header就不用赋值。
//注意,这里的列不包括width==0的列
int[] uplineindex={-1,-1,0,0,0,-1,1,1};//注意,这里的列不包括width==0的列
dgp.setTowLineHeader(uplinestr,uplineindex);
dgp.Print();
}
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-4-29 12:28 , Processed in 0.159129 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表