最近项目中要实现标签打印的功能,有几个条件

  • 标签模板可以事先生成,用的是CodeSoft软件
  • 标签模板里面有二维码
  • 标签模板里面有一些变量,要求打印的时候自动填充
  • 产线电脑上没有安装CodeSoft,即便安装也不能使用,因为没有License

从开始计划做标签打印开始,做了三套解决方案,难度和依赖条件各不相同

  1. 利用Excel
  2. CodeSoft API
  3. 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

用代码实现标签打印的三种方式相关推荐

  1. 将代码注入到进程的三种方式

    [源码下载] 介绍 在Code Project网站有许多关于password spy的文章,但是这些都是基于Windows Hooks的,还有没有其他方式能实现这种效果呢?是的,有,不过,先让我们简要 ...

  2. JS-01-在HTML中嵌入JavaScript代码的三种方式

    JS-01-在HTML中嵌入JavaScript代码的三种方式 1.JavaScript概述 Web的组成有HTML.CSS还有即将要学习的JavaScript(简称JS). CSS和JS主要是服务于 ...

  3. 在HTML 中嵌入 JS 代码的三种方式

    一,在HTML中嵌入JS代码的第一种方式:行间事件 行间事件是指将JavaScript函数写到HTML元素中的执行事件. 1.JavaScript 是一种事件驱动型的编程语言,通常都是在发生某个事件的 ...

  4. JavaScript——关于JavaScript、在HTML中嵌入JS代码的三种方式、变量

    文章目录 JavaScript 01 关于JavaScript 1.1 JS的发展历史 1.2 JS的特性 1.3 JS的组成 1.4 JSP和JS的区别 02 在HTML中嵌入JS代码的三种方式 2 ...

  5. 代码示例:Java中定义数组的三种方式

    在Java中,数组的定义有三种方式,其基本语法格式如下: 数组类型[] 数组名 = new 数组类型[数组长度]; 数组类型[] 数组名 = new 数组类型[]{数组元素0,数组元素1,...}; ...

  6. Web CSS #id 标签选择器 style display 类选择器.class 使用CSS的三种方式 列表装饰 绝对定位

    文章目录 CSS使用的三种方式 内联定义方式 实现代码 实现结果 样式块方式 实现代码 显示结果 链入外部样式表文件 实现代码 图是结果 #id 选择器 #id名 实现代码 实现结果 标签选择器 标签 ...

  7. Winform中通过NPOI导出Excel的三种方式(HSSFWorkbook,XSSFWorkbook,SXSSFWorkbook)附代码下载

    场景 HSSFworkbook,XSSFworkbook,SXSSFworkbook区别 HSSFWorkbook: 是操作Excel2003以前(包括2003)的版本,扩展名是.xls:导出exce ...

  8. Java动物类enjoy方法打印_Java反射学习-2 - 获取Class对象的三种方式

    1 packagecn.tx.reflect;2 3 importjava.lang.reflect.Constructor;4 importjava.lang.reflect.Field;5 imp ...

  9. html语言闪烁特效代码,css3 实现文字闪烁效果的三种方式示例代码

    1.通过改变透明度来实现文字的渐变闪烁,效果图: 文字闪烁 星星之火可以燎原 .myclass{ letter-spacing:5px;/*字间距*/ color: red; font-weight: ...

最新文章

  1. 解决POST数据时因启用Csrf出现的400错误
  2. oracle中类似indexof用法_instr函数
  3. EOS账户系统(2)账户和钱包
  4. [北京活动] 5月11日 PMCAFF创业私密分享会邀请函已经下发
  5. mysql事物日志工具_MySQL——常用工具和日志
  6. Puffer:专注拥塞控制、带宽预测和ABR
  7. java hprof_java 性能之 hprof
  8. Kafka单节点多broker的部署和使用
  9. python 双指针法_leetcode 11 题解:python3@ 官方题解_暴力法_双指针法
  10. attr 和 prop 区别
  11. 图像金字塔——实现图像融合
  12. 向量加减法首尾规律_向量的加减法
  13. oracle公司的crm系统,原创-CRM客户关系管理系统设计-jsp+oracle
  14. 制作纯净的U盘启动盘(避免纯净系统安装后却内置垃圾软件)
  15. Https网址在线安全检测网站
  16. ESP32/ESP32S2直连腾讯云,实现微信小程序控制
  17. html svg折线带圆角,SVG / d3.js上的矩形的一个角的圆角(svg / d3.js rounded corner
  18. javascript网页设计期末作业 购物网站
  19. 使用CSS画一个扇形
  20. 窃密软件访问的文件和注册表

热门文章

  1. 投资和投机的区别是什么?
  2. Axure-照片墙制作
  3. Cacti完全使用手册 ( 让你快速个性化使用Cacti )
  4. Mac的恶意软件真的比较少吗?
  5. 从零开始学习恶意软件聚类可视化
  6. 基于单片机控制的智能窗帘控制系统的设计与实现
  7. Sumo学习日记 - day1 从traci开始
  8. Google Code jam Qualification Round 2015 --- Problem A. Standing Ovation
  9. 基于MATLAB的车道线识别、自动驾驶识别
  10. 幸存者偏差Survivorship Bias