相信各位在实际的项目中,需要开发打条码模块的也会有不少,很多同行肯定也一直觉得斑马打印机很不错,但是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,
cBuf);
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");
// if
(!printer.Close())
//
{
//
MessageBox.Show("未能关闭与打印机之间的连接,这可能意味着严重的错误,请重启电脑及打印机。");
//
return;
//
}
//}
}
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;
}
}
原文:http://www.cnblogs.com/Geton/p/3595312.html