疯狂的打印机小票
到公司实习接到的第一个任务,是实现打印一个如上图的小票。
看起来简单,却足足坑了我将近一周,光测试打印效果就足足花了三捆的打印纸。
这里的难点主要有两个:
商品名称、数量和单价都要为固定的宽度
商品名称需要超过折行,不能显示省略号
php处理字符串比较特殊,中文是占3个字节,而非中文则是占1个字节,并且中文的宽度是非中文的2倍左右。
查找了下相关的文档,找到了以下函数:
str_len:获取字符串的字节数
mb_str_len:获取字符串的字符数
str_pad:填充字符到指定长度
首先解决第一个问题,因为对于字符串中文比较另类,所以我们需要先找出一个字符串里有几个中文,一种思路是使用正则表达式,但是众所周知正则的性能比较低,在生产环境中应该尽量避免使用,转而可以使用如下的方式:(多出来的字节数都是中文惹的祸)
<?php
$str = "这是中文测试aaaaa";
echo (strlen($str)-mb_strlen($str))/2;
输出结果为:6(符合预期)
然后,再看下面这组数据:
厉害了啊啊
米饭50g
我们的目标是要把这两行都拓展为宽度为20的字符串。
在使用str_pad这个函数拓展字符串的时候,它是会把一个中文当做3个字节来处理的,也就是说如果我们要扩展到20的宽度,中文就占了3个单位,但实际上它只有2个单位那么宽,所以我们需要在拓展的时候,在目标宽度基础上再加上中文字符数,以抵消这种损失。
<?php
echo mb_str_pad("厉害了啊啊",20).";";
echo "\n";
echo mb_str_pad("米饭50g",20).";";
function mb_str_pad( $input, $pad_length, $pad_string = '_', $pad_type = STR_PAD_RIGHT)
{
$diff = strlen( $input ) - mb_strlen( $input );
return str_pad( $input, $pad_length + $diff/2, $pad_string, $pad_type );
}
效果如图:
关于第二个难点,可以使用mb_substr对字符串进行截取,比如你最大允许它的宽度为20,那就10个10个的进行截取,然后换行就可以啦。
最新文章
全部分类