相信各位在實際的項目中,須要開發打條碼模塊的也會有很多,不少同行確定也一直以爲斑馬打印機很不錯,可是ZPL打印中文字符很麻煩。若是購買字體卡,或者經過CODESOFT,BARTENDER,LABELVIEW等有控件的條碼軟件打印,成本較高,老闆也不容易接受,而本身開發的程序則靈活性更好,方便適應公司的發展須要。下面把本身在實際的運用中寫的關於打印中文信息的代碼與你們一塊兒分享,若是有寫得很差的地方,請各位指出。如下代碼是在C#環境中測試經過。先用文本排版好格式(zpl文件),而後經過填充數據打印所須要的內容。sql
// 首先是引用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;ui
FileStream fileStream = File.OpenRead(sFileName);
try
{
StreamReader reader = new StreamReader(fileStream, System.Text.Encoding.Default);
reader.BaseStream.Seek(0, SeekOrigin.Begin);spa
string strLine = reader.ReadLine();
while (strLine != null)
{
//string[] split = strLine.Split('\n');
//printStringArray[i] = strLine;
printStringArray.Add(strLine);
i++;
strLine = reader.ReadLine();code
}
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));
}
}orm
/******************************************************************
*** 功能 檢查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;
}
}