文档章节

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

白志华
 白志华
发布于 2015/10/18 10:56
字数 841
阅读 50
收藏 0

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

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

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

具体的算法源码:

#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

 

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

本文转载自:http://blog.csdn.net/xiaoxian8023/article/details/7276220

共有 人打赏支持
白志华
粉丝 31
博文 265
码字总数 57524
作品 0
长沙
程序员
私信 提问
2017-05-04日志

.修改后台 添加用户时的密码不做md5加密的问题 .用户昵称为特殊字符时,mysql保存失败的问题,设置数据库字符编码为utf8mfb .手机号绑定bug解决:原因是linux上没有指定mysql和tomcat的时区 .公...

test2013
2017/05/04
1
0
zz304222428/DriverPosPrint

驱动打印小票--80热敏打印机 项目环境基于JFinal2.2 偷了个懒直接在JFinal demo上做的 在大神 SubLuLu/thermalprinter 开源的项目基础上写了这个demo,SubLuLu用的是指令打印,而且环境是基于...

zz304222428
2016/10/11
0
0
第1章 标准输入流 & 转换流 & 打印流

1.1 标准输入输出流 public static final InputStream in:标准输入流 public static final PrintStream out:标准输出流 1.2 转换流 1.2.1 OutputStreamWriter:将字节输出流转换为字符输出流 ...

我是小谷粒
2018/04/17
0
0
iphone聊天用几种图形(表情)与文字混排的实现与比较 [复制链接]

一、用HTML实现文字表情混合排列 用HTML实现图形文字混排的好处就是你不需要考虑表情在文字里面的位置问题,你只需要自己做一个HTML,然后用UIWEBVIEW加载一下,然后再把WENVIEW放到视图上,...

长平狐
2012/08/13
171
0
关于Base⑥4编码换行回车引发的blood事件

分析某个sdk的通讯协议,万变不离其宗,基本都是对称加密或者非对称加密后圌进行通讯完整性以及内容可靠性的反复校验。 周三稍微逆向差不多看了实现,偷懒没继续,周四下午任务交接发现以为不...

kingsOSZT
2016/05/17
63
0

没有更多内容

加载失败,请刷新页面

加载更多

Temp-Memo

SQL High CPU troubleshooting checklist SELECT TOP 50[Avg. MultiCore/CPU time(sec)] = qs.total_worker_time / 1000000 / qs.execution_count,[Total MultiCore/CPU time(sec)] = ......

Goopand
4分钟前
0
0
dotConnect for Oracle入门指南(七):存储过程

【下载dotConnect for Oracle最新版本】 dotConnect for Oracle(原名OraDirect.NET)建立在ADO.NET技术上,为基于Oracle数据库的应用程序提供完整的解决方案。它为设计应用程序结构带来了新的...

电池盒
6分钟前
0
0
如何使用阿里云ARMS轻松重现用户浏览器问题

客户投诉不断,本地却无法重现? 页面加载较慢是用户经常会反馈的问题,也是前端非常关注的问题之一。但定位、排查解决这类问题就通常会花费非常多的时间,主要原因如下: 页面是在用户端的浏...

阿里云官方博客
10分钟前
0
0
因资源用尽导致服务宕机

1. 事故的发生 服务调用场景和发生的事件如下图所示,红色表示服务不可用. 服务A和服务B都是内部服务,服务C_*为不同运营商提供的服务,遵循一样的协议。 某一天,突然发现所有服务A调用服务...

北风刮的不认真了
14分钟前
1
0
锤子科技"临死前"被"接盘" ,内部人士爆料已改签今日头条母公司

就在昨天,据据锤子科技内部人士透露,部分锤子科技员工在昨天已经接到了相关的临时通知,要求改签劳动合同至今日头条的母公司——字节跳动。至于这是锤子科技真正再度复活还是借尸还魂都不重...

终端研发部
23分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部