MaoBisheng

Asp.Net(C#) & SQL & Oracle

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  71 随笔 :: 0 文章 :: 58 评论 :: 2 引用

 

.Net中的打印A4纸如何实现(以C#为例)

——VB中的Printer.Print.Net中如何实现

在VB中,如果要打印打印A4文档,且内容是从DB中,或者DataGrid中等动态获取的,实现起来非常简单,诸如以下代码(rs表示一记录集):

    rs.MoveFirst
    Printer.PaperSize 
= vbPRPSA4
    Printer.Orientation 
= vbPRORPortrait
    Printer.FontName 
= "Courier New"
    Printer.FontBold 
= True
    Printer.FontSize 
= 24
    Printer.Print 
"               FQA Report"
    Printer.FontSize 
= 16
    Printer.Print 
"   Pallet ID:" & Trim(rs("pallet_id"))
    
    NewLine2 
= String(100" ")
    
Mid(NewLine2, 15= "NO#"
    
Mid(NewLine2, 1030= "System S/N"
    
Mid(NewLine2, 3520= "BOX_ID"
    
Mid(NewLine2, 6020= "Pallet_ID"
    
    
While Not rs.EOF
        NewLine2 
= String(100" ")
        
Mid(NewLine2, 15= Trim(rs("No"))
        
Mid(NewLine2, 1030= Trim(rs("SN"))
        
Mid(NewLine2, 3520= Trim(rs("BOX_ID"))
        
Mid(NewLine2, 6020= "" & Trim(rs("Pallet_ID"))
        Printer.Print NewLine2
        rs.MoveNext
    Wend
    
    Printer.Print NewLine2
    Printer.Print 
String(100"-")

    在上述代码中,如果记录集中的数量很多,即内容超出了一页纸,程序不用做任何设置,便会自动分页,那么到.Net中,如何实现这么一个简单的功能呢?
    查了好多资料,上网搜了好久,发现没有类似的例子,看了MSDN后,才发现,到VB.Net中,VB中那么好用的Printer不见了,一下为MSDN的描述:http://msdn.microsoft.com/zh-tw/library/cc438273(VS.71).aspx

"Visual Basic 6.0 中的 Printer 物件在 Visual Basic .NET 中是由 PrintDocument 组件取代。两者的行为不同,但在多数情况下可复制功能。下表将列出 Visual Basic 6.0 属性 (Property)、方法及事件与其 Visual Basic .NET 对等用法。如果没有直接的对等用法,则会提供连结以取得其它信息。除非另外注明,否则所有的对象都是在 System.Drawing 命名空间中。"

第一感觉是,在.Net中有比这更好用的打印功能,而且功能更强大,于是开始翻书,上网找例子,花了好长时间后,终于在网上找到了两个例子,跟教科书(C#高级编程第四版第25章,VB 2005入门经典第7章)里的例子差不多,例子中都是要先打开文档,LoadFile后,然后计算中共有多少行,然后设置一些属性等等,虽然功能强大,但是极其复杂,不能直接拿来用,于是只好自己改写。。。

打印Function:

public bool PrintDoc()
{
    
try
    
{
        
//获取需要打印的内容
        string strSQL = "exec [usp_PalletPrintDocInfo] '" 
            
+ Parameters.strStation + "', '" + Parameters.strPalletID + "'";
        dsPrintInfo 
= doDB.GetDataSet(strSQL);
        
if (dsPrintInfo.Tables[0].Rows.Count < 1 || dsPrintInfo.Tables[1].Rows.Count < 1)
        
{
            Parameters.strMsg 
= "Get Print Information Error";
            
return false;
        }


        
//打印
        PrintDocument printDocument = new PrintDocument();
        printDocument.PrintPage 
+= new PrintPageEventHandler(this.pd_PrintPage);
        printDocument.Print();

        
////打印预览,调试的时候,可以通过这个,节约纸张
        //PrintPreviewDialog ppd = new PrintPreviewDialog();
        
//PrintDocument pd = new PrintDocument();
        
//pd.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
        
//ppd.Document = pd;
        
//ppd.ShowDialog();

        
return true;
    }

    
catch(Exception ex)
    
{
        Parameters.strMsg 
= ex.Message.ToString();
        
return false;
    }

}

 

上面代码中,核心的是下面这个事件,调用pd_PrintPage方法:

//打印
PrintDocument printDocument = new PrintDocument();
printDocument.PrintPage 
+= new PrintPageEventHandler(this.pd_PrintPage);
printDocument.Print();

 

pd_PrintPage方法:

//打印A4纸用的变量

private void pd_PrintPage(object sender, PrintPageEventArgs e)
{
    
string strLine;//用于存放当前行打印的信息            
    float leftMargin = (e.MarginBounds.Left) * 3 / 4;   //左边距
    float topMargin = e.MarginBounds.Top * 2 / 3;       //顶边距
    float verticalPosition = topMargin;                 //初始化垂直位置,设为顶边距

    Font mainFont 
= new Font("Courier New"10);//打印的字体
    
//每页的行数,当打印行数超过这个时,要换页(1.05这个值是根据实际情况中设定的,可以不要)
    int linesPerPage = (int)(e.MarginBounds.Height * 1.05 / mainFont.GetHeight(e.Graphics));

    
//Format of this DocReport

    
//打印具体的SN,BoxID,PalletID列表

    
//如果总行数大于目前实际行号,表明还有页要打,lineQty是估计数,因此实际用时要仔细估算
    if (lineQty > lineNo)   
    
{
        e.HasMorePages 
= true
    }

    
else
    
{
        e.HasMorePages 
= false;
    }


    
//打印结尾信息

    printingPageNo
++//页号加一
}


打印效果大致截图:(如果有多页,尾部的信息只在最后一页显示)
 
总结:如此简单的功能,在.Net中实现起来确实那么的复杂,尤其是对于自动分页的功能,虽然总体上功能强大了好多,但是把原先那么好用的东西给去掉了。以上代码改写成VB.Net的话,都差不多。。。

 

 

作者:MaoBisheng
出处:http://maobisheng.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted on 2008-12-30 10:30 MaoBisheng 阅读(3587) 评论(5) 编辑 收藏

评论

#1楼 2008-12-30 12:05 潜水员      
先占个沙发,下班研究
 回复 引用 查看   

#2楼 2008-12-30 12:45 feiyun0112      
http://msdn.microsoft.com/zh-cn/library/microsoft.visualbasic.powerpacks.printing.compatibility.vb6.printer.aspx
 回复 引用 查看   

#3楼[楼主] 2008-12-30 12:56 毛必盛      
--引用--------------------------------------------------
feiyun0112: <a href="http://msdn.microsoft.com/zh-cn/library/microsoft.visualbasic.powerpacks.printing.compatibility.vb6.printer.aspx" target="_new">http://msdn.microsoft.com/zh-cn/library/microsoft.visualbasic.powerpacks.printing.compatibility.vb6.printer.aspx</a>
--------------------------------------------------------
谢谢,我看了,应该是可以用的,不想去试了,呵呵。
代码以后迟早要升级,就这个功能而言,用C#实现以后升级或许比在VB6的基础上升级更方便了。

Microsoft.VisualBasic.PowerPacks.Printing.Compatibility.VB6 命名空间中的函数和对象是提供给用于将 Visual Basic 6.0 升级到 Visual Basic 2008 的工具使用的。在大多数情况下,这些函数和对象重复 .NET Framework 的其他命名空间中的功能。只有 Visual Basic 6.0 代码模型与 .NET Framework 实现有显著区别时才需要这些函数和对象。
 回复 引用 查看   

#4楼 2008-12-31 09:20 毁于随      
为什么不用报表控件来做呢?
 回复 引用 查看   

#5楼[楼主] 2008-12-31 15:33 毛必盛      
--引用--------------------------------------------------
毁于随: 为什么不用报表控件来做呢?
--------------------------------------------------------
报表控件大概是可以的,我没有用过,老程序是VB版本的,现改成.Net的,思维定势,觉得用类似的功能也能实现。
 回复 引用 查看