一种办法是用标签设计软件做好模板,在标签设计软件中打印,这种办法不用写代码,但对我来说觉得不能接受,所以尝试代码解决问题。
网上搜索一番,找不到什么资料,基本都是说发送ZPL、EPL指令到打印机,而且还是COM/LPT口连接打印机。后来研究.net的打印类库,发现是用绘图方式打印至打印机的,也叫GDI打印,于是思路有了点突破,那我可以用报表工具画好标签,运行报表时,把结果输出位图,再发送至打印机。
后来又找到一种更好的办法,利用标签设计软件做好模板,打印至本地文件,把其中的ZPL、EPL指令拷贝出来,替换其中动态变化的内容为变量名,做成一个模板文本,在代码中动态替换变量,再把指令输出至打印机。
折腾了几天,终于把这两种思路都实现了,顺便解决了USB接口打印机的ZPL、EPL指令发送问题。
今天有点困,改天再详细讲解一下这两种思路的具体实现。
==============================================================================================================
如何获取标签设计软件输出至打印的ZPL指令?安装好打印机驱动,修改打印机端口,新建一个打印机端口,类型为本地端口,端口名称设置为C:\printer.log,再用标签设计软件打印一次,此文件中就有ZPL指令了。
==============================================================================================================
2012-06-02:发布代码ZebraPrintHelper.cs。
==============================================================================================================
2013-01-17:发布代码ZebraPrintHelper.cs,修正BUG,新增TCP打印支持Zebra无线打印QL320+系列打印机。已经生产环境实际应用,支持POS小票、吊牌、洗水唛、条码、文本混合标签打印。因涉及公司源码,只能截图VS解决方案给大家看。
==============================================================================================================
ZebraPrintHelper类代码:
调用例子代码:
private void BackgroundWorkerPrint_DoWork(object sender, DoWorkEventArgs e) {
BackgroundWorker worker = sender as BackgroundWorker;
int i = 0, nextRemainder = 0, count = this._listBarcodeData.Count;
bool flag = true;
float pageWidth, pageHeight;
int dpiX, dpiY, perPaperFactor;
string reportPath = string.Format(@"{0}/Reports/{1}", Application.StartupPath, this._modelType);
PrintLog printLog = new PrintLog() { Operater = LoginName };
PrinterSettings printerSettings = new PrinterSettings() { PrinterName = PrintParam, Copies = 1 };
using (StreamReader tr = new StreamReader(this.ModelFilePath)) {
XElement xe = XDocument.Load(tr).Root.Elements()
.Elements(XName.Get("ModelType")).First(x => x.Value == this._modelType).Parent;
pageWidth = float.Parse(xe.Elements(XName.Get("PageWidth")).First().Value);
pageHeight = float.Parse(xe.Elements(XName.Get("PageHeight")).First().Value);
dpiX = int.Parse(xe.Elements(XName.Get("DotPerInchX")).First().Value);
dpiY = int.Parse(xe.Elements(XName.Get("DotPerInchY")).First().Value);
perPaperFactor = int.Parse(xe.Elements(XName.Get("PerPaperFactor")).First().Value);
this._no = int.Parse(xe.Elements(XName.Get("NO")).First().Value);
}
using (LocalReportHelper printHelper = new LocalReportHelper(reportPath)) {
printHelper.PrintTypeNO = this._no;
printHelper.PrintLogInformation = printLog;
printHelper.ExportImageDeviceInfo.DpiX = dpiX;
printHelper.ExportImageDeviceInfo.DpiY = dpiY;
printHelper.ExportImageDeviceInfo.PageWidth = pageWidth;
printHelper.ExportImageDeviceInfo.PageHeight = pageHeight;
foreach (BarcodeData bdCurrent in this._listBarcodeData) {
if (worker.CancellationPending == true) {
e.Cancel = true;
break;
}
else {
try {
DataSet dsCurrent = this.GetDataForPrinterByBarcode(bdCurrent.Barcode, bdCurrent.IncreaseType);
DataSet dsNext = null, dsPrevious = dsCurrent.Copy();
int amount = this._printType == 0 ? 1 : bdCurrent.Amount - nextRemainder;
int copies = amount / perPaperFactor;
int remainder = nextRemainder = amount % perPaperFactor;
Action actPrint = (ds, duplicates, barcodes, amountForLog) => {
printHelper.PrintLogInformation.Barcode = barcodes;
printHelper.PrintLogInformation.Amount = amountForLog;
if (this.PrintType == 0 && DeviceType == DeviceType.DRV) {
printerSettings.Copies = (short)duplicates;
printHelper.WindowsDriverPrint(printerSettings, dpiX, ds);
}
else {
printHelper.OriginalPrint(DeviceType, ds, duplicates, PrintParam);
}
};
if (copies > 0) {
int amountForCopy = copies;
if (perPaperFactor > 1) {
DataSet dsCurrentCopy = dsCurrent.CopyForBarcode();
dsCurrent.Merge(dsCurrentCopy);
amountForCopy = copies * perPaperFactor;
}
actPrint.Invoke(dsCurrent, copies, bdCurrent.Barcode, amountForCopy);
}
if (remainder > 0) {
int nextIndex = i + 1;
string barcodes = bdCurrent.Barcode;
if (nextIndex < count) {
BarcodeData bdNext = this._listBarcodeData[nextIndex];
dsNext = this.GetDataForPrinterByBarcode(bdNext.Barcode, bdNext.IncreaseType);
dsPrevious.Merge(dsNext);
barcodes += "," + bdNext.Barcode;
}
actPrint.Invoke(dsPrevious, 1, barcodes, 1);
}
worker.ReportProgress(i++, string.Format("正在生成 {0} 并输送往打印机...", bdCurrent.Barcode));
if (this._printType == 0) {
count = 1;
flag = true;
break;
}
}
catch (Exception ex) {
flag = false;
e.Result = ex.Message;
break;
}
}
}
if (!e.Cancel && flag) {
e.Result = string.Format("打印操作成功完成,共处理条码 {0} 条", count);
}
}
}
LocalReportHelper类代码:
using System;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Microsoft.Reporting.WinForms;
using Umisky.BarcodePrint.Core;
namespace Umisky.BarcodePrint.Codes {
public class LocalReportHelper : IDisposable {
#region Properties
public String LocalReportPath { get; set; }
public LocalReport LocalReportInstance { get; private set; }
public GraphDeviceInfo ExportImageDeviceInfo { get; set; }
public PrintLog PrintLogInformation { get; set; }
public int PrintTypeNO { get; set; }
#endregion
private Stream _stream;
private int _bmpDPI;
private DataSet _ds;
public LocalReportHelper(String reportPath)
: this(reportPath, new GraphDeviceInfo() {
ColorDepth = 1,
DpiX = 203,
DpiY = 203,
PageWidth = 8f,
PageHeight = 12.2f,
MarginTop = 0.2f
}) { }
public LocalReportHelper(String reportPath, GraphDeviceInfo deviceInfo) {
this._bmpDPI = 96;
this.LocalReportPath = reportPath;
this.ExportImageDeviceInfo = deviceInfo;
this.LocalReportInstance = new LocalReport() { ReportPath = reportPath };
this.LocalReportInstance.SubreportProcessing += new SubreportProcessingEventHandler(LocalReportInstance_SubreportProcessing);
}
private void LocalReportInstance_SubreportProcessing(object sender, SubreportProcessingEventArgs e) {
foreach (DataTable dt in this._ds.Tables) {
e.DataSources.Add(new ReportDataSource(dt.TableName, dt));
}
}
public void Dispose() {
this.ExportImageDeviceInfo = null;
this.LocalReportInstance = null;
this.LocalReportPath = null;
this._ds = null;
}
public void AddReportParameter(string paramName, string value) {
this.LocalReportInstance.SetParameters(new ReportParameter(paramName, value));
}
#region Export hang title image by reporting services
private void AddWashIcones() {
this.LocalReportInstance.EnableExternalImages = true;
this.LocalReportInstance.SetParameters(new ReportParameter("AppPath", Application.StartupPath));
}
private void AddBarcodesAssembly() {
this.LocalReportInstance.AddTrustedCodeModuleInCurrentAppDomain(ConfigurationManager.AppSettings["BarcodesAssembly"]);
}
private Stream CreateStreamCallBack(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) {
string tempFolderPath = string.Concat(Environment.GetEnvironmentVariable("TEMP"), "/");
this._stream = new FileStream(string.Concat(tempFolderPath, name, ".", fileNameExtension), FileMode.Create);
return this._stream;
}
private void Export() {
if (string.IsNullOrEmpty(this.LocalReportPath) ||
this.LocalReportInstance == null ||
this.ExportImageDeviceInfo == null) {
throw new InvalidExpressionException("Invalid parameters");
}
if (this.PrintTypeNO >= -1 || this.PrintTypeNO == -3) {
this.AddBarcodesAssembly();
if (this.PrintTypeNO >= 0) {
this.AddWashIcones();
}
}
if (this.PrintTypeNO >= 0) {
this.LocalReportInstance.DataSources.Clear();
foreach (DataTable dt in this._ds.Tables) {
this.LocalReportInstance.DataSources.Add(new ReportDataSource(dt.TableName, dt));
}
}
this.LocalReportInstance.Refresh();
if (this._stream != null) {
this._stream.Close();
this._stream = null;
}
Warning[] warnings;
this.LocalReportInstance.Render(
"Image",
this.ExportImageDeviceInfo.ToString(),
PageCountMode.Actual,
CreateStreamCallBack,
out warnings);
this._stream.Position = 0;
}
private void SaveLog() {
using (Bitmap image = (Bitmap)Image.FromStream(this._stream)) {
image.SetResolution(96, 96);
using (MemoryStream ms = new MemoryStream()) {
image.Save(ms, ImageFormat.Jpeg);
this.PrintLogInformation.BarcodeImage = ms.ToArray();
}
}
LogHelper.AddLog(this.PrintLogInformation);
if (this._stream != null) {
this._stream.Close();
this._stream = null;
}
}
#endregion
#region Windows driver print
private void PrintPage(object sender, PrintPageEventArgs ev) {
Bitmap bmp = (Bitmap)Image.FromStream(this._stream);
bmp.SetResolution(this._bmpDPI, this._bmpDPI);
ev.Graphics.DrawImage(bmp, 0, 0);
ev.HasMorePages = false;
}
///
/// Print by windows driver
///
/// .net framework PrinterSettings class, including some printer information
/// the bitmap image resoluation, dots per inch
public void WindowsDriverPrint(PrinterSettings printerSettings, int bmpDPI, DataSet ds) {
this._ds = ds;
this.Export();
if (this._stream == null) {
return;
}
this._bmpDPI = bmpDPI;
PrintDocument printDoc = new PrintDocument();
printDoc.DocumentName = "条码打印";
printDoc.PrinterSettings = printerSettings;
printDoc.PrintController = new StandardPrintController();
if (!printDoc.PrinterSettings.IsValid) {
if (this._stream != null) {
this._stream.Close();
this._stream = null;
}
MessageBox.Show("Printer found errors, Please contact your administrators!", "Print Error");
return;
}
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
printDoc.Print();
this.SaveLog();
}
#endregion
#region Original print
///
/// Send the file to the printer or use the printer command
///
/// The port(LPT,COM,DRV) which the device connecting
/// Total number for print
/// The report datasource
/// Print parameters
/// The built-in printer programming language, you can choose EPL or ZPL
public void OriginalPrint(DeviceType deviceType,
DataSet ds,
int copies = 1,
string printParam = null,
ProgrammingLanguage printLanguage = ProgrammingLanguage.ZPL) {
this._ds = ds;
this.Export();
if (this._stream == null) {
return;
}
int port = 1;
int.TryParse(printParam, out port);
int length = (int)this._stream.Length;
byte[] bytes = new byte[length];
this._stream.Read(bytes, 0, length);
ZebraPrintHelper.Copies = copies;
ZebraPrintHelper.PrinterType = deviceType;
ZebraPrintHelper.PrinterName = printParam;
ZebraPrintHelper.Port = port;
ZebraPrintHelper.PrinterProgrammingLanguage = printLanguage;
ZebraPrintHelper.PrintGraphics(bytes);
this.SaveLog();
}
#endregion
}
}
转自:http://blog.csdn.net/ldljlq/article/details/7338772#