用代码实现标签打印的三种方式
最近项目中要实现标签打印的功能,有几个条件
- 标签模板可以事先生成,用的是CodeSoft软件
- 标签模板里面有二维码
- 标签模板里面有一些变量,要求打印的时候自动填充
- 产线电脑上没有安装CodeSoft,即便安装也不能使用,因为没有License
从开始计划做标签打印开始,做了三套解决方案,难度和依赖条件各不相同
- 利用Excel
- CodeSoft API
- ZPL+Win32 API
- 利用Excel
这是一个半自动化的方案,主要想法是在Excel里面做好模板,变量的部分通过编写VBA脚本,读取SQL Server数据库里面的内容进行填充,填充好了之后,手动打印。缺点是没有办法生成二维码。 --- Pass
代码
Public Sub SynTableConfig() Dim cnn As New ADODB.Connection, sh As Worksheet Dim rs As New ADODB.Recordset Dim cnnStr As String, SQL As String'建立与SQL Server数据库服务器的连接 cnnStr = "Provider=SQLOLEDB;Initial Catalog=" & myDataBase & ";User ID=" & myname & ";Password=" & mypassword & ";Data Source=" & serverip cnn.ConnectionString = cnnStr cnn.Open SQL = "select * from sys_table where id='123' order by 表名称" Set rs = cnn.Execute(SQL) While Not rs.EOF ............. rs.MoveNext Wend rs.Close Set rs = Nothing cnn.Close Set cnn = Nothing End Sub
- CodeSoft API
CodeSoft企业版提供了ActiveX控件,可以在C#中添加对Lppx2.tlb的引用,调用相关API对CodeSoft编辑好的Label文件进行变量替换等操作,然后打印。编程难度不大,但是有个致命限制,要安装CodeSoft软件并插入usbkey。公司虽然买了license,但是仅限于工程师编辑Label模板文件,产线电脑上没有安装软件,更不可能插入usbkey,因为很贵。--- Pass
代码如下
class CodeSoft{string _printerName = "";public CodeSoft(string printerName){_printerName = printerName;}public void Print(string labelFileName, Dictionary<string,string> parameters){LabelManager2.Application labApp = null;LabelManager2.Document doc = null;string labFileName = System.Windows.Forms.Application.StartupPath + @"\" + labelFileName;try{if (!File.Exists(labFileName)){throw new FileNotFoundException("File not exsit", labFileName);}labApp = new LabelManager2.Application();labApp.Documents.Open(labFileName, false);doc = labApp.ActiveDocument;doc.Printer.SwitchTo(_printerName);string printerName = labApp.ActivePrinterName;foreach (string parameterName in parameters.Keys){doc.Variables.FormVariables.Item(parameterName).Value = parameters[parameterName];}doc.PrintDocument(1);}catch (Exception ex){throw ex;}finally{labApp.Documents.CloseAll(true);//doc.Quit();doc = null;doc = null;GC.Collect(0);}}}
- ZPL+Win32 API
ZPL是Zebra公司的标签标记语言,描述了标签上有哪些内容,何种字体,何种颜色等等。大部分标签打印机应该都支持,最起码我们的430t是可以支持的。具体打印的思路是利用CodeSoft软件,生成一个PRN文件(具体怎么生成不知道)。PRN文件里面的内容就是用ZPL描述的标签。我用程序读入这个PRN文件,将里面的变量替换掉,生成一个新文件,然后调用系统Native的打印功能,进行打印。
代码如下
class PrinterHelper{// Structure and API declarions:[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]public class DOCINFOA{[MarshalAs(UnmanagedType.LPStr)]public string pDocName;[MarshalAs(UnmanagedType.LPStr)]public string pOutputFile;[MarshalAs(UnmanagedType.LPStr)]public string pDataType;}[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool ClosePrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool EndDocPrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool StartPagePrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool EndPagePrinter(IntPtr hPrinter);[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);// SendBytesToPrinter()// When the function is given a printer name and an unmanaged array// of bytes, the function sends those bytes to the print queue.// Returns true on success, false on failure.public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount){Int32 dwError = 0, dwWritten = 0;IntPtr hPrinter = new IntPtr(0);DOCINFOA di = new DOCINFOA();bool bSuccess = false; // Assume failure unless you specifically succeed. di.pDocName = "My C#.NET RAW Document";di.pDataType = "RAW";// Open the printer.if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)){// Start a document.if (StartDocPrinter(hPrinter, 1, di)){// Start a page.if (StartPagePrinter(hPrinter)){// Write your bytes.bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);EndPagePrinter(hPrinter);}EndDocPrinter(hPrinter);}ClosePrinter(hPrinter);}// If you did not succeed, GetLastError may give more information// about why not.if (bSuccess == false){dwError = Marshal.GetLastWin32Error();}return bSuccess;}public static bool SendFileToPrinter(string szPrinterName, string szFileName, Dictionary<string, string> parameters){string fileName = AssignValueToVariables(szFileName, parameters);return SendFileToPrinter(szPrinterName, fileName);}public static bool SendFileToPrinter(string szPrinterName, string szFileName){// Open the file.FileStream fs = new FileStream(szFileName, FileMode.Open);// Create a BinaryReader on the file.BinaryReader br = new BinaryReader(fs);// Dim an array of bytes big enough to hold the file's contents.Byte[] bytes = new Byte[fs.Length];bool bSuccess = false;// Your unmanaged pointer.IntPtr pUnmanagedBytes = new IntPtr(0);int nLength;nLength = Convert.ToInt32(fs.Length);// Read the contents of the file into the array.bytes = br.ReadBytes(nLength);// Allocate some unmanaged memory for those bytes.pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);// Copy the managed byte array into the unmanaged array.Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);// Send the unmanaged bytes to the printer.bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);// Free the unmanaged memory that you allocated earlier. Marshal.FreeCoTaskMem(pUnmanagedBytes);return bSuccess;}private static string AssignValueToVariables(string szFileName, Dictionary<string, string> parameters){StreamReader sr = new StreamReader(szFileName, Encoding.Default);string line;StringBuilder sb = new StringBuilder();while ((line = sr.ReadLine()) != null){sb.AppendLine(line);}string newContent = UpdateVariable(sb.ToString(), parameters);return WriteToFile(szFileName, newContent);}private static string WriteToFile(string szFileName, string newContent){string fullFileName = szFileName + ".new.PRN";if (File.Exists(fullFileName)){File.Delete(fullFileName);}using (FileStream fs = new FileStream(fullFileName, FileMode.Create)){using (StreamWriter sw = new StreamWriter(fs)){sw.Write(newContent);sw.Flush();}}return fullFileName;}private static string UpdateVariable(string content, Dictionary<string, string> parameters){string newContent = content;foreach (string parameterName in parameters.Keys){string parameterValue = parameters[parameterName];newContent = newContent.Replace(string.Format("_tag${0}$tag_", parameterName), parameterValue);}return newContent;}public static bool SendStringToPrinter(string szPrinterName, string szString){IntPtr pBytes;Int32 dwCount;// How many characters are in the string?dwCount = szString.Length;// Assume that the printer is expecting ANSI text, and then convert// the string to ANSI text.pBytes = Marshal.StringToCoTaskMemAnsi(szString);// Send the converted ANSI string to the printer. SendBytesToPrinter(szPrinterName, pBytes, dwCount);Marshal.FreeCoTaskMem(pBytes);return true;}}
转载于:https://www.cnblogs.com/QiuTianBaBa/p/6730829.html
用代码实现标签打印的三种方式相关推荐
- 将代码注入到进程的三种方式
[源码下载] 介绍 在Code Project网站有许多关于password spy的文章,但是这些都是基于Windows Hooks的,还有没有其他方式能实现这种效果呢?是的,有,不过,先让我们简要 ...
- JS-01-在HTML中嵌入JavaScript代码的三种方式
JS-01-在HTML中嵌入JavaScript代码的三种方式 1.JavaScript概述 Web的组成有HTML.CSS还有即将要学习的JavaScript(简称JS). CSS和JS主要是服务于 ...
- 在HTML 中嵌入 JS 代码的三种方式
一,在HTML中嵌入JS代码的第一种方式:行间事件 行间事件是指将JavaScript函数写到HTML元素中的执行事件. 1.JavaScript 是一种事件驱动型的编程语言,通常都是在发生某个事件的 ...
- JavaScript——关于JavaScript、在HTML中嵌入JS代码的三种方式、变量
文章目录 JavaScript 01 关于JavaScript 1.1 JS的发展历史 1.2 JS的特性 1.3 JS的组成 1.4 JSP和JS的区别 02 在HTML中嵌入JS代码的三种方式 2 ...
- 代码示例:Java中定义数组的三种方式
在Java中,数组的定义有三种方式,其基本语法格式如下: 数组类型[] 数组名 = new 数组类型[数组长度]; 数组类型[] 数组名 = new 数组类型[]{数组元素0,数组元素1,...}; ...
- Web CSS #id 标签选择器 style display 类选择器.class 使用CSS的三种方式 列表装饰 绝对定位
文章目录 CSS使用的三种方式 内联定义方式 实现代码 实现结果 样式块方式 实现代码 显示结果 链入外部样式表文件 实现代码 图是结果 #id 选择器 #id名 实现代码 实现结果 标签选择器 标签 ...
- Winform中通过NPOI导出Excel的三种方式(HSSFWorkbook,XSSFWorkbook,SXSSFWorkbook)附代码下载
场景 HSSFworkbook,XSSFworkbook,SXSSFworkbook区别 HSSFWorkbook: 是操作Excel2003以前(包括2003)的版本,扩展名是.xls:导出exce ...
- Java动物类enjoy方法打印_Java反射学习-2 - 获取Class对象的三种方式
1 packagecn.tx.reflect;2 3 importjava.lang.reflect.Constructor;4 importjava.lang.reflect.Field;5 imp ...
- html语言闪烁特效代码,css3 实现文字闪烁效果的三种方式示例代码
1.通过改变透明度来实现文字的渐变闪烁,效果图: 文字闪烁 星星之火可以燎原 .myclass{ letter-spacing:5px;/*字间距*/ color: red; font-weight: ...
最新文章
- 解决POST数据时因启用Csrf出现的400错误
- oracle中类似indexof用法_instr函数
- EOS账户系统(2)账户和钱包
- [北京活动] 5月11日 PMCAFF创业私密分享会邀请函已经下发
- mysql事物日志工具_MySQL——常用工具和日志
- Puffer:专注拥塞控制、带宽预测和ABR
- java hprof_java 性能之 hprof
- Kafka单节点多broker的部署和使用
- python 双指针法_leetcode 11 题解:python3@ 官方题解_暴力法_双指针法
- attr 和 prop 区别
- 图像金字塔——实现图像融合
- 向量加减法首尾规律_向量的加减法
- oracle公司的crm系统,原创-CRM客户关系管理系统设计-jsp+oracle
- 制作纯净的U盘启动盘(避免纯净系统安装后却内置垃圾软件)
- Https网址在线安全检测网站
- ESP32/ESP32S2直连腾讯云,实现微信小程序控制
- html svg折线带圆角,SVG / d3.js上的矩形的一个角的圆角(svg / d3.js rounded corner
- javascript网页设计期末作业 购物网站
- 使用CSS画一个扇形
- 窃密软件访问的文件和注册表