ZPL打印中文信息
博客来源:http://www.cnblogs.com/Geton/p/3595312.html
相信各位在实际的项目中,需要开发打条码模块的也会有不少,很多同行肯定也一直觉得斑马打印机很不错,但是ZPL打印中文字符很麻烦。如果购买字体卡,或者通过CODESOFT,BARTENDER,LABELVIEW等有控件的条码软件打印,成本较高,老板也不容易接受,而自己开发的程序则灵活性更好,方便适应公司的发展需要。下面把自己在实际的运用中写的关于打印中文信息的代码与大家一起分享,如果有写得不好的地方,请各位指出。以下代码是在C#环境中测试通过。先用文本排版好格式(zpl文件),然后通过填充数据打印所需要的内容。
// 首先是引用fnthex32.dll,它是用于斑马条码打印机打印汉子所需的dll文件
#region 调用fnthex32.dll,用于转换中文字符
//GETFONTHEX可以将中文字体转换为HEX字体
//由于ZEBRA打印机本身不能打印中文,因此需要将中文进行转换,传给打印机
[DllImport("fnthex32.dll")]
public static extern int GETFONTHEX(
string BarcodeText,
string FontName,
string FileName,
int Orient,
int Height,
int Width,
int IsBold,
int IsItalic,
StringBuilder ReturnBarcodeCMD);
#endregion
// 读取zpl文件内容到数组
/******************************************************************
*** 功能 打开文件,并读出内容,保存到数组
*** 说明 参数sFileName文件名称
*** 将文件内容赋给数组返回(通过)
******************************************************************/
private string[] getPrintStringArray(string sFileName)
{
ArrayList printStringArray = new ArrayList();
int i = 0;
FileStream fileStream = File.OpenRead(sFileName);
try
{
StreamReader reader = new StreamReader(fileStream, System.Text.Encoding.Default);
reader.BaseStream.Seek(0, SeekOrigin.Begin);
string strLine = reader.ReadLine();
while (strLine != null)
{
//string[] split = strLine.Split('\n');
//printStringArray[i] = strLine;
printStringArray.Add(strLine);
i++;
strLine = reader.ReadLine();
}
reader.Close();
reader.Dispose();
fileStream.Close();
fileStream.Dispose();
string[] values = (string[])printStringArray.ToArray(typeof(string));
return values;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return (string[])printStringArray.ToArray(typeof(string));
}
}
/******************************************************************
*** 功能 检查fieldStr的内容是否包含中文
*** 说明 fieldStr要检查的字符串数组
******************************************************************/
private bool ChkChinese(string fieldStr)
{
int nLen, nTmp;
string sCharTmp;
nLen = fieldStr.Length;
for (nTmp = 0; nTmp < nLen; nTmp++)
{
sCharTmp = fieldStr.Substring(nTmp, 1);
if (Convert.ToChar(sCharTmp) > 127 || Convert.ToChar(sCharTmp) < 0)
{
return true;
}
}
return false;
}
// 在ZPL文件中,把带_FIELD结尾的内容,以相应的数据源的字段内容去替换掉。
/******************************************************************
*** 功能 用DataTable中栏位的值去替换相应字段
*** 说明 ZPLText为打印标帖的文本内容rds为数据源
*** 将ZPLText中形如WONUM_FIELD的用rds对应的WONUM的值代替,然后还返回数组
******************************************************************/
private string[] convertZPLTextFields(string[] ZPLText, DataTable rds, int currow)
{
string sTemp = "";
string sTemp1 = "";
string sTemp2 = "";
string FieldName = "";
int s1, s2, i, j;
int zNum, fNum;
string fieldStr = "";
zNum = ZPLText.Length - 1; //数组长度
fNum = rds.Columns.Count; //rds列数
for (i = 0; i <= zNum; i++)
{
for (j = 0; j <= fNum - 1; j++)
{
FieldName = rds.Columns[j].ColumnName;
sTemp = FieldName + "_FIELD";
s1 = ZPLText[i].IndexOf(sTemp); //查找fieldName在ZPLText[i]中的索引值(位置)
if (s1 != -1)
{
s2 = s1 + sTemp.Length;
sTemp1 = ZPLText[i].Substring(0, s1);// 替换前半段
sTemp2 = ZPLText[i].Substring(s2, ZPLText[i].Length - s2);//替换后半段
//if (rds.Columns[j].GetType().ToString() == "System.String")
if (rds.Columns[j].DataType.Name == "String")
{
fieldStr = rds.Rows[currow][j].ToString();
if (ChkChinese(fieldStr)) //检查是否存在中文,如果存在则做转换
{
convertChineseToHex(fieldStr, "fchfnt" + i, 2);
ZPLText[i] = sTemp1 + "^XGfchfnt" + i + sTemp2; //^XG 调取图像,这里是先转中文字体为fchfnt,然后用^XG调取它
}
else
{
ZPLText[i] = sTemp1 + fieldStr + sTemp2;
}
}
else
{
ZPLText[i] = sTemp1 + rds.Rows[currow][j].ToString() + sTemp2;
}
}
}
}
return ZPLText;
}
//将文件内容中的标记为中文的内容取出,进行字体转换,然后用相应的字体名替换
private string[] convertZPLTextChinese(string[] ZPLText)
{
int zNum, s1, s2, i;
string sTemp = "", sTemp1 = "";
string[] chStrArr = null;
string compStr, fntName, chStr;
double nRate = 0;
chStr = "";
compStr = "^XGCH(";
fntName = "chfnt";
zNum = ZPLText.Length - 1;
for (i = 0; i <= zNum; i++)
{
s1 = ZPLText[i].IndexOf(compStr);//^XGCH( 前面的字符
if (s1 != -1)
{
s2 = ZPLText[i].IndexOf(")", s1, ZPLText[i].Length - s1);//跟在^XGCH( 后面的另一半括号 )的位置
if (s2 != -1)
{
nRate = 3;
chStrArr = ZPLText[i].Substring(s1 + 6, s2 - s1 - 6).Split(';');//这里的+6就是^XGCH( 字符串的长度
if (chStrArr.Length - 1 == 0)
{
chStr = chStrArr[0];
}
else
{
if (IsNumeric(chStrArr[0]))
{
nRate = Convert.ToDouble(chStrArr[0]);
chStr = chStrArr[1];
}
//else
//{
// chStr = chStrArr[1];
//}
}
sTemp = ZPLText[i].Substring(0, s1 + 3);
sTemp1 = ZPLText[i].Substring(s2 + 1, ZPLText[i].Length - s2 - 1);
convertChineseToHex(chStr, fntName + i, nRate);
ZPLText[i] = sTemp + fntName + i + sTemp1;
}
}
}
return ZPLText;
}
//将中文转换成HEX字体送往PRINTER
//chStr为中文内容
//chFntName 为转换后的字体名称
private void convertChineseToHex(string chStr, string chFntName, double nRate)
{
//int MAX_BUFFER, nCount;
int nCount;
StringBuilder cBuf = new StringBuilder(21000);
nCount = GETFONTHEX(chStr, "宋体", chFntName, 0, Convert.ToInt32(10 * nRate), 0, 1, 0);
string temp = " " + cBuf.ToString();
temp = temp.Substring(0, nCount);
PrintString = GetPrintSW(temp);
}
/******************************************************************
*** 功能 打印标帖程序
*** 说明 labelFileName 标帖格式文件名称
*** dataSource数据源,可为datatable
*** bTotalLabel 为TRUE表示要打印汇总标帖
******************************************************************/
public void execPrintDefineLabel(string labelFileName, DataTable dataSource, bool bTotalLabel)
{
int i;
string sqlStr = String.Empty;
string[] ZPLText = null;
string[] tempArr;
//bool execConvertCHinese;
int lNum;
DataTable currrds = null;
int labelNum;
// double sumqty;
// int placeSp;
int j = 0;
// LoadLogo("d:\\Logo.zpl");
//检测文件是否存在
try
{
if (labelFileName == "" || !File.Exists(labelFileName))
{
MessageBox.Show("标帖格式文件" + labelFileName + "不存在", "提示", MessageBoxButtons.OK);
return;
}
if (dataSource.Rows.Count == 0)
{
MessageBox.Show("无数据打印", "提示", MessageBoxButtons.OK);
return;
}
//取出打印内容
ZPLText = getPrintStringArray(labelFileName);
currrds = dataSource;
lNum = ZPLText.Length - 1;
tempArr = new string[lNum];
ZPLText = convertZPLTextChinese(ZPLText);
tempArr = ZPLText;
//sumqty = 0;
do
{
ZPLText = convertZPLTextFields(ZPLText, currrds, j);
//if (bTotalLabel)
//{
// sumqty = sumqty + Convert.ToDouble(currrds.Columns["QTY"].ToString());
//}
//Printer printer = new Printer();
for (i = 0; i <= lNum; i++)
{
// printer.Write(" " + ZPLText[i]);
PrintString = GetPrintSW(" " + ZPLText[i]);
}
ZPLText = tempArr;
j++;
} while (j < currrds.Rows.Count);
labelNum = currrds.Rows.Count;
//string text = "";
//for (int a = 0; a <= ZPLText.Length - 1; a++)
//{
// text = text + ZPLText[a].ToString() + "\n";
//}
//MessageBox.Show(text, "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
//if (bTotalLabel)
//{
// sumqty = Math.Round(sumqty, 10);
// lNum = currrds.Fields.Count;
// printer.Write("^XA");
// placeSp = 0;
// currrds.MoveFirst();
// for (i = 0; i <= lNum - 1; i++)
// {
// if (currrds.Fields[i].Attributes != 0 && currrds.Fields[i].Attributes == (int)ADODB.FieldAttributeEnum.adFldKeyColumn)
// {
// placeSp = placeSp + 50;
// printer.Write("^AFN^FO50," + placeSp.ToString() + "^FD" + currrds.Fields[i].Name + ": " + currrds.Fields[i].Value + "^FS");
// }
// }
// printer.Write("^AFN^FO50," + Convert.ToString(placeSp + 50) + "^FDSUM QTY: " + sumqty.ToString() + "^FS");
// printer.Write("^AFN^FO50," + Convert.ToString(placeSp + 100) + "^FDLABEL NUMBER: " + labelNum.ToString() + "^FS");
// printer.Write("^XZ");
//}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
//判断是否为数字
public bool IsNumeric(string text)
{
try
{
double num = Convert.ToDouble(text);
return true;
}
catch
{
return false;
}
}
// 加载公司LOGO图像
public void LoadLogo(string sFileName)
{
string logoText = "";
FileStream fileStream = File.OpenRead(sFileName);
try
{
StreamReader reader = new StreamReader(fileStream, System.Text.Encoding.Default);
reader.BaseStream.Seek(0, SeekOrigin.Begin);
string strLine = reader.ReadLine();
while (strLine != null)
{
logoText = logoText + strLine +"\n";
strLine = reader.ReadLine();
}
reader.Close();
reader.Dispose();
fileStream.Close();
fileStream.Dispose();
PrintString = GetPrintSW(logoText);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
///GetPrintSw方法用来构造打印文本,内部StringBuilder.AppendLine在Drawstring时单独占有一行。现改为string来构造,用换行符做为分格sting数组的条件。
public string GetPrintSW(string strPrint)
{
PrintString = PrintString + strPrint + "\r\n";
return PrintString;
}
public string PrintString = string.Empty;
public string PrintName = string.Empty;
private int countNum = 0;
private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics graphic = e.Graphics;//获取绘图对象
float linesPerPage = 0;//页面行号
float yPosition = 0;//绘制字符串的纵向位置
float leftMargin = e.MarginBounds.Left;//左边距
float topMargin = e.MarginBounds.Top;//上边距
string[] split = PrintString.Split('\n');
string line = string.Empty;//读取的行字符串
int currentPageLine = 0;//当前页读取的行数
Font charFont = new Font("宋体", 9, FontStyle.Regular);//设置打印字体
SolidBrush brush = new SolidBrush(Color.Black);//刷子
// Point po = new Point(10, 10);
linesPerPage = e.MarginBounds.Height / charFont.GetHeight(graphic);//每页可打印的行数
//countNum记录全局行数,currentPageLine记录当前打印页行数。
while (countNum < split.Length )
{
if (currentPageLine < linesPerPage)
{
line = split[countNum].ToString();
if (line.Length <= 100)
{
yPosition = topMargin + (currentPageLine * charFont.GetHeight(graphic));
//绘制当前行
graphic.DrawString(line, charFont, brush, leftMargin, yPosition, new StringFormat());
//graphic.DrawString(line, charFont, brush, new StringFormat());
countNum++;
currentPageLine++;
}
else
{
//拆分后的行数 这里插分多行。
int moreLine = line.Length / 100 + 1;
string tempLine;
for (int i = 0; i < moreLine; i++)
{
//获得当前行的子串
if ((line.Length - i * 100) >= 100)
{
tempLine = line.Substring(i * 100, 100);
}
else
{
tempLine = line.Substring(i * 100, line.Length - i * 100);
}
yPosition = topMargin + (currentPageLine * charFont.GetHeight(graphic));
//绘制当前行
graphic.DrawString(tempLine, charFont, brush, leftMargin, yPosition, new StringFormat());
// graphic.DrawString(line, charFont, brush, new StringFormat());
//当前打印页行数加1
currentPageLine++;
}
//总行数加1
countNum++;
}
}
else
{
line = null;
break;
}
}
//一页显示不完时自动重新调用此方法
if (line == null)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
//每次打印完后countNum清0;
if (countNum >= split.Length)//(countNum >= richTextBox1.Lines.Length)
{
countNum = 0;
}
}
ZPL打印中文信息的更多相关文章
- 【原创】python中文编码问题深入分析(二):print打印中文异常及显示乱码问题分析与解决
在学习python以及在使用python进行项目开发的过程中,经常会使用print语句打印一些调试信息,这些调试信息中往往会包含中文,如果你使用python版本是python2.7,或许你也会遇到和我 ...
- SecureCRT——设置打印中文字符
1. 设置方法 使用SecureCRT打印由STM32发送的中文字符提示信息,显示乱码.在网上找了一些链接,再加上自己摸索,终于出了能够让SecureCRT打印中文的方法. 设置以下几个地方即可. 1 ...
- Mybatis框架基于映射文件和配置文件的方式,实现增删改查,可以打印日志信息
首先在lib下导入: 与打印日志信息有关的架包 log4j-1.2.16.jar mybatis架包:mybatis-3.1.1.jar 连接数据库的架包:mysql-connector-java-5 ...
- xcode8 关闭控制台打印不用信息
控制台打印的信息如下 -- :::] subsystem: com.apple.UIKit, category: HIDEventFiltered, enable_level: , persist_l ...
- -XX:+PrintHeapAtGC 每次一次GC后,都打印堆信息
-XX:+PrintHeapAtGC每次一次GC后,都打印堆信息 {Heap before GC invocations=0 (full 0): def new generation total ...
- STM32M CUBE实现printf打印调试信息以及实现单字节接收
在写单片机程序时我们一般喜欢使用printf来通过串口打印调试信息,但这个函数是不能够直接使用的.必须做点对库函数的修改. 具体project下载地址: http://download.csdn.ne ...
- [置顶] 如何vs在cocos2dx项目中打印中文
一开始不是很理解,查了半天资料,终于找到解决方法,但是有部分中文还是不能打印出来,如 会出现部分的中文, 一开始都是问号的解决方法是 点击高级保存选项 设置成Unicode(UTF-8无签名) 这样就 ...
- [osg]osg显示中文信息
转自:http://www.cnblogs.com/feixiang-peng/articles/3152754.html 写好了在osg中实时显示中文信息的效果.中间遇到两个问题,一个是中文显示,一 ...
- 解决华为手机不打印Log信息的问题
在之前安装了Android Studio后,发现了一个很苦恼的事情,就是在程序中的写Log语句,不能正常的在Logcat中打印出来,这对于解决程序bug真是一刀切断,让人无从下手,在各种尝试后,首先我 ...
随机推荐
- (转)VS2010启动调试时老是提示正在下载公共符号
VS2010启动调试时老是提示正在下载公共符号,下载一些.dll文件,点取消后也能继续调试,但特别慢. 解决方法:工具—选项,或者调试—选项和设置,将调试下的“启用 .NET Framework ...
- python安装pycrypto报错error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
系统3.19.0-15-generic #15-Ubuntu 安装pycrypto提示error: command 'x86_64-linux-gnu-gcc' failed with exit st ...
- 問題排查:System.BadImageFormatException: 未能加载文件或程序集“System.ServiceModel
錯誤訊息如下: System.BadImageFormatException: 未能加载文件或程序集“System.ServiceModel, Version=3.0.0.0, Culture=neu ...
- java-GUI图形用户界面
图形用户界面GUI(Graphical User Interface),指的是在一个程序中用户可以看到的和与之交互的部分. JavaAPI中提供两套组件用于支持编写用户界面AWT and Swin ...
- linux 安装jdk,tomcat 配置vsftp 远程连接
不知不觉入行也有一年了,这两天在公司上班有空了就自己装了个vmware虚拟机,装了个红帽6.1完全命令行的操作系统,想着搭个公司现在在用的测试环境,没想到中间碰到了很多问题,不过大部分都解决了,现在可 ...
- 【动态规划】bzoj1664 [Usaco2006 Open]County Fair Events 参加节日庆祝
将区间按左端点排序. f(i)=max{f(j)+1}(p[j].x+p[j].y<=p[i].x && j<i) #include<cstdio> #incl ...
- 国内从事GIS行业的公司及其网址
www.esrichina-bj.cn esri中国北京http://www.lingtu.com/ 北京灵图软件技术有限公司(三维gis) http://www.spatialport.com.cn ...
- 正确理解DTO、值对象和POCO
今天推荐的文章比较技术化也比较简单,但是对于一些初学者而言,可能也是容易搞混的概念:就是如何理解DTO.值对象和POCO之间的区别. 所谓DTO就是数据传输对象(Data Transfer Objec ...
- Google的Bigtable学习笔记(不保证正确性)
跪求各路大侠指正:1.首先是一个列式存储的简单数据模型的数据库,它比键值对模型/文档模型NoSQL数据库复杂点(也就更强一点).2.它的分布式存储性能依靠于GFS也就对单机房网络有硬性指标.3.它同时 ...
- Javascript 异步加载详解(转)
本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy execution),async 属 ...