using Microsoft.Reporting.WinForms; using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Drawing.Imaging; using System.Drawing.Printing; using System.IO; using System.Linq; using System.Text; using ZXing; using ZXing.Common; namespace HighWay.PrintLable { public class PrintHelper { #region 方法 -> 打印列表 private IList m_streams;//声明一个Stream对象的列表用来保存报表的输出数据,LocalReport对象的Render方法会将报表按页输出为多个Stream对象 private bool isLandSapces = false; EncodingOptions options = null; BarcodeWriter writer = null; int page = 0; string RdlcUrl; DataTable GoodsTable; decimal PageLeft; decimal PageRight; decimal PageTop; decimal PageBottom; #region 打印 /// /// 打印 /// /// 打印列表 /// 报表路径 /// 左边距 /// 右边距 /// 上边距 /// 下边距 /// public bool Print(DataTable goodsTable, string rdlcUrl, decimal pageLeft = 0, decimal pageRight = 0, decimal pageTop = 0, decimal pageBottom = 0) { RdlcUrl = rdlcUrl; GoodsTable = goodsTable; PageLeft = pageLeft; PageRight = pageRight; PageTop = pageTop; PageBottom = pageBottom; //获取当前已勾选条码用于生产数据源,如果无则跳出 if (goodsTable.Rows.Count <= 0) { return false; } //判断系统是否有已连接的打印机 if (PrinterSettings.InstalledPrinters.Count == 0) { System.Windows.MessageBox.Show("未检测到打印机,请先安装打印机", "系统提示"); return false; } //判断是否超过1000条数据(数据过多会出现打印错误) if (goodsTable.Rows.Count > 1000) { //txtMessage.Text = "最多一次只可打印1000条!"; return false; } using (PrintDocument printDocument = new PrintDocument())//创建对象 { //打印开始前 printDocument.BeginPrint += new PrintEventHandler(printDocument_BeginPrint); //打印输出(过程) printDocument.PrintPage += new PrintPageEventHandler(printDocument_PrintPage); //打印结束 printDocument.EndPrint += new PrintEventHandler(printDocument_EndPrint); //跳出打印对话框,提供打印参数可视化设置,如选择哪个打印机打印此文档等 System.Windows.Forms.PrintDialog pd = new System.Windows.Forms.PrintDialog(); pd.Document = printDocument; if (System.Windows.Forms.DialogResult.OK == pd.ShowDialog()) //如果确认,将会覆盖所有的打印参数设置 { printDocument.Print(); //打印 } } return true; } #endregion #region 打印开始前绑定数据源 #region 条码生成 public static byte[] Bitmap2Byte(Bitmap bitmap) { using (MemoryStream stream = new MemoryStream()) { bitmap.Save(stream, ImageFormat.Bmp); byte[] data = new byte[stream.Length]; stream.Seek(0, SeekOrigin.Begin); stream.Read(data, 0, Convert.ToInt32(stream.Length)); return data; } } #endregion #region 数据源 void printDocument_BeginPrint(object sender, PrintEventArgs e) { #region 重写数据源 options = new EncodingOptions { Width = 200, Height = 40 }; writer = new BarcodeWriter(); writer.Format = BarcodeFormat.CODE_128; writer.Options = options; #endregion #region 加载报表源 ReportViewer rvDoc = new ReportViewer(); rvDoc.LocalReport.ReportEmbeddedResource = RdlcUrl; rvDoc.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", GoodsTable)); PrintStream(rvDoc.LocalReport); #endregion } #endregion #endregion #region 获取rdlc文件作为打印数据源 private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) { //如果需要将报表输出的数据保存为文件,请使用FileStream对象。 Stream stream = new MemoryStream(); m_streams.Add(stream); return stream; } public void PrintStream(LocalReport rvDoc) { //获取LocalReport中的报表页面方向 isLandSapces = rvDoc.GetDefaultPageSettings().IsLandscape; Export(rvDoc); } private void Export(LocalReport report) { //绑定打印边距 decimal Left = PageLeft / 100; decimal Top = PageTop / 100; decimal Right = PageRight / 100; decimal Bottom = PageBottom / 100; string deviceInfo = "" + "  EMF" + " " + Top + "in" + " " + Left + "in" + " " + Right + "in" + " " + Bottom + "in" + ""; Warning[] warnings; m_streams = new List(); //将报表的内容按照deviceInfo指定的格式输出到CreateStream函数提供的Stream中。 report.Render("Image", deviceInfo, CreateStream, out warnings); foreach (Stream stream in m_streams) stream.Position = 0; } void printDocument_PrintPage(object sender, PrintPageEventArgs e) { //打印啥东东就在这写了 //Metafile对象用来保存EMF或WMF格式的图形, //我们在前面将报表的内容输出为EMF图形格式的数据流。 Metafile pageImage = new Metafile(m_streams[page]); //调整打印机区域的边距 System.Drawing.Rectangle adjustedRect = new System.Drawing.Rectangle(0, 0, e.PageBounds.Width, e.PageBounds.Height); //获取报告内容 //这里的Graphics对象实际指向了打印机 e.Graphics.DrawImage(pageImage, e.PageBounds); page++; //设置是否需要继续打印 e.HasMorePages = (page < m_streams.Count); if (page == m_streams.Count) { page = 0; m_streams = null; } } #endregion #region 打印结束后触发 static void printDocument_EndPrint(object sender, PrintEventArgs e) { } #endregion #endregion } }