文档章节

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

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

 

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

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

白志华
粉丝 34
博文 265
码字总数 57524
作品 0
长沙
程序员
私信 提问
加载中
请先登录后再评论。
【opencv】图形的绘制

1.矩形图像的绘制: 原函数:void cvRectangle(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8,int shift=0) img就是需要绘制的图像 pt1 and pt......

其实我是兔子
2014/10/08
1.1K
1
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
22
5分钟 maven3 快速入门指南

前提条件 你首先需要了解如何在电脑上安装软件。如果你不知道如何做到这一点,请询问你办公室,学校里的人,或花钱找人来解释这个给你。 不建议给Maven的服务邮箱来发邮件寻求支持。 安装Mav...

fanl1982
2014/01/23
1.2W
6
实时分析系统--istatd

istatd是IMVU公司工程师开发的一款优秀的实时分析系统,能够有效地收集,存储和搜索各种分析指标,类似cacti,Graphite,Zabbix等系统。实际上,istatd修改了Graphite的存储后端,重新实现了...

匿名
2013/02/07
2.8K
1
硬实时操作系统--Raw OS

Raw-OS 起飞于2012年,Raw-OS志在制作中国人自己的最优秀硬实时操作系统。 Raw-OS 操作系统特性 内核最大关中断时间无限接近0us, s3c2440系统最大关中断时间实测0.8us。 支持idle任务级别的事...

jorya_txj
2013/03/19
6.1K
1

没有更多内容

加载失败,请刷新页面

加载更多

【c++灵魂科普】(1) 第一部分第一章-初识c++语言

今天带来一篇灵魂科普~ 主要是认识c++语言~话不多说 走起! 【全是干货!】 第一节 c++语言简介 信息学奥林匹克竞赛是一项益智性的竞赛活动,核心是考查选手的智力和使用计算机解题的能力,选...

osc_facwbzof
16分钟前
13
0
谈谈AMD CPU购机心得 与 写代码的感受

序 之前用的是华硕飞行保垒。具体是几代忘记了。。I7 4代的标压CUP。 8G内存 换成了联想yoga 14s。 换电脑的原因 网卡问题,老旧的网卡争网络实在争不过别人。每次看别人网络很好,我却连不上...

osc_0m0d4mbq
17分钟前
0
0
springboot 定时任务

一、在 DemoApplycation.java 写入如下代码 package com.taven.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootA......

tavenpy
18分钟前
8
0
2020年8月中国编程语言排行榜

编程语言比例(市场份额) 工资 排名 编程语言 平均工资 中位数 最低()95% 最高(95%) 人数 百分比 1 julia 22539 22500 9000 37500 17 0.00% 2 rust 20987 18500 5371 45000 548 0.11% 3 scal...

osc_kvcz9ju6
18分钟前
0
0
北风在这里给大家拜年了!!!祝大家2020鼠年大吉!忠心祝愿❤在新的一年里:工作的朋友工作顺利,还在读书的童鞋硕果累累,学技术的伙伴技术更上一层楼!同时祝大家2020百毒不侵!😄最后:武汉...

本文分享自微信公众号 - 北风IT之路(beifengtz)。 如有侵权,请联系 support@oschina.cn 删除。 本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。...

beifengtz
01/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部