前言
最近做一個項目就是winform程序去控制設備,通過modbus-rtu協議去通訊。做的過程中上位機還牽扯到與其他系統對接的問題,當對接好其他系統數據后將數據打印出一個小票,上位機端用serialport來發送和接收下位機指令,下位機接收到上位機的發送的指令設備就做某個動作,設備動作完成將狀態發送給上位機,然后在winform界面呈現設備的狀態,整體的工作原理大概就是這樣子,具體業務就不方便寫入到博客中,打印的需求是隨着打印的內容長短決定打印紙的出紙長度,於是乎在winform中使用rdlc的想法就冒出來了,且看下面步驟
winform 使用rdlc打印小票其中包含動態顯示多條形碼步驟如下
1、 去nuget中download引用一個Microsoft.ReportingServices.ReportViewerControl.Winforms,通過nuget引入進來時會自動添加Microsoft.ReportViewer.WinForms、Microsoft.ReportViewer.Common.dll、Microsoft.ReportViewer.DataVisualization.dll、Microsoft.ReportViewer.Design.dll、Microsoft.ReportViewer.ProcessingObjectModel.dll,一共就是5個dll庫才能用LocalReport
2、添加rdlc文件,且設計rdlc參數和對象數據集,通過 “表” 組件來循環輸出數據,其中包括條碼,項目名稱等等內容,rdlc打印條碼,這里后台將數據傳輸到rdlc時需要將條碼圖片轉成條碼字節數組byte[],然后在rdlc中放一個圖片組件,將數據集中條碼字節數組給到表達式中即可rdlc循環打印條碼輸出
rdlc數據的組裝,條碼生成圖片要用到BarcodeLib.dll
rdlc自動打印條碼的結果
rdlc打印小票其中包含動態顯示多條形碼具體實現代碼請看以下代碼
private void button1_Click(object sender, EventArgs e) { #region test method var fileurl = Application.StartupPath + @"\data.txt";//數據源 if (!File.Exists(fileurl)) { MessageBox.Show("路徑不存在"); return; } var resultStr = File.ReadAllText(fileurl); #endregion var XmlString = Utils.SoapReplace(Utils.ToTxt(resultStr));//解析數據源 Utils.WriteCommandLog("LIS返回信息:" + XmlString); var result = Utils.DeserializeXmlToObject<Response>(XmlString);//xml數據源轉換Response對象 if (result.Code == -1) return; var data = result.LabInfos;//Lis返回的數據結果
#region 回執單打印 LocalReport report = new LocalReport(); //設置需要打印的報表的文件名稱。 report.ReportPath = AppDomain.CurrentDomain.BaseDirectory + @"\receipt.rdlc"; /*自動打印*/ var list = new List<reportData>(); for (int i = 0; i < data.Count; i++) { var item = data[i]; var barcodearr = Utils.ImageToBytes(CreateBarcodePicture(item.LabNum, 418, 50)); list.Add(new reportData() { BarCode = item.LabNum, BarCodeImageArr = barcodearr, PatNo = item.HospNum, Priority = item.Priority, Source = item.Source, TakeReportAddress = item.TakeReportAddress, TakeReportDesc = item.TakeReportDesc, TestItemDesc = item.TestItemDesc }); } ReportDataSource reportDataSource = new ReportDataSource(); reportDataSource.Name = "DataSet1"; reportDataSource.Value = list;//要輸出的數據集 ReportParameter DropPricePrint_rp1 = new ReportParameter("cnname", "李歐"); ReportParameter DropPricePrint_rp2 = new ReportParameter("sex", "男"); ReportParameter DropPricePrint_rp3 = new ReportParameter("age", "30歲"); ReportParameter DropPricePrint_rp4 = new ReportParameter("PrintTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); ReportParameter DropPricePrint_rp5 = new ReportParameter("hospnum", "0001062975"); report.SetParameters(new ReportParameter[] { DropPricePrint_rp1, DropPricePrint_rp2, DropPricePrint_rp3, DropPricePrint_rp4, DropPricePrint_rp5 }); report.DataSources.Add(reportDataSource); report.Refresh(); RDLCPrinter.Run(report, "Microsoft XPS Document Writer"); #endregion }
根據字符串生成條碼圖片對象( 需添加引用:BarcodeLib.dll )
/// <summary> /// 根據字符串生成條碼圖片( 需添加引用:BarcodeLib.dll ) /// </summary> /// <param name="BarcodeString">條碼字符串</param> /// <param name="ImgWidth">圖片寬帶</param> /// <param name="ImgHeight">圖片高度</param> /// <returns></returns> public System.Drawing.Image CreateBarcodePicture(string BarcodeString, int ImgWidth, int ImgHeight) { BarcodeLib.Barcode b = new BarcodeLib.Barcode();//實例化一個條碼對象 BarcodeLib.TYPE type = BarcodeLib.TYPE.CODE128;//編碼類型 //獲取條碼圖片 System.Drawing.Image BarcodePicture = b.Encode(type, BarcodeString, System.Drawing.Color.Black, System.Drawing.Color.White, ImgWidth, ImgHeight); b.Dispose(); return BarcodePicture; }
RDLCPrinter 通過RDLC向默認打印機輸出打印報表
using System; using System.Collections.Generic; using System.Drawing.Imaging; using System.Drawing.Printing; using System.IO; using System.Text; using Microsoft.Reporting.WinForms; namespace System { /// <summary> /// 通過RDLC向默認打印機輸出打印報表 /// </summary> public class RDLCPrinter : IDisposable { /// <summary> /// 當前打印頁號 /// </summary> static int m_currentPageIndex; /// <summary> /// RDCL轉換stream一頁對應一個stream /// </summary> static List<Stream> m_streams; /// <summary> /// 把report輸出成stream /// </summary> /// <param name="report">傳入需要Export的report</param> private void Export(LocalReport report) { string deviceInfo = "<DeviceInfo>" + " <OutputFormat>EMF</OutputFormat>" + //" <PageWidth>8cm</PageWidth>" + //" <PageHeight>20in</PageHeight>" + " <MarginTop>0in</MarginTop>" + " <MarginLeft>0in</MarginLeft>" + " <MarginRight>0in</MarginRight>" + " <MarginBottom>0in</MarginBottom>" + "</DeviceInfo>"; Warning[] warnings; m_streams = new List<Stream>(); report.Render("Image", deviceInfo, CreateStream, out warnings); foreach (Stream stream in m_streams) stream.Position = 0; } /// <summary> /// 創建具有指定的名稱和格式的流。 /// </summary> private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) { Stream stream = new FileStream(name + "." + fileNameExtension, FileMode.Create); m_streams.Add(stream); return stream; } /// <summary> /// 打印輸出 /// </summary> private void PrintPage(object sender, PrintPageEventArgs ev) { Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]); ev.Graphics.DrawImage(pageImage, ev.PageBounds); m_currentPageIndex++; ev.HasMorePages = (m_currentPageIndex < m_streams.Count); } /// <summary> /// 打印預處理 /// 打印機名稱: Microsoft XPS Document Writer /// </summary> private void Print(string printerName) { PrintDocument printDoc = new PrintDocument(); if (m_streams == null || m_streams.Count == 0) return; printDoc.PrinterSettings.PrinterName = printerName; if (!printDoc.PrinterSettings.IsValid) { string msg = String.Format("Can't find printer \"{0}\".", printerName); throw new Exception(msg); } printDoc.PrintPage += new PrintPageEventHandler(PrintPage); StandardPrintController spc = new StandardPrintController();//指定打印控制器 printDoc.PrintController = spc; printDoc.Print(); } public void Dispose() { if (m_streams != null) { foreach (Stream stream in m_streams) stream.Close(); m_streams = null; } } /// <summary> /// 對外接口,啟動打印 /// </summary> /// <param name="report">打印報表組件</param> /// <param name="printerName">打印機名稱</param> public static void Run(LocalReport report, string printerName) { m_currentPageIndex = 0; RDLCPrinter billPrint = new RDLCPrinter(); billPrint.Export(report); billPrint.Print(printerName); billPrint.Dispose(); } } }
當然這里也提供了源碼給您下載,如您需要請點擊 【rdlc動態打印多條形碼源碼例子】 提取碼: 6p5v
對於rdlc如何打印小票其中包含動態顯示多條形碼的解決方法對你有用,那就拿去不用謝