文档章节

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

白志华
 白志华
发布于 2015/10/18 10:56
字数 841
阅读 45
收藏 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

共有 人打赏支持
白志华
粉丝 29
博文 265
码字总数 57524
作品 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:将字节输出流转换为字符输出流 ...

我是小谷粒
04/17
0
0
关于Base⑥4编码换行回车引发的blood事件

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

kingsOSZT
2016/05/17
63
0
iphone聊天用几种图形(表情)与文字混排的实现与比较 [复制链接]

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

长平狐
2012/08/13
168
0
linux的echo命令简单介绍

介绍: linux的echo命令, 在终端下打印变量value的时候也是常常用到, echo命令的功能是在显示器上显示一段文字,一般起到一个提示的作用。 详细: 语法: echo [ -n ] 字符串 。 其中选项n...

FrendLin
2016/07/07
10
0

没有更多内容

加载失败,请刷新页面

加载更多

你为什么在Redis里读到了本应过期的数据

一个事故的故事 晚上睡的正香突然被电话吵醒,对面是开发焦急的声音:我们的程序在访问redis的时候读到了本应过期的key导致整个业务逻辑出了问题,需要马上解决。 看到这里你可能会想:这是不...

IT--小哥
今天
2
0
祝大家节日快乐,阖家幸福! centos GnuTLS 漏洞

yum update -y gnutls 修复了GnuTLS 漏洞。更新到最新 gnutls.x86_64 0:2.12.23-22.el6 版本

yizhichao
昨天
5
0
Scrapy 1.5.0之选择器

构造选择器 Scrapy选择器是通过文本(Text)或 TextResponse 对象构造的 Selector 类的实例。 它根据输入类型自动选择最佳的解析规则(XML vs HTML): >>> from scrapy.selector import Sele...

Eappo_Geng
昨天
4
0
Windows下Git多账号配置,同一电脑多个ssh-key的管理

Windows下Git多账号配置,同一电脑多个ssh-key的管理   这一篇文章是对上一篇文章《Git-TortoiseGit完整配置流程》的拓展,所以需要对上一篇文章有所了解,当然直接往下看也可以,其中也有...

morpheusWB
昨天
5
0
中秋快乐!!!

HiBlock
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部