长昼慢慢,无心工作,没有终点的等待未免不让人烦躁,默默无闻随波逐流,每天除了上下班的生活不免有些烦躁,工作最大的乐趣莫于在忙里偷闲干点自己喜欢做的事情了。有时候心中总有些冲动去做自己想做的事情,渐渐的被生活磨圆了锋利的棱角。
生活归生活,活就要活的精彩,工作还得继续,进来由于项目中需要,在做打印的时候希望列内容可以自动换行,就是固定列宽,超过宽度了就可以自己换行,现有打印又不支持自动换行,想想想自己解决算了,既然是换行,列内超出部分打印到本列下一行不就可以了吗?有想法就要付出实际行动去证明。
由于项目中用的打印机是针式打印机,每行打印的字符数是固定的104,每个汉字所占的宽度为英文字符的2倍,所以每行可以打印52汉字或104个英文字符,要实现换行就要对每一行的每一列进行计算,超过列宽的打印到下一行,然后下面打印的内容整体下移即可,这里就需要计算混合字符串中的字节长度,我们平时字符串用的的Length是字符的长度,例如:“ABC你好”,以下字符串的长度就是5,我们都知道英文字符一般占1个字节长度,一个中文字符占2个字节长度,那我们如何获取字符串的字节长度呢?
答案永远充满的神奇的色彩,每天有所期盼,生活就不会失去色彩,内心总会有些小激动。获取字节长度当然使用字符编码去获取了。
var length = Encoding.GetEncoding("GB18030").GetBytes(str).Length;
这里的GB18030也可以用GB2312代替,GBK也可以,他们的区别就是字符集的范围与标准,具体区别去问度娘吧!
例如我们需要打印以下内容
序号 名称 描述 说明
001 打车费用 出租车发票 加班打车费用
。。。。此处省略n行
其中要求第一列宽度为4个英文字符,间距1个英文字符;
第二列8个英文字符,间距1个英文字符;
第三列8个英文字符,间距1个英文字符;
第四列8个英文字符
明显看出来,第三列第四列内容超出规定打印的宽度了,但是内容又不能缩减,这时就需要做换行了。
下面要做的就是将列内容分割了超出指定宽度就将内容截断放入下一行,这里需要注意的一点就是,例如列宽为4第一列为一个汉字加一个英文字符下面又是一个汉字我们就需要将这个汉字放入下一行了,就是当前列宽度剩1,接下来又是一个汉字的时候就需要换行了。下面就在一个将字符串分割成多行的函数
private IList<string> GetLines(string column,int _LineMaxLength ) { IList<string> result= new List<string>(); int length = 0;//字符计数 int startindex = 0;//截取位置计数 int wordCount = 0;//char计数 var totlecount = GetWordsLength(column); int startLength = 0; foreach (var word in column) { wordCount++; var wordLength = GetWordsLength(word.ToString()); length += wordLength; var isEndLine = (totlecount - startLength) < _LineMaxLength; if (length == _LineMaxLength || length == _LineMaxLength - 1 || isEndLine) { var subLength = isEndLine ? (column.Length - startindex) : wordCount; result.Add(column.Substring(startindex, subLength)); startindex += subLength; wordCount = 0; startLength += length; length = 0; if (isEndLine) { break; } } } return result; }
/// <summary> /// 获取字符长度 /// </summary> /// <param name="str"></param> /// <returns></returns> public int GetWordsLength(string str) { return Encoding.GetEncoding("GB18030").GetBytes(str).Length; }
有了这个函数接下来就是遍历每一行的每一列了
根据每列的计算结果,针对列需要换行的地方插入新行,将多出来的内容放入新行即可。
客户的需求永远是苛刻的,满足他们的欲望,这样才能更好的提高我们自己。