打印小票时自动换行算法,可处理各种字符混排

这是一个算法,是我在做热敏打印机打印小票时解决的一个问题,想了想还是分享给大家,或许多大家有些许帮助。

在打印小票时,可能遇到一些字符串长度过长的问题,但是你不能直接截取,所以需要自动换行来显示全部名称。经过分析,其实是这么一个问题:需要把字符串分行,使得每行不得超过最大长度,最后一行长度为指定的最小长度,长度不够,用空格补齐。

先给出一个简单的效果示例图:

具体的算法源码:

#Region "把字符串按指定最大长度分行,使得最后一行长度为指定的最低长度" <summary> 处理字符串自动换行问题。最短为intLenMin,最长为intLenMax,最后一行用空格补齐到intLenMin长度。 </summary> <param name="strOldText">原字符串</param> <param name="intLenMin">最短字节长度</param> <param name="intLenMax">最长字节长度</param> <returns>string</returns> <remarks></remarks> Public Function AutomaticLine(ByVal strOldText As String, ByVal intLenMin As Integer, ByVal intLenMax As Integer) As String Dim intLength As Integer Dim strResult As String = "" 获取原字符串的字节长度 intLength = System.Text.Encoding.GetEncoding("gb2312").GetByteCount(strOldText) If intLength > intLenMax Then 总字节数> 最长截取的最长字节数, 则截取最长字节数, 然后对剩余字符串再处理 获取字符串的UCS2码 Dim bytes As Byte() = System.Text.Encoding.Unicode.GetBytes(strOldText) 获取字符的实际截取位置 Dim intCutPos = RealCutPos(bytes, intLenMax) 采用递归调用 strResult = System.Text.Encoding.Unicode.GetString(bytes, 0, intCutPos * 2) + vbCrLf + AutomaticLine(Mid(strOldText, intCutPos + 1), intLenMin, intLenMax) ElseIf intLength > intLenMin Then 如果 最长字节数 >总字节数 > 最短字节数,则 换行,并补齐空格到最短字节数位置 strResult = strOldText + vbCrLf + Space(intLenMin) Else 如果 总字节数 < 最短字节数,则直接补齐空格到最短字节数的位置 strResult = strOldText + Space(intLenMin - intLength) End If Return strResult End Function <summary> 返回字符的实际截取位置 </summary> <param name="bytes">UCS2码</param> <param name="intLength">要截取的字节长度</param> <returns></returns> <remarks></remarks> Public Function RealCutPos(ByVal bytes As Byte(), ByVal intLength As Integer) As Integer 获取UCS2编码 Dim intCountB As Integer = 0 统计当前的字节数 Dim intCutPos As Integer = 0 记录要截取字节的位置 While (intCutPos < bytes.GetLength(0) AndAlso intCountB < intLength) 偶数位置,如0、2、4等,为UCS2编码中两个字节的第一个字节 If intCutPos Mod 2 = 0 Then 在UCS2第一个字节时,字节数加1 intCountB += 1 Else 当UCS2编码的第二个字节大于0时,该UCS2字符为汉字,一个汉字算两个字节 If bytes(intCutPos) > 0 Then intCountB += 1 End If End If intCutPos += 1 End While 如果intCutPos为奇数时,处理成偶数 If intCutPos Mod 2 = 1 Then 该UCS2字符是汉字时,去掉这个截一半的汉字 If bytes(intCutPos) > 0 Then intCutPos = intCutPos - 1 Else 该UCS2字符是字母或数字,则保留该字符 intCutPos = intCutPos + 1 End If End If Return intCutPos / 2 End Function #End Region

由于该算法是按照字节处理的,所以可以处理中英文、数字及各种字符的混排,当截取的最后一位正好是汉字,则会自动处理到前一个字符,不会出现截取错误而导致乱码。

经验分享 程序员 微信小程序 职场和发展